diff --git a/data/shaders/untextured_object.frag b/data/shaders/untextured_object.frag new file mode 100644 index 000000000..ccbc54ab9 --- /dev/null +++ b/data/shaders/untextured_object.frag @@ -0,0 +1,19 @@ +#version 130 +uniform sampler2D DiffuseMap; +uniform sampler2D SpecularMap; +uniform sampler2D SSAO; +uniform vec2 screen; +uniform vec3 ambient; +in vec4 color; +out vec4 FragColor; + +void main(void) +{ + vec2 tc = gl_FragCoord.xy / screen; + vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture(SpecularMap, tc).xyz; + float ao = texture(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + + FragColor = vec4(color.xyz * LightFactor * ao, 1.); +} diff --git a/data/shaders/untextured_object.vert b/data/shaders/untextured_object.vert new file mode 100644 index 000000000..1dafaa08e --- /dev/null +++ b/data/shaders/untextured_object.vert @@ -0,0 +1,12 @@ +#version 130 +uniform mat4 ModelViewProjectionMatrix; + +in vec3 Position; +in vec4 Color; +out vec4 color; + +void main(void) +{ + color = Color; + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); +} diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index a43049f24..bfa453335 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -242,6 +242,7 @@ void Shaders::loadShaders() MeshShader::ObjectPass1Shader::init(); MeshShader::ObjectRefPass1Shader::init(); MeshShader::ObjectPass2Shader::init(); + MeshShader::UntexturedObjectShader::init(); MeshShader::ObjectRefPass2Shader::init(); MeshShader::SphereMapShader::init(); MeshShader::SplattingShader::init(); @@ -368,6 +369,41 @@ namespace MeshShader glUniform3f(uniform_ambient, s.r, s.g, s.b); } + GLuint UntexturedObjectShader::Program; + GLuint UntexturedObjectShader::attrib_position; + GLuint UntexturedObjectShader::attrib_color; + GLuint UntexturedObjectShader::uniform_MVP; + GLuint UntexturedObjectShader::uniform_DiffuseMap; + GLuint UntexturedObjectShader::uniform_SpecularMap; + GLuint UntexturedObjectShader::uniform_SSAO; + GLuint UntexturedObjectShader::uniform_screen; + GLuint UntexturedObjectShader::uniform_ambient; + + void UntexturedObjectShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/untextured_object.vert").c_str(), file_manager->getAsset("shaders/untextured_object.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_color = glGetAttribLocation(Program, "Color"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void UntexturedObjectShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + } + + GLuint ObjectRefPass2Shader::Program; GLuint ObjectRefPass2Shader::attrib_position; GLuint ObjectRefPass2Shader::attrib_texcoord; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index b9c6ad5f9..370e2c6a9 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -59,6 +59,17 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); }; +class UntexturedObjectShader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_color; + static GLuint uniform_MVP, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); +}; + class ObjectRefPass2Shader { public: diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 27f36bd19..87b1d07ba 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -366,6 +366,24 @@ void STKMesh::drawGrassPass2(const GLMesh &mesh) glDrawElements(ptype, count, itype, 0); } +void STKMesh::drawUntexturedObject(const GLMesh &mesh) +{ + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + setTexture(0, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(1, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(2, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + + glUseProgram(MeshShader::UntexturedObjectShader::Program); + MeshShader::UntexturedObjectShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + +} + void STKMesh::drawObjectPass2(const GLMesh &mesh) { GLenum ptype = mesh.PrimitiveType; @@ -484,9 +502,6 @@ void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type) void STKMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { - - if (!mesh.textures[0]) - return; switch (irr_driver->getPhase()) { case 0: @@ -528,6 +543,8 @@ void STKMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type) drawObjectRefPass2(mesh); else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) drawGrassPass2(mesh); + else if (!mesh.textures[0]) + drawUntexturedObject(mesh); else drawObjectPass2(mesh); break; @@ -613,6 +630,11 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride); } + else if (!mesh.textures[0]) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::UntexturedObjectShader::attrib_position, -1, -1, -1, -1, -1, MeshShader::UntexturedObjectShader::attrib_color, mesh.Stride); + } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 7a3352153..0ed8b9638 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -43,6 +43,7 @@ protected: void drawObjectPass2(const GLMesh &mesh); void drawObjectRefPass2(const GLMesh &mesh); void drawGrassPass2(const GLMesh &mesh); + void drawUntexturedObject(const GLMesh &mesh); // Forward pass (for transparents meshes) void drawTransparentObject(const GLMesh &mesh);