diff --git a/src/forwardmodule.cpp b/src/forwardmodule.cpp index c00fccd..160f709 100644 --- a/src/forwardmodule.cpp +++ b/src/forwardmodule.cpp @@ -48,42 +48,40 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light) { std::size_t j; for(j=0; jgetFlags()) break; if(j == lightFlagList.size()) - continue; // WARNING : missing shader for the light + { + fprintf(stderr, "WARNING : missing shader for the light"); + continue; + } Shader* shader = shaders[i*lightFlagList.size() + j]; shader->bind(); // bind light attributes - if(light == NULL) + switch(light->getType()) { - // ambient light - shader->bindVec3(shader->getLocation("lightColor"), glm::vec3(0.1f)); // add attribute, and setter for ambient lighting - } - else - { - switch(light->getType()) - { - case Light::DIRECTIONNAL: - shader->bindVec3(shader->getLocation("dirLight"), -light->getDir()); - shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); - if(light->isShadowCaster()) - { - light->getShadowMap()->bind(NB_FLAGS); // NB_FLAGS has the value of the first available slot after the phong material texture slots - shader->bindInteger(shader->getLocation("shadowMap"), NB_FLAGS); - } - break; - case Light::POINT: - shader->bindVec3(shader->getLocation("pointLight"), light->getPos()); - shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); - shader->bindFloat(shader->getLocation("attenuation"), light->getAttenuation()); - break; - case Light::SPOT: - shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); - // TODO add cutoff and attenuation + case Light::AMBIENT: + shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); // add attribute, and setter for ambient lighting break; + case Light::DIRECTIONNAL: + shader->bindVec3(shader->getLocation("dirLight"), -light->getDir()); + shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); + if(light->isShadowCaster()) + { + light->getShadowMap()->bind(PhongMaterial::NB_PHONG_SLOTS); // NB_PHONG_SLOTS has the value of the first available slot after the phong material texture slots + shader->bindInteger(shader->getLocation("shadowMap"), PhongMaterial::NB_PHONG_SLOTS); } + break; + case Light::POINT: + shader->bindVec3(shader->getLocation("pointLight"), light->getPos()); + shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); + shader->bindFloat(shader->getLocation("attenuation"), light->getAttenuation()); + break; + case Light::SPOT: + shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); + // TODO add cutoff and attenuation + break; } unsigned int id = 2; for(SceneIterator* geometryIt = scene->getGeometry(); @@ -184,20 +182,6 @@ void ForwardModule::compileShaders(Scene* scene) { std::vector defines; - // set geometry defines - if(i & NORMAL_MAP_FLAG) - defines.push_back(flagStr[NORMAL_MAP]); - if(i & AMBIENT_TEXTURE_FLAG) - defines.push_back(flagStr[AMBIENT_TEXTURE]); - if(i & DIFFUSE_TEXTURE_FLAG) - defines.push_back(flagStr[DIFFUSE_TEXTURE]); - if(i & SPECULAR_TEXTURE_FLAG) - defines.push_back(flagStr[SPECULAR_TEXTURE]); - if(i & ALPHA_MASK_FLAG) - defines.push_back(flagStr[ALPHA_MASK]); - if(i & INSTANCING_FLAG) - defines.push_back(flagStr[INSTANCING]); - std::size_t boundary = defines.size(); for(int j : lightFlagList) { diff --git a/src/light.cpp b/src/light.cpp index c8931e8..1c7d23f 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -28,6 +28,16 @@ Light::Light() initPointLight(); } +void Light::initAmbientLight(glm::vec3 lightColor = glm::vec3(0.1f)) +{ + type = AMBIENT; + position = glm::vec3(0); + color = lightColor; + shadowCaster = false; + isDir = false; + viewMatrix = glm::mat4(); +} + void Light::initDirectionnalLight(glm::vec3 dir, glm::vec3 lightColor) { type = DIRECTIONNAL; @@ -87,8 +97,8 @@ void Light::initShadowMap(int resWidth, int resHeight, glm::vec3 dim) shadowMap->initColorAttachments(); ShaderSource source; - source.setSource(vertSource, ShaderSource::VERTEX); - source.setSource(fragSource, ShaderSource::FRAGMENT); + source.setSource(shadowVertSource, ShaderSource::VERTEX); + source.setSource(shadowFragSource, ShaderSource::FRAGMENT); std::vector defines; shaders[0] = source.compile(defines.size(), defines.data()); defines.push_back("ALPHA_MASK"); @@ -145,32 +155,30 @@ void Light::setPosition(glm::vec3 new_pos) viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0)); } -unsigned int Light::getFlags(Light* l) +unsigned int Light::getFlags() { - if(l == NULL) - return 1 << AMBIENT_FLAG; - else + unsigned int flags = 0; + switch(l->getType()) { - unsigned int flags = 0; - switch(l->getType()) - { - case DIRECTIONNAL : - flags |= 1 << DIRECTIONNAL_FLAG; - break; - case POINT : - flags |= 1 << POINT_FLAG; - break; - case SPOT : - flags |= 1 << SPOT_FLAG; - break; - } - if(l->isShadowCaster()) - flags |= 1 << SHADOWMAP_FLAG; - return flags; + case AMBIENT : + flags = 1 << AMBIENT_FLAG; + break; + case DIRECTIONNAL : + flags = 1 << DIRECTIONNAL_FLAG; + break; + case POINT : + flags = 1 << POINT_FLAG; + break; + case SPOT : + flags = 1 << SPOT_FLAG; + break; } + if(l->isShadowCaster()) + flags |= 1 << SHADOWMAP_FLAG; + return flags; } -const char* Light::vertSource = +const char* Light::shadowVertSource = "layout(location = 0)in vec3 inPosition;\n\ #ifdef ALPHA_MASK\n\ layout(location = 2)in vec2 inTexCoord;\n\ @@ -185,7 +193,7 @@ const char* Light::vertSource = gl_Position = MVP * vec4(inPosition, 1.0);\n\ }\n"; -const char* Light::fragSource = +const char* Light::shadowFragSource = "#ifdef ALPHA_MASK\n\ uniform sampler2D alphaMask;\n\ in vec2 varTexCoord;\n\ diff --git a/src/light.h b/src/light.h index e0d0569..b44561a 100644 --- a/src/light.h +++ b/src/light.h @@ -15,6 +15,7 @@ class Light : public Camera { public: enum LightType { + AMBIENT, DIRECTIONNAL, POINT, SPOT @@ -32,6 +33,7 @@ public: static const glm::mat4 biasMatrix; Light(); + void initAmbientLight(glm::vec3 lightColor = glm::vec3(0.1f)); void initDirectionnalLight(glm::vec3 dir = glm::vec3(0, -1, 0), glm::vec3 lightColor = glm::vec3(1)); void initPointLight(glm::vec3 pos = glm::vec3(0), glm::vec3 lightColor = glm::vec3(1), float att = 1); void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1)); @@ -58,7 +60,10 @@ public: // does nothing, just required for inheriting Camera void resize(int width, int height) {} - static unsigned int getFlags(Light* l); + /** + * @brief getFlags returns the flags that defines the specificities of the light + */ + unsigned int getFlags(); private: // standard attributes LightType type; @@ -79,8 +84,8 @@ private: Shader* shaders[2]; glm::mat4 viewMatrix; glm::mat4 projectionMatrix; - static const char* vertSource; - static const char* fragSource; + static const char* shadowVertSource; + static const char* shadowFragSource; }; #endif // LIGHT_H diff --git a/src/phongmaterial.h b/src/phongmaterial.h index 205968d..f4e1841 100644 --- a/src/phongmaterial.h +++ b/src/phongmaterial.h @@ -16,6 +16,7 @@ private: NORMALS_SLOT, SPECULAR_SLOT, ALPHA_SLOT, + NB_PHONG_SLOTS }; glm::vec3 ambient; diff --git a/src/scene.cpp b/src/scene.cpp index 5eb92be..c0c28a7 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -31,52 +31,45 @@ std::vector Scene::getLightTypes() return types; } -ArrayScene::~ArrayScene() +BasicScene::~BasicScene() { clearScene(); } -void ArrayScene::addMesh(GeometryNode* node) +void BasicScene::addMesh(GeometryNode* gn) { - Node n; - n.geometry = node; - unsigned int flags = node->mesh->getFlags(); - if(nodes.count(flags) > 0) - nodes[m->getFlags()]->push_back(n); - else - { - std::vector *vec = new std::vector(); - vec->push_back(n); - nodes[m->getFlags()] = vec; - } + geometry->push_back(gn); } -void ArrayScene::addMesh(Mesh* m, glm::mat4 transform) +GeometryNode* BasicScene::addMesh(Mesh* m, glm::mat4 transform) { GeometryNode *gn = new GeometryNode(m, transform); allocations.push_back(gn); addMesh(gn); + return gn; } -void ArrayScene::clearScene() +void BasicScene::addLight(Light* myLight) +{ + lights.push_back(myLight); +} + +void BasicScene::clearScene() { - for(auto it : nodes) - delete it; for(GeometryNode *gn : allocations) delete gn; allocations.clear(); - nodes.clear(); + geometry.clear(); + lights.clear(); } -SceneIterator ArrayScene::getLights(unsigned int flags) +SceneIterator* BasicScene::getLights() { - if(nodes.count(flags)) - return ArrayIterator(*(nodes[flags])); + return new ArrayIterator(lights); } -SceneIterator ArrayScene::getGeometry(unsigned int flags) +SceneIterator* BasicScene::getGeometry() { - if(nodes.count(flags)) - return ArrayIterator(*(nodes[flags])); + return new ArrayIterator(geometry); } diff --git a/src/scene.h b/src/scene.h index 95693dc..92e69ef 100644 --- a/src/scene.h +++ b/src/scene.h @@ -3,7 +3,6 @@ #include #include -#include #include "light.h" class Camera; @@ -41,8 +40,8 @@ public: Pipeline* getPipeline() {return m_pipeline;} - virtual SceneIterator getLights(unsigned int flags) = 0; - virtual SceneIterator getGeometry(unsigned int flags) = 0; + virtual SceneIterator* getLights() = 0; + virtual SceneIterator* getGeometry() = 0; virtual void getMeshTypes(std::vector &meshTypes); virtual void getLightTypes(std::vector &lightTypes); @@ -62,31 +61,25 @@ public: virtual bool isValid() {return id < vec.size();} }; -class ArrayScene : public Scene +class BasicScene : public Scene { protected: - union Node - { - Light* light; - GeometryNode* geometry; - }; - - std::unordered_map*> nodes; - + std::vector lights; // fast node access for rendering + std::vector geometry; std::vector allocations; public: - ArrayScene() : Scene() {} - ~ArrayScene(); + BasicScene() : Scene() {} + ~BasicScene(); void setPipeline(Pipeline *pipeline) {m_pipeline = pipeline;} void clearScene(); void addMesh(GeometryNode* node); - void addMesh(Mesh* m, glm::mat4 transform); - void addLight(Light* myLight) {lights.push_back(myLight);} + GeometryNode* addMesh(Mesh* m, glm::mat4 transform); + void addLight(Light* myLight); Mesh* getMesh(int id) {return geometry[id]->mesh;} - SceneIterator getLights(unsigned int flags); - SceneIterator getGeometry(unsigned int flags); + SceneIterator* getLights(); + SceneIterator* getGeometry(); }; #endif // SCENE_H