kick
|
00001 // 00002 // material.h 00003 // KickCPP 00004 // 00005 // Created by morten on 8/25/13. 00006 // Copyright (c) 2013 Morten Nobel-Joergensen. All rights reserved. 00007 // 00008 00009 #pragma once 00010 00011 #include <iostream> 00012 #include <memory> 00013 00014 #include <glm/glm.hpp> 00015 #include <vector> 00016 #include <map> 00017 #include <glm/gtc/type_ptr.hpp> 00018 #include "kick/core/project_asset.h" 00019 #include "kick/core/event_listener.h" 00020 #include "kick/core/kickgl.h" 00021 #include "kick/texture/texture2d.h" 00022 #include "kick/texture/texture_cube.h" 00023 #include "shader_enums.h" 00024 00025 namespace kick { 00026 00027 class Shader; 00028 00029 00030 00031 struct MaterialData { 00032 MaterialData(int intValue):value{intValue}, glType{GL_INT} {} 00033 MaterialData(float floatValue):value{floatValue}, glType{GL_FLOAT}{} 00034 MaterialData(glm::vec4 vec4Value):value{vec4Value}, glType{GL_FLOAT_VEC4}{} 00035 MaterialData(glm::mat3 mat3Value):value{mat3Value}, glType{GL_FLOAT_MAT3}{} 00036 MaterialData(glm::mat4 mat4Value):value{mat4Value}, glType{GL_FLOAT_MAT4}{} 00037 MaterialData(Texture2D *textureValue):value{textureValue}, glType{GL_SAMPLER_2D}{} 00038 MaterialData(TextureCube *textureValue):value{textureValue}, glType{GL_SAMPLER_CUBE}{} 00039 00040 MaterialData(const MaterialData & val); 00041 MaterialData& operator=(const MaterialData& other); 00042 00043 union MaterialValueType{ // todo find workaround should be union 00044 // union constructors 00045 MaterialValueType(int intValue):intValue{intValue}{} 00046 MaterialValueType(float floatValue){this->floatValue[0] = floatValue;} 00047 MaterialValueType(glm::vec4 vec4Value){ for (int i=0;i<4;i++){floatValue[i] = vec4Value[i]; }} 00048 MaterialValueType(glm::mat3 mat3Value){ for (int i=0;i<9;i++){floatValue[i] = glm::value_ptr(mat3Value)[i]; }} 00049 MaterialValueType(glm::mat4 mat4Value){ for (int i=0;i<16;i++){floatValue[i] = glm::value_ptr(mat4Value)[i]; }} 00050 MaterialValueType(Texture2D* texture2d):texture2D{texture2d}{} 00051 MaterialValueType(TextureCube* textureCube):textureCube{textureCube}{} 00052 int intValue; 00053 float floatValue[16]; 00054 Texture2D* texture2D; 00055 TextureCube* textureCube; 00056 } value; 00057 00058 void setValue(MaterialValueType val); 00059 00060 int shaderLocation; 00061 int glType; 00062 // is the value inherited from the default uniform value in the shader 00063 bool defaultUniform = false; 00064 }; 00065 00066 class Material : public ProjectAsset { 00067 public: 00068 explicit Material(std::shared_ptr<Shader> shader = {}); 00069 Material(const Material& copy); 00070 ~Material(); 00071 void setShader(std::shared_ptr<Shader> shader); 00072 std::shared_ptr<Shader> shader(); 00073 void setUniform(std::string name, int value); 00074 void setUniform(std::string name, float value); 00075 void setUniform(std::string name, glm::vec4 value); 00076 void setUniform(std::string name, glm::mat3 value); 00077 void setUniform(std::string name, glm::mat4 value); 00078 void setUniform(std::string name, std::shared_ptr<Texture2D> value); 00079 void setUniform(std::string name, std::shared_ptr<TextureCube> value); 00080 00081 int bind(); 00082 int renderOrder(); 00083 private: 00084 template <class E> 00085 void setUniformInternal(std::string name, E value); 00086 void shaderChanged(ShaderEvent se); 00087 void setDefaultUniforms(); 00088 void updateShaderLocation(std::string name, MaterialData& value); 00089 void setUniformData(std::string name, MaterialData&& value); 00090 // current data (may misfit with current shader) 00091 std::map<std::string, MaterialData> currentUniformData; 00092 std::shared_ptr<Shader> mShader; 00093 EventListener<ShaderEvent> shaderChangedListener; 00094 int mRenderOrder = 1000; 00095 std::map<std::string, std::shared_ptr<Texture2D>> texture2DRef; 00096 std::map<std::string, std::shared_ptr<TextureCube>> textureCubeRef; 00097 }; 00098 00099 std::string to_string(MaterialData & data); 00100 00101 template <class E> 00102 void Material::setUniformInternal(std::string name, E value){ 00103 MaterialData data{value}; 00104 setUniformData(name, std::move(data)); 00105 } 00106 }