kick
/Users/morten/Programmering/cpp/kick/src/kick/material/material.h
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 }
 All Classes Functions Variables