Allow GL3 to have hardware skinning
This commit is contained in:
parent
b7e047b4c1
commit
76e070b709
@ -1,81 +1,86 @@
|
|||||||
// SuperTuxKart - a fun racing game with go-kart
|
#ifdef GL_ES
|
||||||
// Copyright (C) 2013 the SuperTuxKart team
|
uniform mat4 ModelMatrix;
|
||||||
//
|
uniform mat4 InverseModelMatrix;
|
||||||
// This program is free software; you can redistribute it and/or
|
uniform vec2 texture_trans;
|
||||||
// modify it under the terms of the GNU General Public License
|
#else
|
||||||
// as published by the Free Software Foundation; either version 3
|
uniform mat4 ModelMatrix =
|
||||||
// of the License, or (at your option) any later version.
|
mat4(1., 0., 0., 0.,
|
||||||
//
|
0., 1., 0., 0.,
|
||||||
// This program is distributed in the hope that it will be useful,
|
0., 0., 1., 0.,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
0., 0., 0., 1.);
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
uniform mat4 InverseModelMatrix =
|
||||||
// GNU General Public License for more details.
|
mat4(1., 0., 0., 0.,
|
||||||
//
|
0., 1., 0., 0.,
|
||||||
// You should have received a copy of the GNU General Public License
|
0., 0., 1., 0.,
|
||||||
// along with this program; if not, write to the Free Software
|
0., 0., 0., 1.);
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
// skinning.vert
|
uniform vec2 texture_trans = vec2(0., 0.);
|
||||||
#version 330 compatibility
|
#endif
|
||||||
#define MAX_JOINT_NUM 36
|
uniform int skinning_offset;
|
||||||
#define MAX_LIGHT_NUM 8
|
|
||||||
|
|
||||||
uniform mat4 JointTransform[MAX_JOINT_NUM];
|
layout(location = 0) in vec3 Position;
|
||||||
|
layout(location = 1) in vec3 Normal;
|
||||||
|
layout(location = 2) in vec4 Color;
|
||||||
|
layout(location = 3) in vec4 Data1;
|
||||||
|
layout(location = 4) in vec4 Data2;
|
||||||
|
layout(location = 5) in ivec4 Joint;
|
||||||
|
layout(location = 6) in vec4 Weight;
|
||||||
|
|
||||||
void main()
|
out vec3 nor;
|
||||||
|
out vec3 tangent;
|
||||||
|
out vec3 bitangent;
|
||||||
|
out vec2 uv;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
#stk_include "utils/getworldmatrix.vert"
|
||||||
|
|
||||||
|
void main(void)
|
||||||
{
|
{
|
||||||
int index;
|
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
|
||||||
vec4 ecPos;
|
vec4 idle_position = vec4(Position, 1.);
|
||||||
vec3 normal;
|
vec4 idle_normal = vec4(Normal, 0.);
|
||||||
vec3 light_dir;
|
vec4 skinned_position = vec4(0.);
|
||||||
float n_dot_l;
|
vec4 skinned_normal = vec4(0.);
|
||||||
float dist;
|
|
||||||
|
|
||||||
mat4 ModelTransform = gl_ModelViewProjectionMatrix;
|
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
|
||||||
|
vec4 single_bone_influenced_position;
|
||||||
|
vec4 single_bone_influenced_normal;
|
||||||
|
|
||||||
index = int(gl_Color.r * 255.99);
|
// First bone:
|
||||||
mat4 vertTran = JointTransform[index - 1];
|
single_bone_influenced_position = joint_matrices[clamp(Joint[0] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||||
|
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||||
|
single_bone_influenced_normal = joint_matrices[clamp(Joint[0] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||||
|
skinned_position += Weight[0] * single_bone_influenced_position;
|
||||||
|
skinned_normal += Weight[0] * single_bone_influenced_normal;
|
||||||
|
|
||||||
index = int(gl_Color.g * 255.99);
|
// Second bone:
|
||||||
if(index > 0)
|
single_bone_influenced_position = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||||
vertTran += JointTransform[index - 1];
|
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||||
|
single_bone_influenced_normal = joint_matrices[clamp(Joint[1] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||||
|
skinned_position += Weight[1] * single_bone_influenced_position;
|
||||||
|
skinned_normal += Weight[1] * single_bone_influenced_normal;
|
||||||
|
|
||||||
index = int(gl_Color.b * 255.99);
|
// Third bone:
|
||||||
if(index > 0)
|
single_bone_influenced_position = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||||
vertTran += JointTransform[index - 1];
|
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||||
|
single_bone_influenced_normal = joint_matrices[clamp(Joint[2] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||||
|
skinned_position += Weight[2] * single_bone_influenced_position;
|
||||||
|
skinned_normal += Weight[2] * single_bone_influenced_normal;
|
||||||
|
|
||||||
index = int(gl_Color.a * 255.99);
|
// Fourth bone:
|
||||||
if(index > 0)
|
single_bone_influenced_position = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||||
vertTran += JointTransform[index - 1];
|
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||||
|
single_bone_influenced_normal = joint_matrices[clamp(Joint[3] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||||
|
skinned_position += Weight[3] * single_bone_influenced_position;
|
||||||
|
skinned_normal += Weight[3] * single_bone_influenced_normal;
|
||||||
|
|
||||||
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
|
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * skinned_position;
|
||||||
|
// Keep orthogonality
|
||||||
|
nor = (TransposeInverseModelView * skinned_normal).xyz;
|
||||||
|
// Keep direction
|
||||||
|
tangent = (ViewMatrix * ModelMatrix * vec4(Data1.z, Data1.w, Data2.x, 0.)).xyz;
|
||||||
|
bitangent = (ViewMatrix * ModelMatrix * vec4(Data2.y, Data2.z, Data2.w, 0.)).xyz;
|
||||||
|
|
||||||
normal = (vertTran * vec4(gl_Normal, 0.0)).xyz;
|
uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
|
||||||
normal = normalize(gl_NormalMatrix * normal);
|
color = Color.zyxw;
|
||||||
|
|
||||||
gl_FrontColor = vec4(0,0,0,0);
|
|
||||||
for(int i = 0;i < MAX_LIGHT_NUM;i++)
|
|
||||||
{
|
|
||||||
light_dir = vec3(gl_LightSource[i].position-ecPos);
|
|
||||||
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
|
|
||||||
dist = length(light_dir);
|
|
||||||
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
|
|
||||||
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
|
|
||||||
}
|
|
||||||
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
|
|
||||||
|
|
||||||
|
|
||||||
ModelTransform *= vertTran;
|
|
||||||
|
|
||||||
gl_Position = ModelTransform * gl_Vertex;
|
|
||||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
|
||||||
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Reflections.
|
|
||||||
vec3 r = reflect( ecPos.xyz , normal );
|
|
||||||
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
|
|
||||||
gl_TexCoord[1].s = r.x/m + 0.5;
|
|
||||||
gl_TexCoord[1].t = r.y/m + 0.5;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ void DrawCalls::clearLists()
|
|||||||
ListDisplacement::getInstance()->clear();
|
ListDisplacement::getInstance()->clear();
|
||||||
|
|
||||||
ListMatDefault::getInstance()->clear();
|
ListMatDefault::getInstance()->clear();
|
||||||
|
ListSkinnedSolid::getInstance()->clear();
|
||||||
ListMatAlphaRef::getInstance()->clear();
|
ListMatAlphaRef::getInstance()->clear();
|
||||||
ListMatSphereMap::getInstance()->clear();
|
ListMatSphereMap::getInstance()->clear();
|
||||||
ListMatDetails::getInstance()->clear();
|
ListMatDetails::getInstance()->clear();
|
||||||
@ -305,6 +306,12 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
|||||||
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||||
core::vector2df(0.0f, 0.0f)));
|
core::vector2df(0.0f, 0.0f)));
|
||||||
break;
|
break;
|
||||||
|
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
|
||||||
|
ListSkinnedSolid::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||||
|
(mesh->m_render_info && mesh->m_material ?
|
||||||
|
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||||
|
core::vector2df(0.0f, 0.0f)), skinning_offset);
|
||||||
|
break;
|
||||||
case Material::SHADERTYPE_ALPHA_TEST:
|
case Material::SHADERTYPE_ALPHA_TEST:
|
||||||
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||||
(mesh->m_render_info && mesh->m_material ?
|
(mesh->m_render_info && mesh->m_material ?
|
||||||
|
@ -176,6 +176,7 @@ void drawRSM(const core::matrix4 & rsm_matrix)
|
|||||||
void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
|
||||||
{
|
{
|
||||||
renderMeshes1stPass<DefaultMaterial, 2, 1>();
|
renderMeshes1stPass<DefaultMaterial, 2, 1>();
|
||||||
|
renderMeshes1stPass<SkinnedSolid, 5, 2, 1>();
|
||||||
renderMeshes1stPass<SplattingMat, 2, 1>();
|
renderMeshes1stPass<SplattingMat, 2, 1>();
|
||||||
renderMeshes1stPass<UnlitMat, 3, 2, 1>();
|
renderMeshes1stPass<UnlitMat, 3, 2, 1>();
|
||||||
renderMeshes1stPass<AlphaRef, 3, 2, 1>();
|
renderMeshes1stPass<AlphaRef, 3, 2, 1>();
|
||||||
@ -191,6 +192,7 @@ void GL3DrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
|
|||||||
const std::vector<GLuint>& prefilled_tex) const
|
const std::vector<GLuint>& prefilled_tex) const
|
||||||
{
|
{
|
||||||
renderMeshes2ndPass<DefaultMaterial, 4, 3, 1> (handles, prefilled_tex);
|
renderMeshes2ndPass<DefaultMaterial, 4, 3, 1> (handles, prefilled_tex);
|
||||||
|
renderMeshes2ndPass<SkinnedSolid, 5, 4, 3, 1> (handles, prefilled_tex);
|
||||||
renderMeshes2ndPass<AlphaRef, 4, 3, 1> (handles, prefilled_tex);
|
renderMeshes2ndPass<AlphaRef, 4, 3, 1> (handles, prefilled_tex);
|
||||||
renderMeshes2ndPass<UnlitMat, 3, 1 > (handles, prefilled_tex);
|
renderMeshes2ndPass<UnlitMat, 3, 1 > (handles, prefilled_tex);
|
||||||
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
renderMeshes2ndPass<SplattingMat, 1 > (handles, prefilled_tex);
|
||||||
|
@ -655,8 +655,8 @@ struct SkinnedSolid
|
|||||||
typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader;
|
typedef InstancedSkinnedMeshPass2Shader InstancedSecondPassShader;
|
||||||
//typedef InstancedShadowShader InstancedShadowPassShader;
|
//typedef InstancedShadowShader InstancedShadowPassShader;
|
||||||
//typedef CInstancedRSMShader InstancedRSMShader;
|
//typedef CInstancedRSMShader InstancedRSMShader;
|
||||||
//typedef Shaders::ObjectPass1Shader FirstPassShader;
|
typedef Shaders::SkinnedMeshPass1Shader FirstPassShader;
|
||||||
//typedef Shaders::ObjectPass2Shader SecondPassShader;
|
typedef Shaders::SkinnedMeshPass2Shader SecondPassShader;
|
||||||
//typedef ShadowShader ShadowPassShader;
|
//typedef ShadowShader ShadowPassShader;
|
||||||
//typedef CRSMShader RSMShader;
|
//typedef CRSMShader RSMShader;
|
||||||
typedef ListSkinnedSolid List;
|
typedef ListSkinnedSolid List;
|
||||||
@ -668,7 +668,7 @@ struct SkinnedSolid
|
|||||||
static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures;
|
static const STK::Tuple<size_t, size_t, size_t> SecondPassTextures;
|
||||||
static const STK::Tuple<> ShadowTextures;
|
static const STK::Tuple<> ShadowTextures;
|
||||||
static const STK::Tuple<size_t> RSMTextures;
|
static const STK::Tuple<size_t> RSMTextures;
|
||||||
}; // struct DefaultMaterial
|
}; // struct SkinnedSolid
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
struct DefaultMaterial
|
struct DefaultMaterial
|
||||||
|
@ -359,6 +359,29 @@ Shaders::ObjectPass2Shader::ObjectPass2Shader()
|
|||||||
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // ObjectPass2Shader
|
} // ObjectPass2Shader
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
Shaders::SkinnedMeshPass1Shader::SkinnedMeshPass1Shader()
|
||||||
|
{
|
||||||
|
loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
|
GL_FRAGMENT_SHADER, "object_pass1.frag");
|
||||||
|
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
|
||||||
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
|
} // SkinnedMeshPass1Shader
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
Shaders::SkinnedMeshPass2Shader::SkinnedMeshPass2Shader()
|
||||||
|
{
|
||||||
|
loadProgram(OBJECT, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
|
GL_FRAGMENT_SHADER, "object_pass2.frag");
|
||||||
|
assignUniforms("ModelMatrix", "texture_trans", "color_change", "skinning_offset");
|
||||||
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
|
1, "SpecularMap", ST_NEAREST_FILTERED,
|
||||||
|
2, "SSAO", ST_BILINEAR_FILTERED,
|
||||||
|
3, "Albedo", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
|
4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
|
5, "colorization_mask", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
|
} // SkinnedMeshPass2Shader
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
Shaders::TransparentShader::TransparentShader()
|
Shaders::TransparentShader::TransparentShader()
|
||||||
{
|
{
|
||||||
|
@ -153,6 +153,24 @@ public:
|
|||||||
}; // ObjectPass2Shader
|
}; // ObjectPass2Shader
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
class SkinnedMeshPass1Shader : public TextureShader<SkinnedMeshPass1Shader, 1,
|
||||||
|
core::matrix4, core::matrix4,
|
||||||
|
int>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SkinnedMeshPass1Shader();
|
||||||
|
}; // SkinnedMeshPass1Shader
|
||||||
|
|
||||||
|
// ========================================================================
|
||||||
|
class SkinnedMeshPass2Shader : public TextureShader < SkinnedMeshPass2Shader, 6,
|
||||||
|
core::matrix4, core::vector2df,
|
||||||
|
core::vector2df, int >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SkinnedMeshPass2Shader();
|
||||||
|
}; // SkinnedMeshPass2Shader
|
||||||
|
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
|
||||||
}; // class Shaders
|
}; // class Shaders
|
||||||
|
@ -119,7 +119,7 @@ class ListMatDefault : public MeshList<ListMatDefault, GLMesh *, core::matrix4,
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
class ListSkinnedSolid : public MeshList<ListSkinnedSolid, GLMesh *, core::matrix4,
|
class ListSkinnedSolid : public MeshList<ListSkinnedSolid, GLMesh *, core::matrix4,
|
||||||
core::matrix4, core::vector2df,
|
core::matrix4, core::vector2df,
|
||||||
core::vector2df>
|
core::vector2df, int>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user