From 8008ec851eb448274b03d06e00bee2c537448b42 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 23 Dec 2016 01:31:13 +0800 Subject: [PATCH] Allow to use hardware skinning with opengl 3.1 Now we only need UBO to store the joint matrices to support it --- data/shaders/instanced_skinning.vert | 16 +++++++++ data/shaders/instanced_skinning_shadow.vert | 11 ++++++ data/shaders/skinning.vert | 10 ++++++ data/shaders/skinning_shadow.vert | 7 ++++ src/graphics/central_settings.cpp | 2 +- src/graphics/materials.hpp | 40 ++++++++++----------- src/graphics/shader.cpp | 15 ++++++++ src/graphics/shader.hpp | 1 + src/graphics/shaders.cpp | 2 +- 9 files changed, 82 insertions(+), 22 deletions(-) diff --git a/data/shaders/instanced_skinning.vert b/data/shaders/instanced_skinning.vert index 49a029361..c8e192143 100644 --- a/data/shaders/instanced_skinning.vert +++ b/data/shaders/instanced_skinning.vert @@ -1,3 +1,4 @@ +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec4 Color; @@ -17,6 +18,21 @@ layout(location = 13) in sampler2D ThirdHandle; layout(location = 14) in sampler2D FourthHandle; #endif layout(location = 15) in int skinning_offset; +#else +in vec3 Position; +in vec3 Normal; +in vec4 Color; +in vec4 Data1; +in vec4 Data2; +in ivec4 Joint; +in vec4 Weight; + +in vec3 Origin; +in vec3 Orientation; +in vec3 Scale; +in vec4 misc_data; +in int skinning_offset; +#endif out vec3 nor; out vec3 tangent; diff --git a/data/shaders/instanced_skinning_shadow.vert b/data/shaders/instanced_skinning_shadow.vert index 2d2542e1e..21e4a5294 100644 --- a/data/shaders/instanced_skinning_shadow.vert +++ b/data/shaders/instanced_skinning_shadow.vert @@ -1,5 +1,6 @@ uniform int layer; +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 3) in vec4 Data1; layout(location = 5) in ivec4 Joint; @@ -11,6 +12,16 @@ layout(location = 9) in vec3 Scale; layout(location = 11) in uvec2 Handle; #endif layout(location = 15) in int skinning_offset; +#else +in vec3 Position; +in vec4 Data1; +in ivec4 Joint; +in vec4 Weight; +in vec3 Origin; +in vec3 Orientation; +in vec3 Scale; +in int skinning_offset; +#endif #ifdef VSLayer out vec2 uv; diff --git a/data/shaders/skinning.vert b/data/shaders/skinning.vert index e64ec294d..2652fc10e 100644 --- a/data/shaders/skinning.vert +++ b/data/shaders/skinning.vert @@ -18,6 +18,7 @@ uniform vec2 texture_trans = vec2(0., 0.); #endif uniform int skinning_offset; +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec4 Color; @@ -25,6 +26,15 @@ layout(location = 3) in vec4 Data1; layout(location = 4) in vec4 Data2; layout(location = 5) in ivec4 Joint; layout(location = 6) in vec4 Weight; +#else +in vec3 Position; +in vec3 Normal; +in vec4 Color; +in vec4 Data1; +in vec4 Data2; +in ivec4 Joint; +in vec4 Weight; +#endif out vec3 nor; out vec3 tangent; diff --git a/data/shaders/skinning_shadow.vert b/data/shaders/skinning_shadow.vert index 6fc5d35c8..6e8d8fb3b 100644 --- a/data/shaders/skinning_shadow.vert +++ b/data/shaders/skinning_shadow.vert @@ -2,10 +2,17 @@ uniform mat4 ModelMatrix; uniform int skinning_offset; uniform int layer; +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 3) in vec4 Data1; layout(location = 5) in ivec4 Joint; layout(location = 6) in vec4 Weight; +#else +in vec3 Position; +in vec4 Data1; +in ivec4 Joint; +in vec4 Weight; +#endif #ifdef VSLayer out vec2 uv; diff --git a/src/graphics/central_settings.cpp b/src/graphics/central_settings.cpp index cea030f3f..56a267260 100644 --- a/src/graphics/central_settings.cpp +++ b/src/graphics/central_settings.cpp @@ -446,6 +446,6 @@ bool CentralVideoSettings::isDefferedEnabled() const bool CentralVideoSettings::supportsHardwareSkinning() const { - return isARBUniformBufferObjectUsable() && isARBExplicitAttribLocationUsable() && getGLSLVersion() >= 330; + return isARBUniformBufferObjectUsable(); } #endif // !SERVER_ONLY diff --git a/src/graphics/materials.hpp b/src/graphics/materials.hpp index aa5805af4..7845a1654 100644 --- a/src/graphics/materials.hpp +++ b/src/graphics/materials.hpp @@ -626,7 +626,7 @@ public: SkinnedPass1Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "object_pass1.frag"); assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset"); assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED); @@ -640,7 +640,7 @@ public: InstancedSkinnedPass1Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_object_pass1.frag"); assignUniforms(); assignSamplerNames(0, "glosstex", ST_TRILINEAR_ANISOTROPIC_FILTERED); @@ -656,7 +656,7 @@ public: SkinnedPass2Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "object_pass2.frag"); assignUniforms("ModelMatrix", "texture_trans", "color_change", "skinning_offset"); @@ -676,7 +676,7 @@ public: InstancedSkinnedPass2Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_object_pass2.frag"); assignUniforms(); assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, @@ -698,7 +698,7 @@ public: SkinnedRefPass1Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "objectref_pass1.frag"); assignUniforms("ModelMatrix", "InverseModelMatrix", "texture_trans", "skinning_offset"); @@ -714,7 +714,7 @@ public: InstancedSkinnedRefPass1Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_objectref_pass1.frag"); assignUniforms(); assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED, @@ -732,7 +732,7 @@ public: SkinnedRefPass2Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "objectref_pass2.frag"); assignUniforms("ModelMatrix", "texture_trans", "color_change", "skinning_offset"); @@ -752,7 +752,7 @@ public: InstancedSkinnedRefPass2Shader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_objectref_pass2.frag"); assignUniforms(); assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, @@ -773,7 +773,7 @@ public: SkinnedUnlitShader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "object_unlit.frag"); assignUniforms("ModelMatrix", "texture_trans", "skinning_offset"); assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, @@ -790,7 +790,7 @@ public: InstancedSkinnedUnlitShader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_object_unlit.frag"); assignUniforms(); assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED, @@ -809,7 +809,7 @@ public: SkinnedNormalMapShader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "normalmap.frag"); assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset"); assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, @@ -824,7 +824,7 @@ public: InstancedSkinnedNormalMapShader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert", GL_FRAGMENT_SHADER, "instanced_normalmap.frag"); assignUniforms(); assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED, @@ -845,12 +845,12 @@ public: return; if (CVS->isAMDVertexShaderLayerUsable()) { - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning_shadow.vert", GL_FRAGMENT_SHADER, "shadow.frag"); } else { - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning_shadow.vert", GL_GEOMETRY_SHADER, "shadow.geom", GL_FRAGMENT_SHADER, "shadow.frag"); } @@ -871,12 +871,12 @@ public: return; if (CVS->isAMDVertexShaderLayerUsable()) { - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", GL_FRAGMENT_SHADER, "shadow.frag"); } else { - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", GL_GEOMETRY_SHADER, "instanced_shadow.geom", GL_FRAGMENT_SHADER, "shadow.frag"); } @@ -898,12 +898,12 @@ public: return; if (CVS->isAMDVertexShaderLayerUsable()) { - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning_shadow.vert", GL_FRAGMENT_SHADER, "shadowref.frag"); } else { - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning_shadow.vert", GL_GEOMETRY_SHADER, "shadow.geom", GL_FRAGMENT_SHADER, "shadowref.frag"); } @@ -926,12 +926,12 @@ public: return; if (CVS->isAMDVertexShaderLayerUsable()) { - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", GL_FRAGMENT_SHADER, "instanced_shadowref.frag"); } else { - loadProgram(OBJECT, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning_shadow.vert", GL_GEOMETRY_SHADER, "instanced_shadow.geom", GL_FRAGMENT_SHADER, "instanced_shadowref.frag"); } diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 2383cab50..ec3ac239e 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -142,6 +142,7 @@ void ShaderBase::setAttribute(AttributeType type) glBindAttribLocation(m_program, 7, "Origin"); glBindAttribLocation(m_program, 8, "Orientation"); glBindAttribLocation(m_program, 9, "Scale"); + glBindAttribLocation(m_program, 10, "misc_data"); break; case PARTICLES_SIM: glBindAttribLocation(m_program, 0, "particle_position"); @@ -160,6 +161,20 @@ void ShaderBase::setAttribute(AttributeType type) glBindAttribLocation(m_program, 5, "rotationvec"); glBindAttribLocation(m_program, 6, "anglespeed"); break; + case SKINNED_MESH: + glBindAttribLocation(m_program, 0, "Position"); + glBindAttribLocation(m_program, 1, "Normal"); + glBindAttribLocation(m_program, 2, "Color"); + glBindAttribLocation(m_program, 3, "Data1"); + glBindAttribLocation(m_program, 4, "Data2"); + glBindAttribLocation(m_program, 5, "Joint"); + glBindAttribLocation(m_program, 6, "Weight"); + glBindAttribLocation(m_program, 7, "Origin"); + glBindAttribLocation(m_program, 8, "Orientation"); + glBindAttribLocation(m_program, 9, "Scale"); + glBindAttribLocation(m_program, 10, "misc_data"); + glBindAttribLocation(m_program, 15, "skinning_offset"); + break; } } // setAttribute diff --git a/src/graphics/shader.hpp b/src/graphics/shader.hpp index 46ab6fcf6..7df252576 100644 --- a/src/graphics/shader.hpp +++ b/src/graphics/shader.hpp @@ -50,6 +50,7 @@ protected: OBJECT, PARTICLES_SIM, PARTICLES_RENDERING, + SKINNED_MESH, }; // AttributeType /** OpenGL's program id. */ diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d00b06dbc..5c623d329 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -302,7 +302,7 @@ Shaders::ObjectPass2Shader::ObjectPass2Shader() Shaders::SkinnedTransparentShader::SkinnedTransparentShader() { if (!CVS->supportsHardwareSkinning()) return; - loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert", + loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert", GL_FRAGMENT_SHADER, "transparent.frag"); assignUniforms("ModelMatrix", "texture_trans", "skinning_offset", "custom_alpha"); assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);