From d4b263761e15604c15f9ec034356beb31edc08a1 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 7 May 2014 13:23:22 +1000 Subject: [PATCH 01/10] Fix #1231 - stk-code/data not found on windows (secondary report). --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d94deb40..ba13be3fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -316,13 +316,13 @@ install(FILES data/supertuxkart_32.png data/supertuxkart_128.png DESTINATION sha install(FILES data/supertuxkart.appdata DESTINATION share/appdata) # ==== Checking if data folder exists ==== -if(NOT IS_DIRECTORY ../data) +if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data) message( FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/data folder doesn't exist" ) endif() # ==== Checking if stk-assets folder exists ==== if(CHECK_ASSETS) - if(NOT IS_DIRECTORY ../../stk-assets) + if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../stk-assets) set (CUR_DIR ${CMAKE_CURRENT_SOURCE_DIR}) get_filename_component(PARENT_DIR ${CUR_DIR} PATH) message( FATAL_ERROR "${PARENT_DIR}/stk-assets folder doesn't exist. " From fd7399d98334d293315460e082947f7461f9703b Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 7 May 2014 23:57:07 +0200 Subject: [PATCH 02/10] Use instancing to expand shadows instead of GS --- data/shaders/instanciedshadow.vert | 13 +++++++++- data/shaders/shadow.geom | 34 ++++---------------------- data/shaders/shadow.vert | 13 +++++++++- src/graphics/stkinstancedscenenode.cpp | 26 ++++++++++---------- src/graphics/stkmesh.cpp | 4 +-- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/data/shaders/instanciedshadow.vert b/data/shaders/instanciedshadow.vert index 0c2377b93..fbc28db16 100644 --- a/data/shaders/instanciedshadow.vert +++ b/data/shaders/instanciedshadow.vert @@ -1,3 +1,12 @@ +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; + in vec3 Origin; in vec3 Orientation; in vec3 Scale; @@ -6,13 +15,15 @@ in vec3 Position; in vec2 Texcoord; out vec2 tc; +out int layerId; mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); void main(void) { + layerId = gl_InstanceID & 3; mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); - gl_Position = ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); tc = Texcoord; } \ No newline at end of file diff --git a/data/shaders/shadow.geom b/data/shaders/shadow.geom index e57567f84..4824679d7 100644 --- a/data/shaders/shadow.geom +++ b/data/shaders/shadow.geom @@ -1,43 +1,19 @@ -layout (std140) uniform MatrixesData -{ - mat4 ViewMatrix; - mat4 ProjectionMatrix; - mat4 InverseViewMatrix; - mat4 InverseProjectionMatrix; - mat4 ShadowViewProjMatrixes[4]; -}; - -#if __VERSION__ >= 400 -layout(triangles, invocations=4) in; -#else layout(triangles) in; -#endif -layout(triangle_strip, max_vertices=12) out; +layout(triangle_strip, max_vertices=4) out; in vec2 tc[3]; +in int layerId[3]; out vec2 uv; -void emitToLayer(int layerId) +void main(void) { - gl_Layer = layerId; + gl_Layer = layerId[0]; for(int i=0; i<3; i++) { uv = tc[i]; - gl_Position = ShadowViewProjMatrixes[layerId] * gl_in[i].gl_Position; + gl_Position = gl_in[i].gl_Position; EmitVertex(); } EndPrimitive(); } - -void main(void) -{ -#if __VERSION__ >= 400 - emitToLayer(gl_InvocationID); -#else - for (int j = 0; j<4; j++) - { - emitToLayer(j); - } -#endif -} diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index 1c45d5fdc..aafe186ce 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -1,12 +1,23 @@ +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; + uniform mat4 ModelMatrix; in vec3 Position; in vec2 Texcoord; out vec2 tc; +out int layerId; void main(void) { + layerId = gl_InstanceID & 3; tc = Texcoord; - gl_Position = ModelMatrix * vec4(Position, 1.); + gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); } diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index 146a28e70..b57ff462d 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -56,18 +56,18 @@ void STKInstancedSceneNode::createGLMeshes() isMaterialInitialized = false; } -template +template void setInstanceAttribPointer() { glEnableVertexAttribArray(T::attrib_origin); glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0); - glVertexAttribDivisor(T::attrib_origin, 1); + glVertexAttribDivisor(T::attrib_origin, divisor); glEnableVertexAttribArray(T::attrib_orientation); glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(T::attrib_orientation, 1); + glVertexAttribDivisor(T::attrib_orientation, divisor); glEnableVertexAttribArray(T::attrib_scale); glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(T::attrib_scale, 1); + glVertexAttribDivisor(T::attrib_scale, divisor); } void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) @@ -80,12 +80,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); if (irr_driver->getGLSLVersion() >= 150) { mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); } break; case FPSM_ALPHA_REF_TEXTURE: @@ -94,12 +94,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); if (irr_driver->getGLSLVersion() >= 150) { mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); } break; case FPSM_GRASS: @@ -108,7 +108,7 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria glGenBuffers(1, &instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; default: return; @@ -122,19 +122,19 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; case SM_ALPHA_REF_TEXTURE: mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; case SM_GRASS: mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, MeshShader::InstancedGrassPass2Shader::attrib_normal, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); - setInstanceAttribPointer(); + setInstanceAttribPointer(); break; default: return; @@ -220,7 +220,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElementsInstanced(ptype, count, itype, 0, instance_count); + glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count); } static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 981da15b9..e6a8db142 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -710,7 +710,7 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); + glDrawElementsInstanced(ptype, count, itype, 0, 4); } void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) @@ -724,7 +724,7 @@ void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); + glDrawElementsInstanced(ptype, count, itype, 0, 4); } bool isObject(video::E_MATERIAL_TYPE type) From cc368103b0d9e2e0fc58d5163cd75781f80f4298 Mon Sep 17 00:00:00 2001 From: vlj Date: Thu, 8 May 2014 00:03:21 +0200 Subject: [PATCH 03/10] Remove an extra EndQuery --- src/graphics/render.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index ab1972eb8..b6fa2518b 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -985,7 +985,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } - gl_driver->extGlEndQuery(GL_TIME_ELAPSED); } static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z) From a73f03a2c4346cf947cac86b7063851613b8935f Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 8 May 2014 01:16:02 +0200 Subject: [PATCH 04/10] Make use of gl_amd_vertex_shader_layer when available --- data/shaders/instanciedshadow.vert | 12 ++++- data/shaders/shadow.geom | 2 +- data/shaders/shadow.vert | 10 ++++ src/graphics/glwrap.cpp | 2 + src/graphics/irr_driver.cpp | 8 ++++ src/graphics/irr_driver.hpp | 6 +++ src/graphics/shaders.cpp | 74 ++++++++++++++++++++++-------- 7 files changed, 94 insertions(+), 20 deletions(-) diff --git a/data/shaders/instanciedshadow.vert b/data/shaders/instanciedshadow.vert index fbc28db16..e421aef03 100644 --- a/data/shaders/instanciedshadow.vert +++ b/data/shaders/instanciedshadow.vert @@ -14,16 +14,26 @@ in vec3 Scale; in vec3 Position; in vec2 Texcoord; +#ifdef VSLayer +out vec2 uv; +#else out vec2 tc; out int layerId; +#endif mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale); void main(void) { - layerId = gl_InstanceID & 3; mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); +#ifdef VSLayer + gl_Layer = gl_InstanceID & 3; + gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); + uv = Texcoord; +#else + layerId = gl_InstanceID & 3; gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); tc = Texcoord; +#endif } \ No newline at end of file diff --git a/data/shaders/shadow.geom b/data/shaders/shadow.geom index 4824679d7..9a1802834 100644 --- a/data/shaders/shadow.geom +++ b/data/shaders/shadow.geom @@ -1,5 +1,5 @@ layout(triangles) in; -layout(triangle_strip, max_vertices=4) out; +layout(triangle_strip, max_vertices=3) out; in vec2 tc[3]; in int layerId[3]; diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index aafe186ce..d7c389b2f 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -12,12 +12,22 @@ uniform mat4 ModelMatrix; in vec3 Position; in vec2 Texcoord; +#ifdef VSLayer +out vec2 uv; +#else out vec2 tc; out int layerId; +#endif void main(void) { +#ifdef VSLayer + gl_Layer = gl_InstanceID & 3; + uv = Texcoord; + gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * vec4(Position, 1.); +#else layerId = gl_InstanceID & 3; tc = Texcoord; gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * vec4(Position, 1.); +#endif } diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 36ea74a22..fbe44bff2 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -236,6 +236,8 @@ GLuint LoadShader(const char * file, unsigned type) Code += "//" + std::string(file) + "\n"; if (UserConfigParams::m_ubo_disabled) Code += "#define UBO_DISABLED\n"; + if (irr_driver->hasVSLayerExtension()) + Code += "#define VSLayer\n"; if (Stream.is_open()) { std::string Line = ""; diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index dcf85200b..1d61bfe14 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -441,6 +441,14 @@ void IrrDriver::initDevice() Log::info("IrrDriver", "OPENGL VERSION IS %d.%d", GLMajorVersion, GLMinorVersion); m_glsl = (GLMajorVersion > 3 || (GLMajorVersion == 3 && GLMinorVersion >= 1)); + // Parse extensions + hasVSLayer = false; + const GLubyte *extensions = glGetString(GL_EXTENSIONS); + if (strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL) + hasVSLayer = true; + + + // This remaps the window, so it has to be done before the clear to avoid flicker m_device->setResizable(false); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index b669a47c1..32fc04029 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -92,6 +92,7 @@ class IrrDriver : public IEventReceiver, public NoCopy { private: int GLMajorVersion, GLMinorVersion; + bool hasVSLayer; /** The irrlicht device. */ IrrlichtDevice *m_device; /** Irrlicht scene manager. */ @@ -171,6 +172,11 @@ public: return 120; } + bool hasVSLayerExtension() const + { + return hasVSLayer; + } + float getExposure() const { return m_exposure; diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index ad1969187..28e441e46 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1500,10 +1500,19 @@ namespace MeshShader attrib_position = -1; return; } - Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + if (irr_driver->hasVSLayerExtension()) + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + } + else + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + } attrib_position = glGetAttribLocation(Program, "Position"); uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); @@ -1530,11 +1539,21 @@ namespace MeshShader attrib_position = -1; return; } - Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), - GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + if (irr_driver->hasVSLayerExtension()) + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + } + else + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); + } attrib_position = glGetAttribLocation(Program, "Position"); attrib_origin = glGetAttribLocation(Program, "Origin"); attrib_orientation = glGetAttribLocation(Program, "Orientation"); @@ -1562,10 +1581,19 @@ namespace MeshShader attrib_texcoord = -1; return; } - Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + if (irr_driver->hasVSLayerExtension()) + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } + else + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); @@ -1597,11 +1625,21 @@ namespace MeshShader attrib_texcoord = -1; return; } - Program = LoadProgram( - GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), - GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), - GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), - GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + if (irr_driver->hasVSLayerExtension()) + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } + else + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(), + GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(), + GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); + } attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_origin = glGetAttribLocation(Program, "Origin"); From 4c9e2afe3153e5f7e25b1b965806c84ed0031654 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 8 May 2014 01:25:37 +0200 Subject: [PATCH 05/10] Cast some char to unsigned char --- src/graphics/render.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index b6fa2518b..c343bc5bc 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -1192,7 +1192,7 @@ static void displayCoeff(float *SHCoeff) } // Only for 9 coefficients -static void testSH(char *color[6], size_t width, size_t height, +static void testSH(unsigned char *color[6], size_t width, size_t height, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff) { float *Y00[6]; @@ -1373,9 +1373,9 @@ void IrrDriver::generateSkyboxCubemap() sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height); } - char *sh_rgba[6]; + unsigned char *sh_rgba[6]; for (unsigned i = 0; i < 6; i++) - sh_rgba[i] = new char[sh_w * sh_h * 4]; + sh_rgba[i] = new unsigned char[sh_w * sh_h * 4]; for (unsigned i = 0; i < 6; i++) { unsigned idx = texture_permutation[i]; @@ -1405,10 +1405,10 @@ void IrrDriver::generateSkyboxCubemap() const video::SColorf& ambientf = irr_driver->getSceneManager()->getAmbientLight(); video::SColor ambient = ambientf.toSColor(); - char *sh_rgba[6]; + unsigned char *sh_rgba[6]; for (unsigned i = 0; i < 6; i++) { - sh_rgba[i] = new char[sh_w * sh_h * 4]; + sh_rgba[i] = new unsigned char[sh_w * sh_h * 4]; for (int j = 0; j < sh_w * sh_h * 4; j+=4) { From c8638ec968bedbbd64cc7b92ed99badbfb8bb39a Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Wed, 7 May 2014 19:35:31 -0400 Subject: [PATCH 06/10] Add basic support to display GPU markers in the profiler --- src/graphics/glwrap.cpp | 7 ++++++ src/graphics/render.cpp | 13 +++++++---- src/utils/profiler.cpp | 52 ++++++++++++++++++++++++++++++++++++++++- src/utils/profiler.hpp | 4 ++++ 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 36ea74a22..9a8139e80 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -3,6 +3,7 @@ #include #include #include "config/user_config.hpp" +#include "utils/profiler.hpp" #ifdef _IRR_WINDOWS_API_ #define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) @@ -371,6 +372,9 @@ void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height) ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) { + if (!UserConfigParams::m_profiler_enabled) return; + if (profiler.isFrozen()) return; + irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver(); if (!timer.initialised) { @@ -381,6 +385,9 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) } ScopedGPUTimer::~ScopedGPUTimer() { + if (!UserConfigParams::m_profiler_enabled) return; + if (profiler.isFrozen()) return; + irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver(); gl_driver->extGlEndQuery(GL_TIME_ELAPSED); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index b6fa2518b..8f9fd8384 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -298,10 +298,7 @@ void IrrDriver::renderGLSL(float dt) else glDisable(GL_FRAMEBUFFER_SRGB); PROFILER_POP_CPU_MARKER(); - - for (unsigned i = 0; i < Q_LAST; i++) - Log::info("GPU Perf", "Phase %d : %d us\n", i, getGPUTimer(i).elapsedTimeus()); - + glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -446,7 +443,9 @@ void IrrDriver::renderSolidFirstPass() return; { +#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1)); +#endif glUseProgram(MeshShader::ObjectPass1Shader::Program); for (unsigned i = 0; i < GroupedFPSM::MeshSet.size(); ++i) { @@ -497,7 +496,9 @@ void IrrDriver::renderSolidSecondPass() setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST); { +#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2)); +#endif m_scene_manager->drawAll(scene::ESNRP_SOLID); glUseProgram(MeshShader::ObjectPass2Shader::Program); @@ -681,7 +682,9 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); { +#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); +#endif m_scene_manager->drawAll(scene::ESNRP_SOLID); } glDisable(GL_POLYGON_OFFSET_FILL); @@ -904,7 +907,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); { +#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT)); +#endif std::vector BucketedLN[15]; for (unsigned int i = 0; i < lightcount; i++) { diff --git a/src/utils/profiler.cpp b/src/utils/profiler.cpp index 379da9347..6cde51c57 100644 --- a/src/utils/profiler.cpp +++ b/src/utils/profiler.cpp @@ -37,6 +37,7 @@ Profiler profiler; #define LINE_HEIGHT 0.030f // height of a line representing a thread #define MARKERS_NAMES_POS core::rect(50,100,150,200) +#define GPU_MARKERS_NAMES_POS core::rect(50,165,150,250) #define TIME_DRAWN_MS 30.0f // the width of the profiler corresponds to TIME_DRAWN_MS milliseconds @@ -315,6 +316,48 @@ void Profiler::draw() } } + QueryPerf hovered_gpu_marker = Q_LAST; + long hovered_gpu_marker_elapsed = 0; + if (hovered_markers.size() == 0) + { + int gpu_y = y_offset + nb_thread_infos*line_height + line_height/2; + float total = 0; + for (unsigned i = 0; i < Q_LAST; i++) + { + total += irr_driver->getGPUTimer(i).elapsedTimeus(); + } + + static video::SColor colors[] = { + video::SColor(255, 255, 0, 0), + video::SColor(255, 0, 255, 0), + video::SColor(255, 0, 0, 255), + video::SColor(255, 255, 255, 0), + video::SColor(255, 255, 0, 255), + video::SColor(255, 0, 255, 255) + }; + + float curr_val = 0; + for (unsigned i = 0; i < Q_LAST; i++) + { + //Log::info("GPU Perf", "Phase %d : %d us\n", i, irr_driver->getGPUTimer(i).elapsedTimeus()); + + float elapsed = irr_driver->getGPUTimer(i).elapsedTimeus(); + core::rect pos((s32)(x_offset + (curr_val / total)*profiler_width), + (s32)(y_offset + gpu_y), + (s32)(x_offset + ((curr_val + elapsed) / total)*profiler_width), + (s32)(y_offset + gpu_y + line_height)); + + curr_val += elapsed; + GL32_draw2DRectangle(colors[i % 6], pos); + + if (pos.isPointInside(mouse_pos)) + { + hovered_gpu_marker = (QueryPerf)i; + hovered_gpu_marker_elapsed = irr_driver->getGPUTimer(i).elapsedTimeus(); + } + } + } + // Draw the end of the frame { s32 x_sync = (s32)(x_offset + factor*m_time_between_sync); @@ -343,6 +386,13 @@ void Profiler::draw() hovered_markers.pop(); } font->draw(text, MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00)); + + if (hovered_gpu_marker != Q_LAST) + { + std::ostringstream oss; + oss << "GPU marker " << hovered_gpu_marker << " : " << hovered_gpu_marker_elapsed << " us"; + font->draw(oss.str().c_str(), GPU_MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00)); + } } if (m_capture_report) @@ -397,6 +447,6 @@ void Profiler::drawBackground() (int)((1.0-MARGIN_X) * screen_size.Width), (int)((MARGIN_Y + 1.75f*LINE_HEIGHT) * screen_size.Height)); - video::SColor color(0xFF, 0xFF, 0xFF, 0xFF); + video::SColor color(0x88, 0xFF, 0xFF, 0xFF); GL32_draw2DRectangle(color, background_rect); } diff --git a/src/utils/profiler.hpp b/src/utils/profiler.hpp index 642b43cef..93fd925e4 100644 --- a/src/utils/profiler.hpp +++ b/src/utils/profiler.hpp @@ -164,11 +164,15 @@ public: bool getCaptureReport() const { return m_capture_report; } void setCaptureReport(bool captureReport); + + bool isFrozen() const { return m_freeze_state == FROZEN; } + protected: // TODO: detect on which thread this is called to support multithreading ThreadInfo& getThreadInfo() { return m_thread_infos[0]; } void drawBackground(); + }; #endif // PROFILER_HPP From 8a64d411d972975a856b964649ebc700926089a8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 8 May 2014 02:07:03 +0200 Subject: [PATCH 07/10] Remove debug arount scoped timer. --- src/graphics/render.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 64b96957c..442ba961a 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -443,9 +443,7 @@ void IrrDriver::renderSolidFirstPass() return; { -#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1)); -#endif glUseProgram(MeshShader::ObjectPass1Shader::Program); for (unsigned i = 0; i < GroupedFPSM::MeshSet.size(); ++i) { @@ -496,9 +494,9 @@ void IrrDriver::renderSolidSecondPass() setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST); { -#ifdef DEBUG + ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2)); -#endif + m_scene_manager->drawAll(scene::ESNRP_SOLID); glUseProgram(MeshShader::ObjectPass2Shader::Program); @@ -682,9 +680,7 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); { -#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); -#endif m_scene_manager->drawAll(scene::ESNRP_SOLID); } glDisable(GL_POLYGON_OFFSET_FILL); @@ -907,9 +903,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); { -#ifdef DEBUG ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT)); -#endif + std::vector BucketedLN[15]; for (unsigned int i = 0; i < lightcount; i++) { From 1746835caeb9a712faae26efb4bcca008b981aa2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 8 May 2014 02:14:31 +0200 Subject: [PATCH 08/10] Factorize godray visibility test in its own function. --- src/graphics/irr_driver.hpp | 1 + src/graphics/render.cpp | 62 ++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 32fc04029..2abd6d048 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -264,6 +264,7 @@ private: void renderSolidSecondPass(); void renderTransparent(); void renderParticles(); + void computeSunVisibility(); void computeCameraMatrix(scene::ICameraSceneNode * const camnode, Camera * const camera); void renderShadows(//ShadowImportanceProvider * const sicb, diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 442ba961a..35b4e9bfb 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -233,34 +233,7 @@ void IrrDriver::renderGLSL(float dt) PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); - // Is the lens flare enabled & visible? Check last frame's query. - const bool hasflare = World::getWorld()->getTrack()->hasLensFlare(); - const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); - if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays) - { - GLuint res = 0; - if (m_query_issued) - gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res); - m_post_processing->setSunPixels(res); - - // Prepare the query for the next frame. - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query); - m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); - m_scene_manager->drawAll(scene::ESNRP_CAMERA); - irr_driver->setPhase(GLOW_PASS); - m_sun_interposer->render(); - gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB); - m_query_issued = true; - - m_lensflare->setStrength(res / 4000.0f); - - if (hasflare) - m_lensflare->OnRegisterSceneNode(); - - // Make sure the color mask is reset - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } + computeSunVisibility(); PROFILER_POP_CPU_MARKER(); // We need to re-render camera due to the per-cam-node hack. @@ -420,6 +393,39 @@ void IrrDriver::renderFixed(float dt) // ---------------------------------------------------------------------------- +void IrrDriver::computeSunVisibility() +{ + // Is the lens flare enabled & visible? Check last frame's query. + const bool hasflare = World::getWorld()->getTrack()->hasLensFlare(); + const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); + irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); + if (UserConfigParams::m_light_shaft && hasgodrays)//hasflare || hasgodrays) + { + GLuint res = 0; + if (m_query_issued) + gl_driver->extGlGetQueryObjectuiv(m_lensflare_query, GL_QUERY_RESULT, &res); + m_post_processing->setSunPixels(res); + + // Prepare the query for the next frame. + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + gl_driver->extGlBeginQuery(GL_SAMPLES_PASSED_ARB, m_lensflare_query); + m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); + m_scene_manager->drawAll(scene::ESNRP_CAMERA); + irr_driver->setPhase(GLOW_PASS); + m_sun_interposer->render(); + gl_driver->extGlEndQuery(GL_SAMPLES_PASSED_ARB); + m_query_issued = true; + + m_lensflare->setStrength(res / 4000.0f); + + if (hasflare) + m_lensflare->OnRegisterSceneNode(); + + // Make sure the color mask is reset + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } +} + void IrrDriver::renderSolidFirstPass() { glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS)); From 5f6829b0715b04386d216a14cfb5dfb3415a1b75 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 8 May 2014 03:14:00 +0200 Subject: [PATCH 09/10] Simplify some code and have a function that render a scene from a cam pov --- src/graphics/irr_driver.hpp | 24 +-- src/graphics/post_processing.cpp | 2 +- src/graphics/render.cpp | 339 +++++++++---------------------- 3 files changed, 101 insertions(+), 264 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 2abd6d048..72419f2b9 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -265,22 +265,12 @@ private: void renderTransparent(); void renderParticles(); void computeSunVisibility(); - void computeCameraMatrix(scene::ICameraSceneNode * const camnode, - Camera * const camera); - void renderShadows(//ShadowImportanceProvider * const sicb, - scene::ICameraSceneNode * const camnode, - //video::SOverrideMaterial &overridemat, - Camera * const camera); - void renderGlow(video::SOverrideMaterial &overridemat, - std::vector& glows, - const core::aabbox3df& cambox, - int cam); - void renderLights(const core::aabbox3df& cambox, - scene::ICameraSceneNode * const camnode, - video::SOverrideMaterial &overridemat, - int cam, float dt); - void renderDisplacement(video::SOverrideMaterial &overridemat, - int cam); + void renderScene(scene::ICameraSceneNode * const camnode, std::vector& glows, float dt, bool hasShadows); + void computeCameraMatrix(scene::ICameraSceneNode * const camnode); + void renderShadows(); + void renderGlow(std::vector& glows); + void renderLights(float dt); + void renderDisplacement(); void doScreenShot(); public: IrrDriver(); @@ -288,7 +278,7 @@ public: void initDevice(); void reset(); void generateSkyboxCubemap(); - void renderSkybox(); + void renderSkybox(const scene::ICameraSceneNode *camera); void setPhase(STKRenderingPass); STKRenderingPass getPhase() const; const std::vector &getShadowViewProj() const diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 1566cb11e..959ac351b 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -665,7 +665,7 @@ void PostProcessing::render() // Grab the sky glBindFramebuffer(GL_FRAMEBUFFER, out_fbo); glClear(GL_COLOR_BUFFER_BIT); - irr_driver->renderSkybox(); +// irr_driver->renderSkybox(); // Set the sun's color const SColor col = World::getWorld()->getTrack()->getSunColor(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 35b4e9bfb..2bfdf7eee 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -140,119 +140,7 @@ void IrrDriver::renderGLSL(float dt) camera->activate(); rg->preRenderCallback(camera); // adjusts start referee - const u32 bgnodes = m_background.size(); -/* if (bgnodes) - { - // If there are background nodes (3d skybox), draw them now. - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); - - m_renderpass = scene::ESNRP_SKY_BOX; - m_scene_manager->drawAll(m_renderpass); - - const video::SOverrideMaterial prev = overridemat; - overridemat.Enabled = 1; - overridemat.EnableFlags = video::EMF_MATERIAL_TYPE; - overridemat.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - - for (i = 0; i < bgnodes; i++) - { - m_background[i]->setPosition(camnode->getPosition() * 0.97f); - m_background[i]->updateAbsolutePosition(); - m_background[i]->render(); - } - - overridemat = prev; - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, true); - }*/ - - // Get Projection and view matrix - computeCameraMatrix(camnode, camera); - glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); - - - // Fire up the MRT - PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); - renderSolidFirstPass(); - PROFILER_POP_CPU_MARKER(); - - - // Todo : reenable glow and shadows - //ShadowImportanceProvider * const sicb = (ShadowImportanceProvider *) - // irr_driver->getCallback(ES_SHADOW_IMPORTANCE); - //sicb->updateIPVMatrix(); - - // Used to cull glowing items & lights - const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox(); - - PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); - // Shadows - if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && - UserConfigParams::m_shadows && track->hasShadows()) - { - renderShadows(camnode, camera); - } - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); - - // Lights - renderLights(cambox, camnode, overridemat, cam, dt); - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); - if (!UserConfigParams::m_dynamic_lights) - { - glEnable(GL_FRAMEBUFFER_SRGB); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS)); - } - renderSolidSecondPass(); - PROFILER_POP_CPU_MARKER(); - - if (UserConfigParams::m_dynamic_lights && World::getWorld()->isFogEnabled()) - { - PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); - m_post_processing->renderFog(); - PROFILER_POP_CPU_MARKER(); - } - - PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF); - renderSkybox(); - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); - // Render anything glowing. - if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow) - { - irr_driver->setPhase(GLOW_PASS); - renderGlow(overridemat, glows, cambox, cam); - } // end glow - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); - computeSunVisibility(); - PROFILER_POP_CPU_MARKER(); - - // We need to re-render camera due to the per-cam-node hack. - PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); - renderTransparent(); - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); - renderParticles(); - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF); - // Handle displacing nodes, if any - const u32 displacingcount = m_displacing.size(); - if (displacingcount) - { - renderDisplacement(overridemat, cam); - } - PROFILER_POP_CPU_MARKER(); + renderScene(camnode, glows, dt, track->hasShadows()); PROFILER_POP_CPU_MARKER(); @@ -317,6 +205,83 @@ void IrrDriver::renderGLSL(float dt) getPostProcessing()->update(dt); } +void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector& glows, float dt, bool hasShadow) +{ + computeCameraMatrix(camnode); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); + + PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); + renderSolidFirstPass(); + PROFILER_POP_CPU_MARKER(); + + const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox(); + + PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); + // Shadows + if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && + UserConfigParams::m_shadows && hasShadow) + { + renderShadows(); + } + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); + + // Lights + renderLights(dt); + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); + if (!UserConfigParams::m_dynamic_lights) + { + glEnable(GL_FRAMEBUFFER_SRGB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + else + { + glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS)); + } + renderSolidSecondPass(); + PROFILER_POP_CPU_MARKER(); + + if (UserConfigParams::m_dynamic_lights && World::getWorld()->isFogEnabled()) + { + PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); + m_post_processing->renderFog(); + PROFILER_POP_CPU_MARKER(); + } + + PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0xFF); + renderSkybox(camnode); + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00); + // Render anything glowing. + if (!m_mipviz && !m_wireframe && UserConfigParams::m_glow) + { + irr_driver->setPhase(GLOW_PASS); + renderGlow(glows); + } // end glow + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0x00, 0xFF, 0xFF); + computeSunVisibility(); + PROFILER_POP_CPU_MARKER(); + + // We need to re-render camera due to the per-cam-node hack. + PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); + renderTransparent(); + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); + renderParticles(); + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF); + renderDisplacement(); + PROFILER_POP_CPU_MARKER(); +} + // -------------------------------------------- void IrrDriver::renderFixed(float dt) @@ -560,10 +525,12 @@ void IrrDriver::renderParticles() m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT); } -void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, - Camera * const camera) +void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode) { - m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); + m_scene_manager->drawAll(scene::ESNRP_CAMERA); + irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)); + irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); + irr_driver->genProjViewMatrix(); const Vec3 *vmin, *vmax; World::getWorld()->getTrack()->getAABB(&vmin, &vmax); @@ -622,17 +589,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, float up = box.MaxEdge.Y; float down = box.MinEdge.Y; -/* left -= fmodf(left, units_per_w); - right -= fmodf(right, units_per_w); - up -= fmodf(up, units_per_h); - down -= fmodf(down, units_per_h); - z -= fmodf(z, 0.5f); - - // FIXME: quick and dirt (and wrong) workaround to avoid division by zero - if (left == right) right += 0.1f; - if (up == down) down += 0.1f; - if (z == 30) z += 0.1f;*/ - core::matrix4 tmp_matrix; tmp_matrix.buildProjectionMatrixOrthoLH(left, right, @@ -647,12 +603,7 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, assert(sun_ortho_matrix.size() == 4); camnode->setNearValue(oldnear); camnode->setFarValue(oldfar); - camnode->render(); - camera->activate(); - m_scene_manager->drawAll(scene::ESNRP_CAMERA); - irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)); - irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); - irr_driver->genProjViewMatrix(); +// camnode->render(); float *tmp = new float[16 * 8]; @@ -669,12 +620,8 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, delete tmp; } -void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, - scene::ICameraSceneNode * const camnode, - //video::SOverrideMaterial &overridemat, - Camera * const camera) +void IrrDriver::renderShadows() { - irr_driver->setPhase(SHADOW_PASS); glDisable(GL_BLEND); glEnable(GL_POLYGON_OFFSET_FILL); @@ -693,104 +640,11 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); - - - //sun_ortho_matrix *= m_suncam->getViewMatrix(); -/* ((SunLightProvider *) m_shaders->m_callbacks[ES_SUNLIGHT])->setShadowMatrix(ortho); - sicb->setShadowMatrix(ortho); - - overridemat.Enabled = 0; - - // Render the importance map - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLLAPSE), true, true); - - m_shadow_importance->render(); - - CollapseProvider * const colcb = (CollapseProvider *) - m_shaders-> - m_callbacks[ES_COLLAPSE]; - ScreenQuad sq(m_video_driver); - sq.setMaterialType(m_shaders->getShader(ES_COLLAPSE)); - sq.setTexture(m_rtts->getRTT(RTT_COLLAPSE)); - sq.getMaterial().setFlag(EMF_BILINEAR_FILTER, false); - - const TypeRTT oldh = tick ? RTT_COLLAPSEH : RTT_COLLAPSEH2; - const TypeRTT oldv = tick ? RTT_COLLAPSEV : RTT_COLLAPSEV2; - const TypeRTT curh = tick ? RTT_COLLAPSEH2 : RTT_COLLAPSEH; - const TypeRTT curv = tick ? RTT_COLLAPSEV2 : RTT_COLLAPSEV; - - colcb->setResolution(1, m_rtts->getRTT(RTT_WARPV)->getSize().Height); - sq.setTexture(m_rtts->getRTT(oldh), 1); - sq.render(m_rtts->getRTT(RTT_WARPH)); - - colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height, 1); - sq.setTexture(m_rtts->getRTT(oldv), 1); - sq.render(m_rtts->getRTT(RTT_WARPV)); - - sq.setTexture(0, 1); - ((GaussianBlurProvider *) m_shaders->m_callbacks[ES_GAUSSIAN3H])->setResolution( - m_rtts->getRTT(RTT_WARPV)->getSize().Height, - m_rtts->getRTT(RTT_WARPV)->getSize().Height); - - sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H)); - sq.setTexture(m_rtts->getRTT(RTT_WARPH)); - sq.render(m_rtts->getRTT(curh)); - - sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6V)); - sq.setTexture(m_rtts->getRTT(RTT_WARPV)); - sq.render(m_rtts->getRTT(curv));*/ - - // Convert importance maps to warp maps - // - // It should be noted that while they do repeated work - // calculating the min, max, and total, it's several hundred us - // faster to do that than to do it once in a separate shader - // (shader switch overhead, measured). - /*colcb->setResolution(m_rtts->getRTT(RTT_WARPV)->getSize().Height, - m_rtts->getRTT(RTT_WARPV)->getSize().Height); - - sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPH)); - sq.setTexture(m_rtts->getRTT(curh)); - sq.render(m_rtts->getRTT(RTT_WARPH)); - - sq.setMaterialType(m_shaders->getShader(ES_SHADOW_WARPV)); - sq.setTexture(m_rtts->getRTT(curv)); - sq.render(m_rtts->getRTT(RTT_WARPV));*/ - - // Actual shadow map - - -/* overridemat.Material.MaterialType = m_shaders->getShader(ES_SHADOWPASS); - overridemat.EnableFlags = video::EMF_MATERIAL_TYPE | video::EMF_TEXTURE1 | - video::EMF_TEXTURE2; - overridemat.EnablePasses = scene::ESNRP_SOLID; - overridemat.Material.setTexture(1, m_rtts->getRTT(RTT_WARPH)); - overridemat.Material.setTexture(2, m_rtts->getRTT(RTT_WARPV)); - overridemat.Material.TextureLayer[1].TextureWrapU = - overridemat.Material.TextureLayer[1].TextureWrapV = - overridemat.Material.TextureLayer[2].TextureWrapU = - overridemat.Material.TextureLayer[2].TextureWrapV = video::ETC_CLAMP_TO_EDGE; - overridemat.Material.TextureLayer[1].BilinearFilter = - overridemat.Material.TextureLayer[2].BilinearFilter = true; - overridemat.Material.TextureLayer[1].TrilinearFilter = - overridemat.Material.TextureLayer[2].TrilinearFilter = false; - overridemat.Material.TextureLayer[1].AnisotropicFilter = - overridemat.Material.TextureLayer[2].AnisotropicFilter = 0; - overridemat.Material.Wireframe = 1; - overridemat.Enabled = true;*/ - - - -// overridemat.EnablePasses = 0; -// overridemat.Enabled = false; } // ---------------------------------------------------------------------------- -void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, - std::vector& glows, - const core::aabbox3df& cambox, - int cam) +void IrrDriver::renderGlow(std::vector& glows) { m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_TMP1_WITH_DS)); @@ -815,10 +669,11 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, const GlowData &dat = glows[i]; scene::ISceneNode * const cur = dat.node; + //TODO : implement culling on gpu // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; +// const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); +// if (!nodebox.intersectsWithBox(cambox)) +// continue; cb->setColor(dat.r, dat.g, dat.b); cur->render(); @@ -880,10 +735,7 @@ static void renderPointLights(unsigned count) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); } -void IrrDriver::renderLights(const core::aabbox3df& cambox, - scene::ICameraSceneNode * const camnode, - video::SOverrideMaterial &overridemat, - int cam, float dt) +void IrrDriver::renderLights(float dt) { for (unsigned i = 0; i < sun_ortho_matrix.size(); i++) @@ -1444,11 +1296,10 @@ void IrrDriver::generateSkyboxCubemap() } -void IrrDriver::renderSkybox() +void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera) { if (SkyboxTextures.empty()) return; - scene::ICameraSceneNode *camera = m_scene_manager->getActiveCamera(); if (!SkyboxCubeMap) generateSkyboxCubemap(); glBindVertexArray(MeshShader::SkyboxShader::cubevao); @@ -1481,8 +1332,7 @@ void IrrDriver::renderSkybox() // ---------------------------------------------------------------------------- -void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat, - int cam) +void IrrDriver::renderDisplacement() { glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4)); glClear(GL_COLOR_BUFFER_BIT); @@ -1505,9 +1355,6 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat, for (int i = 0; i < displacingcount; i++) { - m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID); - m_displacing[i]->render(); - m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT); m_displacing[i]->render(); } From 1070fd7395aac077c3b28e3abcaa87b9578ba593 Mon Sep 17 00:00:00 2001 From: Stephen Just Date: Wed, 7 May 2014 23:19:39 -0600 Subject: [PATCH 10/10] Fix segfault on Linux/Mesa For some reason, glGetString(GL_EXTENSIONS) is failing. This will need more investigation --- src/graphics/irr_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 1d61bfe14..911a591ec 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -444,7 +444,7 @@ void IrrDriver::initDevice() // Parse extensions hasVSLayer = false; const GLubyte *extensions = glGetString(GL_EXTENSIONS); - if (strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL) + if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL) hasVSLayer = true;