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 9a8139e80..f85e9a024 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -237,6 +237,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/render.cpp b/src/graphics/render.cpp index 8f9fd8384..64b96957c 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -1197,7 +1197,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]; @@ -1378,9 +1378,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]; @@ -1410,10 +1410,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) { 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");