diff --git a/shaders/forward.frag.glsl b/shaders/forward.frag.glsl index e77ea04..33c95a0 100644 --- a/shaders/forward.frag.glsl +++ b/shaders/forward.frag.glsl @@ -49,8 +49,8 @@ layout(location = 0)out vec4 outColor; vec3 phongLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec){ float diffuseComponent = max(dot(normal, lightDir), 0); - float specularComponent = max(dot(halfVec, normal), 0); - return color*diffuseComponent*(kd+ks*pow(specularComponent, ns)); + float specularComponent = max(dot(halfVec, normal), 0); + return color*diffuseComponent*(kd+ks*pow(specularComponent, ns)); } float computeShadow(sampler2D shadowmap, vec3 shadow){ diff --git a/shaders/forward.vert.glsl b/shaders/forward.vert.glsl index 2309270..d5a2bbf 100644 --- a/shaders/forward.vert.glsl +++ b/shaders/forward.vert.glsl @@ -67,5 +67,5 @@ void main(void) { varTexCoord = inTexCoord.xy; - gl_Position = MVP * vec4(inPosition, 1.0); + gl_Position = MVP * vec4(inPosition, 1.0); } diff --git a/shaders/posteffect.frag.glsl b/shaders/posteffect.frag.glsl new file mode 100644 index 0000000..b06c528 --- /dev/null +++ b/shaders/posteffect.frag.glsl @@ -0,0 +1,12 @@ +#version 330 core + +uniform sampler2DRect colorSampler; +uniform sampler2DRect depthSampler; + +in ivec2 varTexCoord; + +layout(location = 0)out vec4 outColor; + +void main(void) { + outColor = texelFetch(colorSampler, varTexCoord); +} diff --git a/shaders/posteffect.vert.glsl b/shaders/posteffect.vert.glsl new file mode 100644 index 0000000..ab728da --- /dev/null +++ b/shaders/posteffect.vert.glsl @@ -0,0 +1,12 @@ +#version 330 core + +uniform mat4 MVP; + +out vec2 varTexCoord; + +layout(location = 0)in vec3 inPosition; + +void main(void) { + varTexCoord = inPosition.xy; + gl_Position = MVP * vec4(inPosition, 1.0); +} diff --git a/src/forwardmodule.cpp b/src/forwardmodule.cpp index 05132fd..1a735e4 100644 --- a/src/forwardmodule.cpp +++ b/src/forwardmodule.cpp @@ -65,7 +65,7 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light) switch(light->getType()) { case Light::DIRECTIONNAL: - shader->bindVec3(shader->getLocation("dirLight"), light->getDir()); + shader->bindVec3(shader->getLocation("dirLight"), -light->getDir()); shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); if(light->isShadowCaster()) { @@ -94,7 +94,7 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light) glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); if(light != NULL && light->isShadowCaster()) { - glm::mat4 lightMVP = light->getProjectionMatrix() * (light->getViewMatrix() * entity->modelMatrix); + glm::mat4 lightMVP = Light::biasMatrix * light->getProjectionMatrix() * light->getViewMatrix() * entity->modelMatrix; shader->bindMat4(shader->getLocation("lightMVP"), lightMVP); } shader->bindMat4(shader->getLocation("viewMatrix"), myCamera->getViewMatrix()); diff --git a/src/framebuffer.cpp b/src/framebuffer.cpp index 7771a31..c1de13d 100644 --- a/src/framebuffer.cpp +++ b/src/framebuffer.cpp @@ -21,9 +21,17 @@ void FrameBuffer::addTexture(Texture* tex, GLenum attachment) { textures.push_back(tex); bindFBO(); - glAssert(glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0)); - if(attachment != GL_DEPTH_ATTACHMENT) - attachments.push_back(attachment); + if(tex->isCubeMap()) + { + // http://cg.siomax.ru/index.php/computer-graphics/10-one-pass-rendering-to-cube-map + } + else + { + glAssert(glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0)); + if(attachment != GL_DEPTH_ATTACHMENT) + attachments.push_back(attachment); + } + } } diff --git a/src/light.cpp b/src/light.cpp index 4c49829..f2908e1 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -17,6 +17,12 @@ const char* Light::flagStr[] = { "SHADOWMAP" }; +const glm::mat4 Light::biasMatrix( + 0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.0, + 0.5, 0.5, 0.5, 1.0); + Light::Light() { initPointLight(); @@ -62,6 +68,8 @@ bool Light::isDirectionnal() void Light::initShadowMap(int resWidth, int resHeight, glm::vec3 dim) { + shadowMapWidth = resWidth; + shadowMapHeight = resHeight; viewMatrix = glm::lookAt(position, position+direction, glm::vec3(0, 1, 0)); if(type == DIRECTIONNAL) projectionMatrix = glm::ortho(-dim.x/2, dim.x/2, -dim.y/2, dim.y/2, -dim.z/2, dim.z/2); @@ -87,12 +95,13 @@ void Light::initShadowMap(int resWidth, int resHeight, glm::vec3 dim) void Light::generateShadowMap(Scene* scene) { - glAssert(glViewport(0, 0, 512, 512)); + glAssert(glViewport(0, 0, shadowMapWidth, shadowMapHeight)); shadowMap->bindFBO(); glAssert(glClearDepth(1.0)); glAssert(glClear(GL_DEPTH_BUFFER_BIT)); glAssert(glEnable(GL_DEPTH_TEST)); - glDepthFunc(GL_LESS); + glAssert(glDepthFunc(GL_LESS)); + glAssert(glCullFace(GL_FRONT)); for(SceneIterator* entityIt = scene->getGeometry(); entityIt->isValid(); entityIt->next()) { @@ -116,9 +125,11 @@ void Light::generateShadowMap(Scene* scene) { entity->drawGroup(j, false, false, false); shaders[0]->bind(); + shaders[0]->bindMat4(shaders[1]->getLocation("MVP"), lightMVP); } } } + glAssert(glCullFace(GL_BACK)); } Texture* Light::getShadowMap() @@ -154,10 +165,16 @@ unsigned int Light::getFlags(Light* l) const char* Light::vertSource = "#version 330 core\n\ layout(location = 0)in vec3 inPosition;\n\ + #ifdef ALPHA_MASK\n\ + layout(location = 2)in vec2 inTexCoord;\n\ out vec3 varTexCoord;\n\ + #endif\n\ uniform mat4 MVP;\n\ void main()\n\ {\n\ + #ifdef ALPHA_MASK\n\ + varTexCoord = inTexCoord.xy;\n\ + #endif\n\ gl_Position = MVP * vec4(inPosition, 1.0);\n\ }\n"; @@ -165,8 +182,8 @@ const char* Light::fragSource = "#version 330 core\n\ #ifdef ALPHA_MASK\n\ uniform sampler2D alphaMask;\n\ - #endif\n\ in vec3 varTexCoord;\n\ + #endif\n\ out float fragmentdepth;\n\ void main()\n\ {\n\ diff --git a/src/light.h b/src/light.h index 86c696b..6157c38 100644 --- a/src/light.h +++ b/src/light.h @@ -29,6 +29,7 @@ public: NB_LIGHT_FLAGS }; static const char* flagStr[]; + static const glm::mat4 biasMatrix; Light(); void initDirectionnalLight(glm::vec3 dir = glm::vec3(1, 0, 0), glm::vec3 lightColor = glm::vec3(1)); @@ -67,6 +68,8 @@ private: // shadowmap attributes bool shadowCaster; + int shadowMapWidth; + int shadowMapHeight; FrameBuffer* shadowMap; Shader* shaders[2]; glm::mat4 viewMatrix; diff --git a/src/meshbuilder.cpp b/src/meshbuilder.cpp index a21b31d..66c8afc 100644 --- a/src/meshbuilder.cpp +++ b/src/meshbuilder.cpp @@ -82,34 +82,57 @@ int MeshBuilder::getNbGroups() return indiceGroups.size(); } -bool MeshBuilder::operator() (const int& vertId1, const int& vertId2) const +class VertexComparator { - if(positions[vertId1] != positions[vertId2]) - return (positions[vertId1].x + positions[vertId1].y + positions[vertId1].z) > (positions[vertId2].x + positions[vertId2].y + positions[vertId2].z); - if(hasTexCoords()) +public: + // c'est crade mais j'ai pas trouvé d'autre moyen pour le moment + static MeshBuilder* mesh; + static void setMesh(MeshBuilder* m) {VertexComparator::mesh = m;} + + bool operator() (const int& vertId1, const int& vertId2) const { - if(texCoords[vertId1] != texCoords[vertId2]) - return (texCoords[vertId1].x + texCoords[vertId1].y) > (texCoords[vertId2].x + texCoords[vertId2].y); + if(mesh->positions[vertId1].x != mesh->positions[vertId2].x) + return (mesh->positions[vertId1].x < mesh->positions[vertId2].x); + if(mesh->positions[vertId1].y != mesh->positions[vertId2].y) + return (mesh->positions[vertId1].y < mesh->positions[vertId2].y); + if(mesh->positions[vertId1].z != mesh->positions[vertId2].z) + return (mesh->positions[vertId1].z < mesh->positions[vertId2].z); + if(mesh->hasTexCoords()) + { + if(mesh->texCoords[vertId1].x != mesh->texCoords[vertId2].x) + return (mesh->texCoords[vertId1].x < mesh->texCoords[vertId2].x); + if(mesh->texCoords[vertId1].y != mesh->texCoords[vertId2].y) + return (mesh->texCoords[vertId1].y < mesh->texCoords[vertId2].y); + } + if(mesh->hasNormals()) + { + if(mesh->normals[vertId1].x != mesh->normals[vertId2].x) + return (mesh->normals[vertId1].x < mesh->normals[vertId2].x); + if(mesh->normals[vertId1].y != mesh->normals[vertId2].y) + return (mesh->normals[vertId1].y < mesh->normals[vertId2].y); + if(mesh->normals[vertId1].z != mesh->normals[vertId2].z) + return (mesh->normals[vertId1].z < mesh->normals[vertId2].z); + } + return false; } - if(hasNormals()) - { - if(normals[vertId1] != normals[vertId2]) - return (normals[vertId1].x + normals[vertId1].y + normals[vertId1].z) > (normals[vertId2].x + normals[vertId2].y + normals[vertId2].z); - } - return false; -} +}; + +MeshBuilder* VertexComparator::mesh = NULL; void MeshBuilder::mergeVertices() { std::vector swapped; - std::set vertexSet; + std::set vertexSet; + VertexComparator::setMesh(this); int size = positions.size(); for(Group &g : indiceGroups) for(int i=0; i::iterator,bool> ret = vertexSet.insert(g.indices[i]); + if(g.indices[i] >= positions.size()) + g.indices[i] = swapped[size - g.indices[i]]; + std::pair::iterator,bool> ret = vertexSet.insert(g.indices[i]); if(!ret.second) // duplicate found { // updating indices references @@ -138,13 +161,6 @@ void MeshBuilder::mergeVertices() } fprintf(stdout, "found %d vertex duplicates\n", swapped.size()); - - for(Group &g : indiceGroups) - for(int i=0; i= positions.size()) - g.indices[i] = swapped[size - g.indices[i]]; - } } void MeshBuilder::computeNormals() diff --git a/src/posteffectmodule.cpp b/src/posteffectmodule.cpp index e2bd001..cdf2b4d 100644 --- a/src/posteffectmodule.cpp +++ b/src/posteffectmodule.cpp @@ -3,6 +3,7 @@ #include "glassert.h" #include "texture.h" #include "shader.h" +#include const GLfloat PostEffectModule::vertices[] = { 0.0f, 1.0f, 0.0f, @@ -39,6 +40,8 @@ PostEffectModule::PostEffectModule(int width, int height) glAssert(glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(GLfloat), vertices, GL_STATIC_DRAW)); glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, NULL)); glAssert(glEnableVertexAttribArray(0)); + + mvp = glm::ortho(0, width, 0, height); } PostEffectModule::~PostEffectModule() diff --git a/src/posteffectmodule.h b/src/posteffectmodule.h index e5dd920..490df0f 100644 --- a/src/posteffectmodule.h +++ b/src/posteffectmodule.h @@ -2,6 +2,7 @@ #define POSTEFFECTMODULE_H #include +#include #include "module.h" class Shader; @@ -16,6 +17,7 @@ class PostEffectModule : public Module Shader* shader; GLuint colorLocation; GLuint depthLocation; + glm::mat4 mvp; static const GLfloat vertices[]; diff --git a/src/texture.cpp b/src/texture.cpp index ae1ccd9..257ab9c 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -12,9 +12,19 @@ Texture::Texture(GLenum format, { glAssert(glGenTextures(1, &texId)); glAssert(glBindTexture(target, texId)); - glAssert(glTexImage2D(target, 0, internal_format, width, height, 0, format, dataType, NULL)); - setWrap(GL_REPEAT); - setFiltering(GL_LINEAR); + if(target == GL_TEXTURE_2D) + { + glAssert(glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, dataType, NULL)); + setWrap(GL_REPEAT); + setFiltering(GL_LINEAR); + } + else if(target == GL_TEXTURE_CUBE_MAP) + { + for(int i=0; i<6; ++i) + glAssert(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, width, height, 0, format, dataType, NULL)); + setWrap(GL_CLAMP_TO_EDGE); + setFiltering(GL_LINEAR); + } } Texture::Texture(Image* myImage) : target(GL_TEXTURE_2D) diff --git a/src/texture.h b/src/texture.h index 94008c6..c913f94 100644 --- a/src/texture.h +++ b/src/texture.h @@ -34,6 +34,7 @@ public: GLenum getTarget() {return target;} void setWrap(GLint wrap); void setFiltering(GLint filter); + bool isCubeMap() {return target == GL_TEXTURE_CUBE_MAP;} }; #endif // TEXTURE_H