Use texture buffer (texture2d in gles) for skinning
This commit is contained in:
parent
1a9cf6a46f
commit
0d96906d54
@ -22,6 +22,7 @@ void main(void)
|
|||||||
#ifdef Use_Bindless_Texture
|
#ifdef Use_Bindless_Texture
|
||||||
vec4 col = texture(handle, uv);
|
vec4 col = texture(handle, uv);
|
||||||
float specmap = texture(secondhandle, uv).g;
|
float specmap = texture(secondhandle, uv).g;
|
||||||
|
float emitmap = texture(secondhandle, uv).b;
|
||||||
float mask = texture(thirdhandle, uv).a;
|
float mask = texture(thirdhandle, uv).a;
|
||||||
#ifdef SRGBBindlessFix
|
#ifdef SRGBBindlessFix
|
||||||
col.xyz = pow(col.xyz, vec3(2.2));
|
col.xyz = pow(col.xyz, vec3(2.2));
|
||||||
|
@ -49,6 +49,8 @@ flat out sampler2D fourthhandle;
|
|||||||
|
|
||||||
#stk_include "utils/getworldmatrix.vert"
|
#stk_include "utils/getworldmatrix.vert"
|
||||||
|
|
||||||
|
uniform samplerBuffer skinning_tex;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||||
@ -61,18 +63,31 @@ void main(void)
|
|||||||
vec4 skinned_normal = vec4(0.);
|
vec4 skinned_normal = vec4(0.);
|
||||||
vec4 skinned_tangent = vec4(0.);
|
vec4 skinned_tangent = vec4(0.);
|
||||||
vec4 skinned_bitangent = vec4(0.);
|
vec4 skinned_bitangent = vec4(0.);
|
||||||
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
|
if (Weight[0] < 0.01)
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
{
|
||||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
skinned_position = idle_position;
|
||||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
skinned_normal = idle_normal;
|
||||||
vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
skinned_tangent = idle_tangent;
|
||||||
vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent;
|
skinned_bitangent = idle_bitangent;
|
||||||
vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent;
|
}
|
||||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
else
|
||||||
skinned_normal += Weight[i] * single_bone_influenced_normal;
|
{
|
||||||
skinned_tangent += Weight[i] * single_bone_influenced_tangent;
|
for (int i = 0; i < 4; i++)
|
||||||
skinned_bitangent += Weight[i] * single_bone_influenced_bitangent;
|
{
|
||||||
|
if (Weight[i] < 0.01)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mat4 joint_matrix = mat4(
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
|
||||||
|
skinned_position += Weight[i] * joint_matrix * idle_position;
|
||||||
|
skinned_normal += Weight[i] * joint_matrix * idle_normal;
|
||||||
|
skinned_tangent += Weight[i] * joint_matrix * idle_tangent;
|
||||||
|
skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
||||||
|
@ -38,16 +38,32 @@ flat out uvec2 hdle;
|
|||||||
|
|
||||||
#stk_include "utils/getworldmatrix.vert"
|
#stk_include "utils/getworldmatrix.vert"
|
||||||
|
|
||||||
|
uniform samplerBuffer skinning_tex;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||||
vec4 idle_position = vec4(Position, 1.);
|
vec4 idle_position = vec4(Position, 1.);
|
||||||
vec4 skinned_position = vec4(0.);
|
vec4 skinned_position = vec4(0.);
|
||||||
for (int i = 0; i < 4; i++)
|
if (Weight[0] < 0.01)
|
||||||
{
|
{
|
||||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
skinned_position = idle_position;
|
||||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
}
|
||||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (Weight[i] < 0.01)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mat4 joint_matrix = mat4(
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
|
||||||
|
skinned_position += Weight[i] * joint_matrix * idle_position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VSLayer
|
#ifdef VSLayer
|
||||||
|
@ -17,6 +17,11 @@ uniform mat4 InverseModelMatrix =
|
|||||||
uniform vec2 texture_trans = vec2(0., 0.);
|
uniform vec2 texture_trans = vec2(0., 0.);
|
||||||
#endif
|
#endif
|
||||||
uniform int skinning_offset;
|
uniform int skinning_offset;
|
||||||
|
#ifdef GL_ES
|
||||||
|
uniform sampler2D skinning_tex;
|
||||||
|
#else
|
||||||
|
uniform samplerBuffer skinning_tex;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Explicit_Attrib_Location_Usable
|
#ifdef Explicit_Attrib_Location_Usable
|
||||||
layout(location = 0) in vec3 Position;
|
layout(location = 0) in vec3 Position;
|
||||||
@ -55,18 +60,39 @@ void main(void)
|
|||||||
vec4 skinned_normal = vec4(0.);
|
vec4 skinned_normal = vec4(0.);
|
||||||
vec4 skinned_tangent = vec4(0.);
|
vec4 skinned_tangent = vec4(0.);
|
||||||
vec4 skinned_bitangent = vec4(0.);
|
vec4 skinned_bitangent = vec4(0.);
|
||||||
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
|
if (Weight[0] < 0.01)
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
{
|
||||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
skinned_position = idle_position;
|
||||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
skinned_normal = idle_normal;
|
||||||
vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
skinned_tangent = idle_tangent;
|
||||||
vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent;
|
skinned_bitangent = idle_bitangent;
|
||||||
vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent;
|
}
|
||||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
else
|
||||||
skinned_normal += Weight[i] * single_bone_influenced_normal;
|
{
|
||||||
skinned_tangent += Weight[i] * single_bone_influenced_tangent;
|
for (int i = 0; i < 4; i++)
|
||||||
skinned_bitangent += Weight[i] * single_bone_influenced_bitangent;
|
{
|
||||||
|
if (Weight[i] < 0.01)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef GL_ES
|
||||||
|
mat4 joint_matrix = mat4(
|
||||||
|
texelFetch(skinning_tex, ivec2(0, skinning_offset + Joint[i]), 0),
|
||||||
|
texelFetch(skinning_tex, ivec2(1, skinning_offset + Joint[i]), 0),
|
||||||
|
texelFetch(skinning_tex, ivec2(2, skinning_offset + Joint[i]), 0),
|
||||||
|
texelFetch(skinning_tex, ivec2(3, skinning_offset + Joint[i]), 0));
|
||||||
|
#else
|
||||||
|
mat4 joint_matrix = mat4(
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
|
||||||
|
#endif
|
||||||
|
skinned_position += Weight[i] * joint_matrix * idle_position;
|
||||||
|
skinned_normal += Weight[i] * joint_matrix * idle_normal;
|
||||||
|
skinned_tangent += Weight[i] * joint_matrix * idle_tangent;
|
||||||
|
skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
uniform mat4 ModelMatrix;
|
uniform mat4 ModelMatrix;
|
||||||
uniform int skinning_offset;
|
uniform int skinning_offset;
|
||||||
uniform int layer;
|
uniform int layer;
|
||||||
|
uniform samplerBuffer skinning_tex;
|
||||||
|
|
||||||
#ifdef Explicit_Attrib_Location_Usable
|
#ifdef Explicit_Attrib_Location_Usable
|
||||||
layout(location = 0) in vec3 Position;
|
layout(location = 0) in vec3 Position;
|
||||||
@ -25,11 +26,25 @@ void main(void)
|
|||||||
{
|
{
|
||||||
vec4 idle_position = vec4(Position, 1.);
|
vec4 idle_position = vec4(Position, 1.);
|
||||||
vec4 skinned_position = vec4(0.);
|
vec4 skinned_position = vec4(0.);
|
||||||
for (int i = 0; i < 4; i++)
|
if (Weight[0] < 0.01)
|
||||||
{
|
{
|
||||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
skinned_position = idle_position;
|
||||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
}
|
||||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (Weight[i] < 0.01)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mat4 joint_matrix = mat4(
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
|
||||||
|
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
|
||||||
|
skinned_position += Weight[i] * joint_matrix * idle_position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VSLayer
|
#ifdef VSLayer
|
||||||
|
@ -255,14 +255,8 @@ struct S3DVertexTangents : public S3DVertex
|
|||||||
|
|
||||||
struct S3DVertexSkinnedMesh : public S3DVertexTangents
|
struct S3DVertexSkinnedMesh : public S3DVertexTangents
|
||||||
{
|
{
|
||||||
s32 m_joint_idx1;
|
s16 m_joint_idx[4];
|
||||||
s32 m_joint_idx2;
|
s16 m_weight[4];
|
||||||
s32 m_joint_idx3;
|
|
||||||
s32 m_joint_idx4;
|
|
||||||
f32 m_weight1;
|
|
||||||
f32 m_weight2;
|
|
||||||
f32 m_weight3;
|
|
||||||
f32 m_weight4;
|
|
||||||
|
|
||||||
E_VERTEX_TYPE getType() const
|
E_VERTEX_TYPE getType() const
|
||||||
{
|
{
|
||||||
|
@ -243,14 +243,14 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
|||||||
Vertex.TCoords=Vertices_Standard[n].TCoords;
|
Vertex.TCoords=Vertices_Standard[n].TCoords;
|
||||||
Vertex.Tangent=core::vector3df(0.0f, 0.0f, 0.0f);
|
Vertex.Tangent=core::vector3df(0.0f, 0.0f, 0.0f);
|
||||||
Vertex.Binormal=core::vector3df(0.0f, 0.0f, 0.0f);
|
Vertex.Binormal=core::vector3df(0.0f, 0.0f, 0.0f);
|
||||||
Vertex.m_joint_idx1 = 0;
|
Vertex.m_joint_idx[0] = 0;
|
||||||
Vertex.m_joint_idx2 = 0;
|
Vertex.m_joint_idx[1] = 0;
|
||||||
Vertex.m_joint_idx3 = 0;
|
Vertex.m_joint_idx[2] = 0;
|
||||||
Vertex.m_joint_idx4 = 0;
|
Vertex.m_joint_idx[3] = 0;
|
||||||
Vertex.m_weight1 = 0;
|
Vertex.m_weight[0] = 0;
|
||||||
Vertex.m_weight2 = 0;
|
Vertex.m_weight[1] = 0;
|
||||||
Vertex.m_weight3 = 0;
|
Vertex.m_weight[2] = 0;
|
||||||
Vertex.m_weight4 = 0;
|
Vertex.m_weight[3] = 0;
|
||||||
Vertices_SkinnedMesh.push_back(Vertex);
|
Vertices_SkinnedMesh.push_back(Vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,14 +265,14 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
|||||||
Vertex.TCoords=Vertices_Tangents[n].TCoords;
|
Vertex.TCoords=Vertices_Tangents[n].TCoords;
|
||||||
Vertex.Tangent=Vertices_Tangents[n].Tangent;
|
Vertex.Tangent=Vertices_Tangents[n].Tangent;
|
||||||
Vertex.Binormal=Vertices_Tangents[n].Binormal;
|
Vertex.Binormal=Vertices_Tangents[n].Binormal;
|
||||||
Vertex.m_joint_idx1 = 0;
|
Vertex.m_joint_idx[0] = 0;
|
||||||
Vertex.m_joint_idx2 = 0;
|
Vertex.m_joint_idx[1] = 0;
|
||||||
Vertex.m_joint_idx3 = 0;
|
Vertex.m_joint_idx[2] = 0;
|
||||||
Vertex.m_joint_idx4 = 0;
|
Vertex.m_joint_idx[3] = 0;
|
||||||
Vertex.m_weight1 = 0;
|
Vertex.m_weight[0] = 0;
|
||||||
Vertex.m_weight2 = 0;
|
Vertex.m_weight[1] = 0;
|
||||||
Vertex.m_weight3 = 0;
|
Vertex.m_weight[2] = 0;
|
||||||
Vertex.m_weight4 = 0;
|
Vertex.m_weight[3] = 0;
|
||||||
Vertices_SkinnedMesh.push_back(Vertex);
|
Vertices_SkinnedMesh.push_back(Vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,55 @@
|
|||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "irrMap.h"
|
#include "irrMap.h"
|
||||||
|
|
||||||
|
inline irr::s16 float_16(irr::f32 in)
|
||||||
|
{
|
||||||
|
irr::s32 i;
|
||||||
|
memcpy(&i, &in, 4);
|
||||||
|
irr::s32 s = (i >> 16) & 0x00008000;
|
||||||
|
irr::s32 e = ((i >> 23) & 0x000000ff) - (127 - 15);
|
||||||
|
irr::s32 m = i & 0x007fffff;
|
||||||
|
if (e <= 0)
|
||||||
|
{
|
||||||
|
if (e < -10)
|
||||||
|
{
|
||||||
|
return irr::s16(s);
|
||||||
|
}
|
||||||
|
m = (m | 0x00800000) >> (1 - e);
|
||||||
|
if (m & 0x00001000)
|
||||||
|
m += 0x00002000;
|
||||||
|
return irr::s16(s | (m >> 13));
|
||||||
|
}
|
||||||
|
else if (e == 0xff - (127 - 15))
|
||||||
|
{
|
||||||
|
if (m == 0)
|
||||||
|
{
|
||||||
|
return irr::s16(s | 0x7c00);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m >>= 13;
|
||||||
|
return irr::s16(s | 0x7c00 | m | (m == 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m & 0x00001000)
|
||||||
|
{
|
||||||
|
m += 0x00002000;
|
||||||
|
if (m & 0x00800000)
|
||||||
|
{
|
||||||
|
m = 0; // overflow in significand,
|
||||||
|
e += 1; // adjust exponent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e > 30)
|
||||||
|
{
|
||||||
|
return irr::s16(s | 0x7c00);
|
||||||
|
}
|
||||||
|
return irr::s16(s | (e << 10) | (m >> 13));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
namespace scene
|
namespace scene
|
||||||
@ -1450,28 +1499,34 @@ void CSkinnedMesh::convertForSkinning()
|
|||||||
core::array<JointInfluence> this_influence;
|
core::array<JointInfluence> this_influence;
|
||||||
core::array<JointInfluence> reported_weight = wi[b][i];
|
core::array<JointInfluence> reported_weight = wi[b][i];
|
||||||
reported_weight.sort(sortJointInfluenceFunc);
|
reported_weight.sort(sortJointInfluenceFunc);
|
||||||
float remaining_weight = 1.0f;
|
|
||||||
for (u32 j = 0; j < 4; j++)
|
for (u32 j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
JointInfluence influence;
|
JointInfluence influence;
|
||||||
if (reported_weight.size() > j)
|
influence.joint_idx = -100000;
|
||||||
influence = reported_weight[j];
|
influence.weight = 0.0f;
|
||||||
else
|
|
||||||
{
|
|
||||||
influence.joint_idx = -100000;
|
|
||||||
influence.weight = remaining_weight;
|
|
||||||
}
|
|
||||||
remaining_weight -= influence.weight;
|
|
||||||
this_influence.push_back(influence);
|
this_influence.push_back(influence);
|
||||||
}
|
}
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx1 = this_influence[0].joint_idx;
|
float total_weight = 0.0f;
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx2 = this_influence[1].joint_idx;
|
for (u32 j = 0; j < reported_weight.size(); j++)
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx3 = this_influence[2].joint_idx;
|
{
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx4 = this_influence[3].joint_idx;
|
total_weight += reported_weight[j].weight;
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight1 = this_influence[0].weight;
|
this_influence[j].joint_idx = reported_weight[j].joint_idx;
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight2 = this_influence[1].weight;
|
this_influence[j].weight = reported_weight[j].weight;
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight3 = this_influence[2].weight;
|
}
|
||||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight4 = this_influence[3].weight;
|
if (!reported_weight.empty())
|
||||||
|
{
|
||||||
|
for (u32 j = 0; j < reported_weight.size(); j++)
|
||||||
|
{
|
||||||
|
this_influence[j].weight =
|
||||||
|
this_influence[j].weight / total_weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx[j] = (s16)this_influence[j].joint_idx;
|
||||||
|
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight[j] = float_16
|
||||||
|
(this_influence[j].weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ bool CentralVideoSettings::isDefferedEnabled() const
|
|||||||
|
|
||||||
bool CentralVideoSettings::supportsHardwareSkinning() const
|
bool CentralVideoSettings::supportsHardwareSkinning() const
|
||||||
{
|
{
|
||||||
return isARBUniformBufferObjectUsable();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
|
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
|
||||||
|
@ -263,7 +263,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedFirstPassShader::getInstance()->use();
|
T::InstancedFirstPassShader::getInstance()->use();
|
||||||
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
|
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
|
||||||
|
handleSkinning(T::InstancedFirstPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
T::Instance));
|
T::Instance));
|
||||||
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
|
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
|
||||||
@ -303,7 +303,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedFirstPassShader::getInstance()->use();
|
T::InstancedFirstPassShader::getInstance()->use();
|
||||||
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
|
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
|
||||||
|
handleSkinning(T::InstancedFirstPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
T::Instance));
|
T::Instance));
|
||||||
glMultiDrawElementsIndirect(GL_TRIANGLES,
|
glMultiDrawElementsIndirect(GL_TRIANGLES,
|
||||||
@ -329,7 +329,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedSecondPassShader::getInstance()->use();
|
T::InstancedSecondPassShader::getInstance()->use();
|
||||||
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
|
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
|
||||||
|
handleSkinning(T::InstancedSecondPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
T::Instance));
|
T::Instance));
|
||||||
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
|
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
|
||||||
@ -364,7 +364,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedSecondPassShader::getInstance()->use();
|
T::InstancedSecondPassShader::getInstance()->use();
|
||||||
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
|
T::InstancedSecondPassShader::getInstance()->setUniforms(uniforms...);
|
||||||
|
handleSkinning(T::InstancedSecondPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
T::Instance));
|
T::Instance));
|
||||||
expandHandlesSecondPass<T>(handles);
|
expandHandlesSecondPass<T>(handles);
|
||||||
@ -451,7 +451,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedShadowPassShader::getInstance()->use();
|
T::InstancedShadowPassShader::getInstance()->use();
|
||||||
T::InstancedShadowPassShader::getInstance()->setUniforms(cascade, uniforms...);
|
T::InstancedShadowPassShader::getInstance()->setUniforms(cascade, uniforms...);
|
||||||
|
handleSkinning(T::InstancedShadowPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
InstanceTypeShadow));
|
InstanceTypeShadow));
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ public:
|
|||||||
{
|
{
|
||||||
T::InstancedShadowPassShader::getInstance()->use();
|
T::InstancedShadowPassShader::getInstance()->use();
|
||||||
T::InstancedShadowPassShader::getInstance()->setUniforms(cascade, uniforms...);
|
T::InstancedShadowPassShader::getInstance()->setUniforms(cascade, uniforms...);
|
||||||
|
handleSkinning(T::InstancedShadowPassShader::getInstance());
|
||||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
|
||||||
InstanceTypeShadow));
|
InstanceTypeShadow));
|
||||||
glMultiDrawElementsIndirect(GL_TRIANGLES,
|
glMultiDrawElementsIndirect(GL_TRIANGLES,
|
||||||
|
@ -258,7 +258,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
|||||||
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
|
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
|
||||||
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
|
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
|
||||||
{
|
{
|
||||||
skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
|
skinning_offset = getSkinningOffset();
|
||||||
if (skinning_offset + am->getTotalJoints() >
|
if (skinning_offset + am->getTotalJoints() >
|
||||||
SharedGPUObjects::getMaxMat4Size())
|
SharedGPUObjects::getMaxMat4Size())
|
||||||
{
|
{
|
||||||
@ -684,9 +684,20 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
|
PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
|
||||||
|
shadow_matrices.updateUBO();
|
||||||
|
#ifdef USE_GLES2
|
||||||
|
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
|
||||||
|
#else
|
||||||
|
glBindBuffer(GL_TEXTURE_BUFFER, SharedGPUObjects::getSkinningBuffer());
|
||||||
|
#endif
|
||||||
for (unsigned i = 0; i < m_deferred_update.size(); i++)
|
for (unsigned i = 0; i < m_deferred_update.size(); i++)
|
||||||
m_deferred_update[i]->updateGL();
|
m_deferred_update[i]->updateGL();
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
|
#ifdef USE_GLES2
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
#else
|
||||||
|
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
PROFILER_PUSH_CPU_MARKER("- cpu particle upload", 0x3F, 0x03, 0x61);
|
PROFILER_PUSH_CPU_MARKER("- cpu particle upload", 0x3F, 0x03, 0x61);
|
||||||
CPUParticleManager::getInstance()->uploadAll();
|
CPUParticleManager::getInstance()->uploadAll();
|
||||||
|
@ -28,6 +28,7 @@ void renderMeshes1stPass()
|
|||||||
{
|
{
|
||||||
auto &meshes = T::List::getInstance()->SolidPass;
|
auto &meshes = T::List::getInstance()->SolidPass;
|
||||||
T::FirstPassShader::getInstance()->use();
|
T::FirstPassShader::getInstance()->use();
|
||||||
|
handleSkinning(T::FirstPassShader::getInstance());
|
||||||
if (CVS->isARBBaseInstanceUsable())
|
if (CVS->isARBBaseInstanceUsable())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||||
for (unsigned i = 0; i < meshes.size(); i++)
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
@ -58,6 +59,7 @@ void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
|||||||
{
|
{
|
||||||
auto &meshes = T::List::getInstance()->SolidPass;
|
auto &meshes = T::List::getInstance()->SolidPass;
|
||||||
T::SecondPassShader::getInstance()->use();
|
T::SecondPassShader::getInstance()->use();
|
||||||
|
handleSkinning(T::SecondPassShader::getInstance());
|
||||||
if (CVS->isARBBaseInstanceUsable())
|
if (CVS->isARBBaseInstanceUsable())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||||
for (unsigned i = 0; i < meshes.size(); i++)
|
for (unsigned i = 0; i < meshes.size(); i++)
|
||||||
@ -95,6 +97,7 @@ void renderShadow(unsigned cascade)
|
|||||||
{
|
{
|
||||||
auto &t = T::List::getInstance()->Shadows[cascade];
|
auto &t = T::List::getInstance()->Shadows[cascade];
|
||||||
T::ShadowPassShader::getInstance()->use();
|
T::ShadowPassShader::getInstance()->use();
|
||||||
|
handleSkinning(T::ShadowPassShader::getInstance());
|
||||||
if (CVS->isARBBaseInstanceUsable())
|
if (CVS->isARBBaseInstanceUsable())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||||
for (unsigned i = 0; i < t.size(); i++)
|
for (unsigned i = 0; i < t.size(); i++)
|
||||||
|
@ -183,5 +183,14 @@ struct HandleExpander
|
|||||||
} // Expand
|
} // Expand
|
||||||
}; // HandleExpander
|
}; // HandleExpander
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template <typename Shader>
|
||||||
|
inline void handleSkinning(Shader* s)
|
||||||
|
{
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(s))
|
||||||
|
{
|
||||||
|
sms->bindSkinningTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif //HEADER_DRAW_TOOLS_HPP
|
#endif //HEADER_DRAW_TOOLS_HPP
|
||||||
|
@ -202,6 +202,7 @@ void renderTransparenPass(const std::vector<RenderGeometry::TexUnit> &TexUnits,
|
|||||||
std::vector<std::tuple<TupleType...> > *meshes)
|
std::vector<std::tuple<TupleType...> > *meshes)
|
||||||
{
|
{
|
||||||
Shader::getInstance()->use();
|
Shader::getInstance()->use();
|
||||||
|
handleSkinning(Shader::getInstance());
|
||||||
if (CVS->isARBBaseInstanceUsable())
|
if (CVS->isARBBaseInstanceUsable())
|
||||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||||
for (unsigned i = 0; i < meshes->size(); i++)
|
for (unsigned i = 0; i < meshes->size(); i++)
|
||||||
|
@ -154,9 +154,9 @@ public:
|
|||||||
glEnableVertexAttribArray(4);
|
glEnableVertexAttribArray(4);
|
||||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)44);
|
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)44);
|
||||||
glEnableVertexAttribArray(5);
|
glEnableVertexAttribArray(5);
|
||||||
glVertexAttribIPointer(5, 4, GL_INT, getVertexPitchFromType(tp), (GLvoid*)60);
|
glVertexAttribIPointer(5, 4, GL_SHORT, getVertexPitchFromType(tp), (GLvoid*)60);
|
||||||
glEnableVertexAttribArray(6);
|
glEnableVertexAttribArray(6);
|
||||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)76);
|
glVertexAttribPointer(6, 4, GL_HALF_FLOAT, GL_FALSE, getVertexPitchFromType(tp), (GLvoid*)68);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,6 +488,10 @@ SkinnedPass1Shader::SkinnedPass1Shader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "object_pass1.frag");
|
GL_FRAGMENT_SHADER, "object_pass1.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
|
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // SkinnedPass1Shader
|
} // SkinnedPass1Shader
|
||||||
@ -499,6 +503,10 @@ InstancedSkinnedPass1Shader::InstancedSkinnedPass1Shader()
|
|||||||
loadProgram(SKINNED_MESH,
|
loadProgram(SKINNED_MESH,
|
||||||
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_object_pass1.frag");
|
GL_FRAGMENT_SHADER, "instanced_object_pass1.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "glosstex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "glosstex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // InstancedSkinnedPass1Shader
|
} // InstancedSkinnedPass1Shader
|
||||||
@ -509,6 +517,10 @@ SkinnedPass2Shader::SkinnedPass2Shader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "object_pass2.frag");
|
GL_FRAGMENT_SHADER, "object_pass2.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "texture_trans", "color_change",
|
assignUniforms("ModelMatrix", "texture_trans", "color_change",
|
||||||
"skinning_offset");
|
"skinning_offset");
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
@ -527,6 +539,10 @@ InstancedSkinnedPass2Shader::InstancedSkinnedPass2Shader()
|
|||||||
loadProgram(SKINNED_MESH,
|
loadProgram(SKINNED_MESH,
|
||||||
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_object_pass2.frag");
|
GL_FRAGMENT_SHADER, "instanced_object_pass2.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
1, "SpecularMap", ST_NEAREST_FILTERED,
|
1, "SpecularMap", ST_NEAREST_FILTERED,
|
||||||
@ -543,6 +559,10 @@ SkinnedRefPass1Shader::SkinnedRefPass1Shader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "objectref_pass1.frag");
|
GL_FRAGMENT_SHADER, "objectref_pass1.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "InverseModelMatrix", "texture_trans",
|
assignUniforms("ModelMatrix", "InverseModelMatrix", "texture_trans",
|
||||||
"skinning_offset");
|
"skinning_offset");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
@ -556,6 +576,10 @@ InstancedSkinnedRefPass1Shader::InstancedSkinnedRefPass1Shader()
|
|||||||
loadProgram(SKINNED_MESH,
|
loadProgram(SKINNED_MESH,
|
||||||
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_objectref_pass1.frag");
|
GL_FRAGMENT_SHADER, "instanced_objectref_pass1.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
1, "glosstex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
1, "glosstex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
@ -567,6 +591,10 @@ SkinnedRefPass2Shader::SkinnedRefPass2Shader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "objectref_pass2.frag");
|
GL_FRAGMENT_SHADER, "objectref_pass2.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "texture_trans", "color_change",
|
assignUniforms("ModelMatrix", "texture_trans", "color_change",
|
||||||
"skinning_offset");
|
"skinning_offset");
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
@ -585,6 +613,10 @@ InstancedSkinnedRefPass2Shader::InstancedSkinnedRefPass2Shader()
|
|||||||
loadProgram(SKINNED_MESH,
|
loadProgram(SKINNED_MESH,
|
||||||
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_objectref_pass2.frag");
|
GL_FRAGMENT_SHADER, "instanced_objectref_pass2.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
1, "SpecularMap", ST_NEAREST_FILTERED,
|
1, "SpecularMap", ST_NEAREST_FILTERED,
|
||||||
@ -601,6 +633,10 @@ SkinnedUnlitShader::SkinnedUnlitShader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "object_unlit.frag");
|
GL_FRAGMENT_SHADER, "object_unlit.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "texture_trans", "skinning_offset");
|
assignUniforms("ModelMatrix", "texture_trans", "skinning_offset");
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
1, "SpecularMap", ST_NEAREST_FILTERED,
|
1, "SpecularMap", ST_NEAREST_FILTERED,
|
||||||
@ -615,6 +651,10 @@ InstancedSkinnedUnlitShader::InstancedSkinnedUnlitShader()
|
|||||||
loadProgram(SKINNED_MESH,
|
loadProgram(SKINNED_MESH,
|
||||||
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_object_unlit.frag");
|
GL_FRAGMENT_SHADER, "instanced_object_unlit.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
assignSamplerNames(0, "DiffuseMap", ST_NEAREST_FILTERED,
|
||||||
1, "SpecularMap", ST_NEAREST_FILTERED,
|
1, "SpecularMap", ST_NEAREST_FILTERED,
|
||||||
@ -628,6 +668,10 @@ SkinnedNormalMapShader::SkinnedNormalMapShader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "normalmap.frag");
|
GL_FRAGMENT_SHADER, "normalmap.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
|
assignUniforms("ModelMatrix", "InverseModelMatrix", "skinning_offset");
|
||||||
assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
1, "glossMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
1, "glossMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
@ -639,6 +683,10 @@ InstancedSkinnedNormalMapShader::InstancedSkinnedNormalMapShader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "instanced_skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "instanced_normalmap.frag");
|
GL_FRAGMENT_SHADER, "instanced_normalmap.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms();
|
assignUniforms();
|
||||||
assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
assignSamplerNames(0, "normalMap", ST_TRILINEAR_ANISOTROPIC_FILTERED,
|
||||||
1, "glossMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
1, "glossMap", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
@ -662,6 +710,10 @@ SkinnedShadowShader::SkinnedShadowShader()
|
|||||||
GL_GEOMETRY_SHADER, "shadow.geom",
|
GL_GEOMETRY_SHADER, "shadow.geom",
|
||||||
GL_FRAGMENT_SHADER, "shadow.frag");
|
GL_FRAGMENT_SHADER, "shadow.frag");
|
||||||
}
|
}
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "skinning_offset", "layer");
|
assignUniforms("ModelMatrix", "skinning_offset", "layer");
|
||||||
#endif
|
#endif
|
||||||
} // SkinnedShadowShader
|
} // SkinnedShadowShader
|
||||||
@ -686,6 +738,10 @@ InstancedSkinnedShadowShader::InstancedSkinnedShadowShader()
|
|||||||
GL_GEOMETRY_SHADER, "instanced_shadow.geom",
|
GL_GEOMETRY_SHADER, "instanced_shadow.geom",
|
||||||
GL_FRAGMENT_SHADER, "shadow.frag");
|
GL_FRAGMENT_SHADER, "shadow.frag");
|
||||||
}
|
}
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("layer");
|
assignUniforms("layer");
|
||||||
#endif
|
#endif
|
||||||
} // InstancedSkinnedShadowShader
|
} // InstancedSkinnedShadowShader
|
||||||
@ -708,6 +764,10 @@ SkinnedRefShadowShader::SkinnedRefShadowShader()
|
|||||||
GL_GEOMETRY_SHADER, "shadow.geom",
|
GL_GEOMETRY_SHADER, "shadow.geom",
|
||||||
GL_FRAGMENT_SHADER, "shadowref.frag");
|
GL_FRAGMENT_SHADER, "shadowref.frag");
|
||||||
}
|
}
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "skinning_offset", "layer");
|
assignUniforms("ModelMatrix", "skinning_offset", "layer");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
#endif
|
#endif
|
||||||
@ -733,6 +793,10 @@ InstancedSkinnedRefShadowShader::InstancedSkinnedRefShadowShader()
|
|||||||
GL_GEOMETRY_SHADER, "instanced_shadow.geom",
|
GL_GEOMETRY_SHADER, "instanced_shadow.geom",
|
||||||
GL_FRAGMENT_SHADER, "instanced_shadowref.frag");
|
GL_FRAGMENT_SHADER, "instanced_shadowref.frag");
|
||||||
}
|
}
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("layer");
|
assignUniforms("layer");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
#endif
|
#endif
|
||||||
|
@ -296,7 +296,8 @@ public:
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedPass1Shader : public TextureShader<SkinnedPass1Shader, 1,
|
class SkinnedPass1Shader : public TextureShader<SkinnedPass1Shader, 1,
|
||||||
core::matrix4, core::matrix4,
|
core::matrix4, core::matrix4,
|
||||||
int>
|
int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedPass1Shader();
|
SkinnedPass1Shader();
|
||||||
@ -304,7 +305,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedPass1Shader
|
class InstancedSkinnedPass1Shader
|
||||||
: public TextureShader<InstancedSkinnedPass1Shader, 1>
|
: public TextureShader<InstancedSkinnedPass1Shader, 1>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedPass1Shader();
|
InstancedSkinnedPass1Shader();
|
||||||
@ -313,7 +315,8 @@ public:
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedPass2Shader : public TextureShader<SkinnedPass2Shader, 6,
|
class SkinnedPass2Shader : public TextureShader<SkinnedPass2Shader, 6,
|
||||||
core::matrix4, core::vector2df,
|
core::matrix4, core::vector2df,
|
||||||
core::vector2df, int >
|
core::vector2df, int >,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedPass2Shader();
|
SkinnedPass2Shader();
|
||||||
@ -321,7 +324,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedPass2Shader
|
class InstancedSkinnedPass2Shader
|
||||||
: public TextureShader<InstancedSkinnedPass2Shader, 6>
|
: public TextureShader<InstancedSkinnedPass2Shader, 6>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedPass2Shader();
|
InstancedSkinnedPass2Shader();
|
||||||
@ -331,7 +335,8 @@ public:
|
|||||||
class SkinnedRefPass1Shader : public TextureShader<SkinnedRefPass1Shader, 2,
|
class SkinnedRefPass1Shader : public TextureShader<SkinnedRefPass1Shader, 2,
|
||||||
core::matrix4,
|
core::matrix4,
|
||||||
core::matrix4,
|
core::matrix4,
|
||||||
core::vector2df, int>
|
core::vector2df, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedRefPass1Shader();
|
SkinnedRefPass1Shader();
|
||||||
@ -339,7 +344,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedRefPass1Shader
|
class InstancedSkinnedRefPass1Shader
|
||||||
: public TextureShader<InstancedSkinnedRefPass1Shader, 2>
|
: public TextureShader<InstancedSkinnedRefPass1Shader, 2>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedRefPass1Shader();
|
InstancedSkinnedRefPass1Shader();
|
||||||
@ -349,7 +355,8 @@ public:
|
|||||||
class SkinnedRefPass2Shader : public TextureShader<SkinnedRefPass2Shader, 6,
|
class SkinnedRefPass2Shader : public TextureShader<SkinnedRefPass2Shader, 6,
|
||||||
core::matrix4,
|
core::matrix4,
|
||||||
core::vector2df,
|
core::vector2df,
|
||||||
core::vector2df, int>
|
core::vector2df, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedRefPass2Shader();
|
SkinnedRefPass2Shader();
|
||||||
@ -357,7 +364,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedRefPass2Shader
|
class InstancedSkinnedRefPass2Shader
|
||||||
: public TextureShader<InstancedSkinnedRefPass2Shader, 6>
|
: public TextureShader<InstancedSkinnedRefPass2Shader, 6>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedRefPass2Shader();
|
InstancedSkinnedRefPass2Shader();
|
||||||
@ -366,7 +374,8 @@ public:
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedUnlitShader : public TextureShader<SkinnedUnlitShader, 4,
|
class SkinnedUnlitShader : public TextureShader<SkinnedUnlitShader, 4,
|
||||||
core::matrix4, core::vector2df,
|
core::matrix4, core::vector2df,
|
||||||
int>
|
int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedUnlitShader();
|
SkinnedUnlitShader();
|
||||||
@ -374,7 +383,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedUnlitShader
|
class InstancedSkinnedUnlitShader
|
||||||
: public TextureShader<InstancedSkinnedUnlitShader, 4>
|
: public TextureShader<InstancedSkinnedUnlitShader, 4>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedUnlitShader();
|
InstancedSkinnedUnlitShader();
|
||||||
@ -383,7 +393,8 @@ public:
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedNormalMapShader : public TextureShader<SkinnedNormalMapShader, 2,
|
class SkinnedNormalMapShader : public TextureShader<SkinnedNormalMapShader, 2,
|
||||||
core::matrix4,
|
core::matrix4,
|
||||||
core::matrix4, int>
|
core::matrix4, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedNormalMapShader();
|
SkinnedNormalMapShader();
|
||||||
@ -391,7 +402,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedNormalMapShader
|
class InstancedSkinnedNormalMapShader
|
||||||
: public TextureShader<InstancedSkinnedNormalMapShader, 2>
|
: public TextureShader<InstancedSkinnedNormalMapShader, 2>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedNormalMapShader();
|
InstancedSkinnedNormalMapShader();
|
||||||
@ -399,7 +411,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedShadowShader : public TextureShader<SkinnedShadowShader, 0,
|
class SkinnedShadowShader : public TextureShader<SkinnedShadowShader, 0,
|
||||||
core::matrix4, int, int>
|
core::matrix4, int, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedShadowShader();
|
SkinnedShadowShader();
|
||||||
@ -407,7 +420,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedShadowShader
|
class InstancedSkinnedShadowShader
|
||||||
: public TextureShader<InstancedSkinnedShadowShader, 0, int>
|
: public TextureShader<InstancedSkinnedShadowShader, 0, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedShadowShader();
|
InstancedSkinnedShadowShader();
|
||||||
@ -415,7 +429,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class SkinnedRefShadowShader : public TextureShader<SkinnedRefShadowShader, 1,
|
class SkinnedRefShadowShader : public TextureShader<SkinnedRefShadowShader, 1,
|
||||||
core::matrix4, int, int>
|
core::matrix4, int, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedRefShadowShader();
|
SkinnedRefShadowShader();
|
||||||
@ -423,7 +438,8 @@ public:
|
|||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
class InstancedSkinnedRefShadowShader
|
class InstancedSkinnedRefShadowShader
|
||||||
: public TextureShader<InstancedSkinnedRefShadowShader, 1, int>
|
: public TextureShader<InstancedSkinnedRefShadowShader, 1, int>,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InstancedSkinnedRefShadowShader();
|
InstancedSkinnedRefShadowShader();
|
||||||
|
@ -367,6 +367,8 @@ public:
|
|||||||
}
|
}
|
||||||
} // loadProgram
|
} // loadProgram
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
virtual void bindCustomTextures() {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void drawFullScreenEffect(Args...args)
|
void drawFullScreenEffect(Args...args)
|
||||||
{
|
{
|
||||||
@ -379,6 +381,34 @@ public:
|
|||||||
}; // Shader
|
}; // Shader
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
class SkinnedMeshShader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GLuint m_skinning_tex_location;
|
||||||
|
public:
|
||||||
|
SkinnedMeshShader() : m_skinning_tex_location(0) {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
template <typename Shader>
|
||||||
|
void init(Shader* s)
|
||||||
|
{
|
||||||
|
s->use();
|
||||||
|
m_skinning_tex_location = s->getUniformLocation("skinning_tex");
|
||||||
|
glUniform1i(m_skinning_tex_location, 15);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void bindSkinningTexture()
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + 15);
|
||||||
|
#ifdef USE_GLES2
|
||||||
|
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
|
||||||
|
#else
|
||||||
|
glBindTexture(GL_TEXTURE_BUFFER,
|
||||||
|
SharedGPUObjects::getSkinningTexture());
|
||||||
|
#endif
|
||||||
|
glBindSampler(15, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -152,39 +152,6 @@ void ShaderBasedRenderer::prepareForwardRenderer()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Upload lighting info to the dedicated uniform buffer
|
|
||||||
*/
|
|
||||||
void ShaderBasedRenderer::uploadLightingData() const
|
|
||||||
{
|
|
||||||
assert(CVS->isARBUniformBufferObjectUsable());
|
|
||||||
|
|
||||||
float Lighting[36];
|
|
||||||
|
|
||||||
core::vector3df sun_direction = irr_driver->getSunDirection();
|
|
||||||
video::SColorf sun_color = irr_driver->getSunColor();
|
|
||||||
|
|
||||||
Lighting[0] = sun_direction.X;
|
|
||||||
Lighting[1] = sun_direction.Y;
|
|
||||||
Lighting[2] = sun_direction.Z;
|
|
||||||
Lighting[4] = sun_color.getRed();
|
|
||||||
Lighting[5] = sun_color.getGreen();
|
|
||||||
Lighting[6] = sun_color.getBlue();
|
|
||||||
Lighting[7] = 0.54f;
|
|
||||||
|
|
||||||
const SHCoefficients* sh_coeff = m_spherical_harmonics->getCoefficients();
|
|
||||||
|
|
||||||
if(sh_coeff) {
|
|
||||||
memcpy(&Lighting[8], sh_coeff->blue_SH_coeff, 9 * sizeof(float));
|
|
||||||
memcpy(&Lighting[17], sh_coeff->green_SH_coeff, 9 * sizeof(float));
|
|
||||||
memcpy(&Lighting[26], sh_coeff->red_SH_coeff, 9 * sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO());
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 36 * sizeof(float), Lighting);
|
|
||||||
} // uploadLightingData
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
|
void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
|
||||||
unsigned int width, unsigned int height)
|
unsigned int width, unsigned int height)
|
||||||
@ -237,8 +204,6 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
|||||||
{
|
{
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedGPUObjects::getViewProjectionMatricesUBO());
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedGPUObjects::getViewProjectionMatricesUBO());
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 1, SharedGPUObjects::getLightingDataUBO());
|
glBindBufferBase(GL_UNIFORM_BUFFER, 1, SharedGPUObjects::getLightingDataUBO());
|
||||||
if (CVS->supportsHardwareSkinning())
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 2, SharedGPUObjects::getSkinningUBO());
|
|
||||||
}
|
}
|
||||||
irr_driver->getSceneManager()->setActiveCamera(camnode);
|
irr_driver->getSceneManager()->setActiveCamera(camnode);
|
||||||
|
|
||||||
@ -812,11 +777,9 @@ void ShaderBasedRenderer::render(float dt)
|
|||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PROFILER_PUSH_CPU_MARKER("UBO upload", 0x0, 0xFF, 0x0);
|
PROFILER_PUSH_CPU_MARKER("Update camera matrices", 0x0, 0xFF, 0x0);
|
||||||
computeMatrixesAndCameras(camnode, m_rtts->getWidth(), m_rtts->getHeight());
|
computeMatrixesAndCameras(camnode, m_rtts->getWidth(), m_rtts->getHeight());
|
||||||
m_shadow_matrices.updateSunOrthoMatrices();
|
m_shadow_matrices.updateSunOrthoMatrices();
|
||||||
if(CVS->isARBUniformBufferObjectUsable())
|
|
||||||
uploadLightingData();
|
|
||||||
PROFILER_POP_CPU_MARKER();
|
PROFILER_POP_CPU_MARKER();
|
||||||
renderScene(camnode, dt, track->hasShadows(), false);
|
renderScene(camnode, dt, track->hasShadows(), false);
|
||||||
|
|
||||||
@ -923,9 +886,6 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target,
|
|||||||
irr_driver->getSceneManager()->setActiveCamera(camera);
|
irr_driver->getSceneManager()->setActiveCamera(camera);
|
||||||
|
|
||||||
computeMatrixesAndCameras(camera, m_rtts->getWidth(), m_rtts->getHeight());
|
computeMatrixesAndCameras(camera, m_rtts->getWidth(), m_rtts->getHeight());
|
||||||
if (CVS->isARBUniformBufferObjectUsable())
|
|
||||||
uploadLightingData();
|
|
||||||
|
|
||||||
renderScene(camera, dt, false, true);
|
renderScene(camera, dt, false, true);
|
||||||
render_target->setFrameBuffer(m_post_processing
|
render_target->setFrameBuffer(m_post_processing
|
||||||
->render(camera, false, m_rtts));
|
->render(camera, false, m_rtts));
|
||||||
|
@ -61,8 +61,6 @@ private:
|
|||||||
|
|
||||||
void prepareForwardRenderer();
|
void prepareForwardRenderer();
|
||||||
|
|
||||||
void uploadLightingData() const;
|
|
||||||
|
|
||||||
void computeMatrixesAndCameras(scene::ICameraSceneNode * const camnode,
|
void computeMatrixesAndCameras(scene::ICameraSceneNode * const camnode,
|
||||||
unsigned int width, unsigned int height);
|
unsigned int width, unsigned int height);
|
||||||
|
|
||||||
|
@ -277,6 +277,10 @@ Shaders::SkinnedTransparentShader::SkinnedTransparentShader()
|
|||||||
if (!CVS->supportsHardwareSkinning()) return;
|
if (!CVS->supportsHardwareSkinning()) return;
|
||||||
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
loadProgram(SKINNED_MESH, GL_VERTEX_SHADER, "skinning.vert",
|
||||||
GL_FRAGMENT_SHADER, "transparent.frag");
|
GL_FRAGMENT_SHADER, "transparent.frag");
|
||||||
|
if (SkinnedMeshShader* sms = dynamic_cast<SkinnedMeshShader*>(this))
|
||||||
|
{
|
||||||
|
sms->init(this);
|
||||||
|
}
|
||||||
assignUniforms("ModelMatrix", "texture_trans", "skinning_offset", "custom_alpha");
|
assignUniforms("ModelMatrix", "texture_trans", "skinning_offset", "custom_alpha");
|
||||||
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||||
} // SkinnedTransparentShader
|
} // SkinnedTransparentShader
|
||||||
|
@ -140,7 +140,8 @@ public:
|
|||||||
// ========================================================================
|
// ========================================================================
|
||||||
class SkinnedTransparentShader : public TextureShader<SkinnedTransparentShader, 1,
|
class SkinnedTransparentShader : public TextureShader<SkinnedTransparentShader, 1,
|
||||||
core::matrix4, core::vector2df,
|
core::matrix4, core::vector2df,
|
||||||
int, float >
|
int, float >,
|
||||||
|
public SkinnedMeshShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkinnedTransparentShader();
|
SkinnedTransparentShader();
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "graphics/post_processing.hpp"
|
#include "graphics/post_processing.hpp"
|
||||||
#include "graphics/rtts.hpp"
|
#include "graphics/rtts.hpp"
|
||||||
#include "graphics/shared_gpu_objects.hpp"
|
#include "graphics/shared_gpu_objects.hpp"
|
||||||
|
#include "graphics/spherical_harmonics.hpp"
|
||||||
#include "graphics/texture_shader.hpp"
|
#include "graphics/texture_shader.hpp"
|
||||||
#include "modes/world.hpp"
|
#include "modes/world.hpp"
|
||||||
#include "physics/triangle_mesh.hpp"
|
#include "physics/triangle_mesh.hpp"
|
||||||
@ -311,6 +312,55 @@ void ShadowMatrices::updateSplitAndLightcoordRangeFromComputeShaders(unsigned in
|
|||||||
#endif
|
#endif
|
||||||
} // updateSplitAndLightcoordRangeFromComputeShaders
|
} // updateSplitAndLightcoordRangeFromComputeShaders
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ShadowMatrices::updateUBO()
|
||||||
|
{
|
||||||
|
if (!CVS->isARBUniformBufferObjectUsable())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float lighting[36] = {};
|
||||||
|
core::vector3df sun_direction = irr_driver->getSunDirection();
|
||||||
|
video::SColorf sun_color = irr_driver->getSunColor();
|
||||||
|
|
||||||
|
lighting[0] = sun_direction.X;
|
||||||
|
lighting[1] = sun_direction.Y;
|
||||||
|
lighting[2] = sun_direction.Z;
|
||||||
|
lighting[4] = sun_color.getRed();
|
||||||
|
lighting[5] = sun_color.getGreen();
|
||||||
|
lighting[6] = sun_color.getBlue();
|
||||||
|
lighting[7] = 0.54f;
|
||||||
|
|
||||||
|
const SHCoefficients* sh_coeff = irr_driver->getSHCoefficients();
|
||||||
|
|
||||||
|
if (sh_coeff)
|
||||||
|
{
|
||||||
|
memcpy(&lighting[8], sh_coeff->blue_SH_coeff, 9 * sizeof(float));
|
||||||
|
memcpy(&lighting[17], sh_coeff->green_SH_coeff, 9 * sizeof(float));
|
||||||
|
memcpy(&lighting[26], sh_coeff->red_SH_coeff, 9 * sizeof(float));
|
||||||
|
}
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO());
|
||||||
|
void* ptr = glMapBufferRange(GL_UNIFORM_BUFFER, 0, 36 * 4,
|
||||||
|
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT |
|
||||||
|
GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
memcpy(ptr, lighting, 36 * 4);
|
||||||
|
glUnmapBuffer(GL_UNIFORM_BUFFER);
|
||||||
|
|
||||||
|
if (CVS->isSDSMEnabled())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER,
|
||||||
|
SharedGPUObjects::getViewProjectionMatricesUBO());
|
||||||
|
ptr = glMapBufferRange(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * 4,
|
||||||
|
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT |
|
||||||
|
GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||||
|
memcpy(ptr, m_ubo_data, (16 * 9 + 2) * 4);
|
||||||
|
glUnmapBuffer(GL_UNIFORM_BUFFER);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
} // updateUBO
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Generate View, Projection, Inverse View, Inverse Projection, ViewProjection
|
/** Generate View, Projection, Inverse View, Inverse Projection, ViewProjection
|
||||||
* and InverseProjection matrixes and matrixes and cameras for the four shadow
|
* and InverseProjection matrixes and matrixes and cameras for the four shadow
|
||||||
@ -338,12 +388,11 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
|
|||||||
const float oldfar = camnode->getFarValue();
|
const float oldfar = camnode->getFarValue();
|
||||||
const float oldnear = camnode->getNearValue();
|
const float oldnear = camnode->getNearValue();
|
||||||
|
|
||||||
float tmp[16 * 9 + 2];
|
memcpy(m_ubo_data, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
|
||||||
memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
|
memcpy(&m_ubo_data[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
|
||||||
memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
|
memcpy(&m_ubo_data[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
|
||||||
memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
|
memcpy(&m_ubo_data[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
|
||||||
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
|
memcpy(&m_ubo_data[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float));
|
||||||
memcpy(&tmp[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float));
|
|
||||||
|
|
||||||
m_sun_cam->render();
|
m_sun_cam->render();
|
||||||
for (unsigned i = 0; i < 4; i++)
|
for (unsigned i = 0; i < 4; i++)
|
||||||
@ -469,27 +518,23 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca
|
|||||||
|
|
||||||
size_t size = m_sun_ortho_matrices.size();
|
size_t size = m_sun_ortho_matrices.size();
|
||||||
for (unsigned i = 0; i < size; i++)
|
for (unsigned i = 0; i < size; i++)
|
||||||
memcpy(&tmp[16 * i + 80],
|
memcpy(&m_ubo_data[16 * i + 80],
|
||||||
m_sun_ortho_matrices[i].pointer(),
|
m_sun_ortho_matrices[i].pointer(),
|
||||||
16 * sizeof(float));
|
16 * sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CVS->isARBUniformBufferObjectUsable())
|
m_ubo_data[144] = float(width);
|
||||||
return;
|
m_ubo_data[145] = float(height);
|
||||||
|
|
||||||
tmp[144] = float(width);
|
|
||||||
tmp[145] = float(height);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER,
|
|
||||||
SharedGPUObjects::getViewProjectionMatricesUBO());
|
|
||||||
if (CVS->isSDSMEnabled())
|
if (CVS->isSDSMEnabled())
|
||||||
{
|
{
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 5) * sizeof(float), tmp);
|
glBindBuffer(GL_UNIFORM_BUFFER,
|
||||||
|
SharedGPUObjects::getViewProjectionMatricesUBO());
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 5) * sizeof(float),
|
||||||
|
m_ubo_data);
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float),
|
glBufferSubData(GL_UNIFORM_BUFFER, (16 * 9) * sizeof(float),
|
||||||
2 * sizeof(float), &tmp[144]);
|
2 * sizeof(float), &m_ubo_data[144]);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float),
|
|
||||||
tmp);
|
|
||||||
} // computeMatrixesAndCameras
|
} // computeMatrixesAndCameras
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -49,6 +49,7 @@ private:
|
|||||||
core::matrix4 m_rsm_matrix;
|
core::matrix4 m_rsm_matrix;
|
||||||
bool m_rsm_matrix_initialized;
|
bool m_rsm_matrix_initialized;
|
||||||
float m_shadows_cam[4][24];
|
float m_shadows_cam[4][24];
|
||||||
|
float m_ubo_data[16 * 9 + 2];
|
||||||
bool m_rsm_map_available;
|
bool m_rsm_map_available;
|
||||||
core::vector3df m_rh_extend;
|
core::vector3df m_rh_extend;
|
||||||
core::matrix4 m_rh_matrix;
|
core::matrix4 m_rh_matrix;
|
||||||
@ -104,6 +105,7 @@ public:
|
|||||||
return m_shadow_scales;
|
return m_shadow_scales;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
void updateUBO();
|
||||||
|
|
||||||
}; // class ShadowMatrices
|
}; // class ShadowMatrices
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ GLuint SharedGPUObjects::m_full_screen_quad_vao;
|
|||||||
GLuint SharedGPUObjects::m_ui_vao;
|
GLuint SharedGPUObjects::m_ui_vao;
|
||||||
GLuint SharedGPUObjects::m_quad_buffer;
|
GLuint SharedGPUObjects::m_quad_buffer;
|
||||||
GLuint SharedGPUObjects::m_quad_vbo;
|
GLuint SharedGPUObjects::m_quad_vbo;
|
||||||
GLuint SharedGPUObjects::m_skinning_ubo;
|
GLuint SharedGPUObjects::m_skinning_tex;
|
||||||
|
GLuint SharedGPUObjects::m_skinning_buf;
|
||||||
int SharedGPUObjects::m_max_mat4_size = 1024;
|
int SharedGPUObjects::m_max_mat4_size = 1024;
|
||||||
bool SharedGPUObjects::m_has_been_initialised = false;
|
bool SharedGPUObjects::m_has_been_initialised = false;
|
||||||
|
|
||||||
@ -158,24 +159,29 @@ void SharedGPUObjects::initLightingDataUBO()
|
|||||||
} // initLightingDataUBO
|
} // initLightingDataUBO
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void SharedGPUObjects::initSkinningUBO()
|
void SharedGPUObjects::initSkinning()
|
||||||
{
|
{
|
||||||
assert(CVS->isARBUniformBufferObjectUsable());
|
m_max_mat4_size = 1024;
|
||||||
irr::core::matrix4 m;
|
glGenTextures(1, &m_skinning_tex);
|
||||||
glGenBuffers(1, &m_skinning_ubo);
|
#ifdef USE_GLES2
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, m_skinning_ubo);
|
glBindTexture(GL_TEXTURE_2D, m_skinning_tex);
|
||||||
int max_size = 0;
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
max_size = std::min(max_size, 65536);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
m_max_mat4_size = max_size / 16 / sizeof(float);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
Log::info("SharedGPUObjects", "Hardware skinning supported, max joints"
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 1024, 0, GL_RGBA, GL_FLOAT,
|
||||||
" support: %d", m_max_mat4_size);
|
NULL);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, max_size, 0, GL_STREAM_DRAW);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
// Reserve a identity matrix for non moving mesh in animated model used by
|
#else
|
||||||
// vertex shader calculation
|
glGenBuffers(1, &m_skinning_buf);
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * sizeof(float), m.pointer());
|
glBindBuffer(GL_TEXTURE_BUFFER, m_skinning_buf);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBufferData(GL_TEXTURE_BUFFER, 65536, NULL, GL_DYNAMIC_DRAW);
|
||||||
} // initSkinningUBO
|
glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex);
|
||||||
|
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf);
|
||||||
|
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||||
|
#endif
|
||||||
|
} // initSkinningTBO
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void SharedGPUObjects::init()
|
void SharedGPUObjects::init()
|
||||||
@ -186,13 +192,14 @@ void SharedGPUObjects::init()
|
|||||||
initQuadBuffer();
|
initQuadBuffer();
|
||||||
initSkyTriVBO();
|
initSkyTriVBO();
|
||||||
initFrustrumVBO();
|
initFrustrumVBO();
|
||||||
|
if (CVS->supportsHardwareSkinning())
|
||||||
|
{
|
||||||
|
initSkinning();
|
||||||
|
}
|
||||||
if (CVS->isARBUniformBufferObjectUsable())
|
if (CVS->isARBUniformBufferObjectUsable())
|
||||||
{
|
{
|
||||||
initShadowVPMUBO();
|
initShadowVPMUBO();
|
||||||
initLightingDataUBO();
|
initLightingDataUBO();
|
||||||
if (CVS->supportsHardwareSkinning())
|
|
||||||
initSkinningUBO();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_has_been_initialised = true;
|
m_has_been_initialised = true;
|
||||||
|
@ -35,7 +35,8 @@ private:
|
|||||||
static GLuint m_ui_vao;
|
static GLuint m_ui_vao;
|
||||||
static GLuint m_quad_buffer;
|
static GLuint m_quad_buffer;
|
||||||
static GLuint m_quad_vbo;
|
static GLuint m_quad_vbo;
|
||||||
static GLuint m_skinning_ubo;
|
static GLuint m_skinning_tex;
|
||||||
|
static GLuint m_skinning_buf;
|
||||||
static int m_max_mat4_size;
|
static int m_max_mat4_size;
|
||||||
|
|
||||||
static void initQuadVBO();
|
static void initQuadVBO();
|
||||||
@ -44,7 +45,7 @@ private:
|
|||||||
static void initFrustrumVBO();
|
static void initFrustrumVBO();
|
||||||
static void initShadowVPMUBO();
|
static void initShadowVPMUBO();
|
||||||
static void initLightingDataUBO();
|
static void initLightingDataUBO();
|
||||||
static void initSkinningUBO();
|
static void initSkinning();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
@ -104,11 +105,17 @@ public:
|
|||||||
return m_quad_vbo;
|
return m_quad_vbo;
|
||||||
} // getQuadVBO
|
} // getQuadVBO
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static GLuint getSkinningUBO()
|
static GLuint getSkinningTexture()
|
||||||
{
|
{
|
||||||
assert(m_has_been_initialised);
|
assert(m_has_been_initialised);
|
||||||
return m_skinning_ubo;
|
return m_skinning_tex;
|
||||||
} // getSkinningUBO
|
} // getSkinningTex
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
static GLuint getSkinningBuffer()
|
||||||
|
{
|
||||||
|
assert(m_has_been_initialised);
|
||||||
|
return m_skinning_buf;
|
||||||
|
} // getSkinningBuffer
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
static int getMaxMat4Size()
|
static int getMaxMat4Size()
|
||||||
{
|
{
|
||||||
|
@ -378,9 +378,13 @@ void STKAnimatedMesh::uploadJoints(const irr::core::matrix4& m,
|
|||||||
int joint, int offset)
|
int joint, int offset)
|
||||||
{
|
{
|
||||||
assert(offset != -1);
|
assert(offset != -1);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getSkinningUBO());
|
#ifdef USE_GLES2
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, offset + joint * 16 * sizeof(float),
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (offset >> 6) + joint, 16, 1, GL_RGBA,
|
||||||
|
GL_FLOAT, m.pointer());
|
||||||
|
#else
|
||||||
|
glBufferSubData(GL_TEXTURE_BUFFER, offset + joint * 16 * sizeof(float),
|
||||||
16 * sizeof(float), m.pointer());
|
16 * sizeof(float), m.pointer());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !SERVER_ONLY
|
#endif // !SERVER_ONLY
|
||||||
|
@ -193,9 +193,9 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type)
|
|||||||
glEnableVertexAttribArray(4);
|
glEnableVertexAttribArray(4);
|
||||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)44);
|
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)44);
|
||||||
glEnableVertexAttribArray(5);
|
glEnableVertexAttribArray(5);
|
||||||
glVertexAttribIPointer(5, 4, GL_INT, getVertexPitchFromType(type), (GLvoid*)60);
|
glVertexAttribIPointer(5, 4, GL_SHORT, getVertexPitchFromType(type), (GLvoid*)60);
|
||||||
glEnableVertexAttribArray(6);
|
glEnableVertexAttribArray(6);
|
||||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)76);
|
glVertexAttribPointer(6, 4, GL_HALF_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)68);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "Wrong vertex type");
|
assert(0 && "Wrong vertex type");
|
||||||
|
@ -513,6 +513,10 @@ void STKParticle::OnRegisterSceneNode()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scene::SParticle p;
|
scene::SParticle p;
|
||||||
|
p.startTime = 0;
|
||||||
|
p.endTime = 0;
|
||||||
|
p.color = 0;
|
||||||
|
p.startColor = 0;
|
||||||
p.pos = m_particles_generating[i].m_position;
|
p.pos = m_particles_generating[i].m_position;
|
||||||
Buffer->BoundingBox.addInternalPoint(p.pos);
|
Buffer->BoundingBox.addInternalPoint(p.pos);
|
||||||
p.size = core::dimension2df(m_particles_generating[i].m_size,
|
p.size = core::dimension2df(m_particles_generating[i].m_size,
|
||||||
|
@ -177,6 +177,7 @@ public:
|
|||||||
template<int N, typename... TexIds>
|
template<int N, typename... TexIds>
|
||||||
void setTextureUnitsImpl(GLuint tex_id, TexIds... args)
|
void setTextureUnitsImpl(GLuint tex_id, TexIds... args)
|
||||||
{
|
{
|
||||||
|
static_assert(N != 15, "15 is reserved for skinning texture");
|
||||||
#if defined(USE_GLES2)
|
#if defined(USE_GLES2)
|
||||||
if (CVS->getGLSLVersion() >= 300)
|
if (CVS->getGLSLVersion() >= 300)
|
||||||
#else
|
#else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user