#include "forwardmodule.h" #include "scene.h" #include "phongentity.h" #include "mesh.h" #include "shader.h" #include "light.h" #include const char* const ForwardModule::flagStr[] = { "NORMAL_MAP", "AMBIENT_TEXTURE", "DIFFUSE_TEXTURE", "SPECULAR_TEXTURE", "ALPHA_MASK" }; const char* const ForwardModule::lightStr[] = { "AMBIENT_LIGHT", "DIRECTIONNAL_LIGHT", "POINT_LIGHT" }; void ForwardModule::renderGL(Camera* myCamera, Scene* scene) { // render ambient lighting lightPass(NULL, myCamera, scene, AMBIENT_LIGHT); // render directionnal lighting and point lighting for(SceneIterator* lightIt = scene->getLights(); lightIt->isValid(); lightIt->next()) { Light* l = lightIt->getItem(); unsigned int type = l->isDirectionnal() ? DIRECTIONNAL_LIGHT : POINT_LIGHT; lightPass(l, myCamera, scene, type); } } void ForwardModule::lightPass(Light* light, Camera* myCamera, Scene* scene, unsigned int type) { // loop over all types of geometry for(int i=0; ibind(); // bind light attributes if(type == DIRECTIONNAL_LIGHT) shader->bindVec3(shader->getLocation("dirLight"), light->getDir()); if(type == POINT_LIGHT) shader->bindVec3(shader->getLocation("pointLight"), light->getPos()); glm::vec3 color; if(type == AMBIENT_LIGHT) color = glm::vec3(0.1f); // add attribute, and setter for ambient lighting else color = light->getColor(); shader->bindVec3(shader->getLocation("lightColor"), color); for(SceneIterator* entityIt = scene->getGeometry(); entityIt->isValid(); entityIt->next()) { // compute matrix attributes PhongEntity* entity = entityIt->getItem(); glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix; glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix; glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); // loop over material groups for(int j=0; jgetMesh()->indiceGroups.size(); ++j) { Material* mat = entity->getMesh()->indiceGroups[i].material; if(mat->getFlags() == flags[i]) { // bind material attributes mat->bindAttributes(shader); shader->bindMatrix(shader->getLocation("viewMatrix"), myCamera->getViewMatrix()); shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix); shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix); shader->bindMatrix(shader->getLocation("MVP"), mvp); // draw geometry entity->drawGroup(j); } } } } } // modern opengl methods void ForwardModule::setShaderSource(ShaderSource* source) { shaderSources = source; } void ForwardModule::compileShaders(Scene* scene) { int size = 1 << NB_FLAGS; bool geometryFlags[size]; for(int i=0; i* EntityIt = scene->getGeometry(); EntityIt->isValid(); EntityIt->next()) { Mesh* m = EntityIt->getItem()->getMesh(); for(Mesh::Group &g : m->indiceGroups) geometryFlags[g.material->getFlags()] = true; } for(int i=0; i defines; defines.push_back(lightStr[AMBIENT_LIGHT]); 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]); // for each geometry flag, 3 shaders are compiled, one for each kind of lighting flags.push_back(i); // ambient shaders.push_back(shaderSources->compile(defines.size(), defines.data())); // directionnal defines[0] = lightStr[DIRECTIONNAL_LIGHT]; shaders.push_back(shaderSources->compile(defines.size(), defines.data())); // point defines[0] = lightStr[POINT_LIGHT]; shaders.push_back(shaderSources->compile(defines.size(), defines.data())); } } }