Allow using SSBO for skinning if supported

This commit is contained in:
Benau 2017-10-20 01:27:44 +08:00
parent 0d96906d54
commit 553b2439ac
10 changed files with 84 additions and 27 deletions

View File

@ -64,10 +64,12 @@ layout (std140) uniform LightingData
float rL22;
};
layout (std140) uniform SkinningData
#ifdef SSBO_SKINNING
layout (std140, binding = 0) readonly buffer SkinningData
{
mat4 joint_matrices[MAX_BONES];
};
#endif
#endif
#endif // HEADER_TXT

View File

@ -78,11 +78,15 @@ void main(void)
{
break;
}
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#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;

View File

@ -57,11 +57,15 @@ void main(void)
{
break;
}
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#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;
}
}

View File

@ -75,7 +75,9 @@ void main(void)
{
break;
}
#ifdef GL_ES
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#elif defined(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),

View File

@ -38,11 +38,21 @@ void main(void)
{
break;
}
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#elif defined(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;
}
}

View File

@ -685,19 +685,30 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
shadow_matrices.updateUBO();
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
#else
glBindBuffer(GL_TEXTURE_BUFFER, SharedGPUObjects::getSkinningBuffer());
glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningBuffer());
#endif
}
for (unsigned i = 0; i < m_deferred_update.size(); i++)
{
m_deferred_update[i]->updateGL();
PROFILER_POP_CPU_MARKER();
}
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_2D, 0);
#else
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER, 0);
#endif
}
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- cpu particle upload", 0x3F, 0x03, 0x61);
CPUParticleManager::getInstance()->uploadAll();

View File

@ -146,9 +146,8 @@ private:
/** End of recursive implementation of assignUniforms. */
void assignUniformsImpl()
{
bindPoint("MatrixData", 0);
bindPoint("MatrixesData", 0);
bindPoint("LightingData", 1);
bindPoint("SkinningData", 2);
} // assignUniformsImpl
// ------------------------------------------------------------------------
@ -384,28 +383,44 @@ public:
class SkinnedMeshShader
{
private:
GLuint m_skinning_tex_location;
GLuint m_skinning_location;
public:
SkinnedMeshShader() : m_skinning_tex_location(0) {}
SkinnedMeshShader() : m_skinning_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);
#ifndef USE_GLES2
if (CVS->isARBShaderStorageBufferObjectUsable() &&
CVS->supportsHardwareSkinning())
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0,
SharedGPUObjects::getSkinningBuffer());
}
else
#endif
{
m_skinning_location = s->getUniformLocation("skinning_tex");
glUniform1i(m_skinning_location, 15);
}
}
// ------------------------------------------------------------------------
void bindSkinningTexture()
{
glActiveTexture(GL_TEXTURE0 + 15);
#ifdef USE_GLES2
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
#else
glBindTexture(GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningTexture());
#endif
glBindSampler(15, 0);
#else
if (!CVS->isARBShaderStorageBufferObjectUsable())
{
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningTexture());
glBindSampler(15, 0);
}
#endif
}
};

View File

@ -170,7 +170,9 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
code << "#define Advanced_Lighting_Enabled\n";
if (CVS->isARBSRGBFramebufferUsable())
code << "#define sRGB_Framebuffer_Usable\n";
if (CVS->isARBShaderStorageBufferObjectUsable() &&
CVS->supportsHardwareSkinning())
code << "#define SSBO_SKINNING\n";
#if !defined(USE_GLES2)
// shader compilation fails with some drivers if there is no precision
// qualifier

View File

@ -174,14 +174,19 @@ void SharedGPUObjects::initSkinning()
glBindTexture(GL_TEXTURE_2D, 0);
#else
glGenBuffers(1, &m_skinning_buf);
glBindBuffer(GL_TEXTURE_BUFFER, m_skinning_buf);
glBufferData(GL_TEXTURE_BUFFER, 65536, NULL, GL_DYNAMIC_DRAW);
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);
const bool ssbo = CVS->isARBShaderStorageBufferObjectUsable();
const GLenum buffer = ssbo ? GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER;
glBindBuffer(buffer, m_skinning_buf);
glBufferData(buffer, 65536, NULL, GL_DYNAMIC_DRAW);
if (!ssbo)
{
glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf);
glBindTexture(GL_TEXTURE_BUFFER, 0);
}
glBindBuffer(buffer, 0);
#endif
} // initSkinningTBO
} // initSkinning
// ----------------------------------------------------------------------------
void SharedGPUObjects::init()

View File

@ -382,7 +382,9 @@ void STKAnimatedMesh::uploadJoints(const irr::core::matrix4& m,
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),
glBufferSubData(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
offset + joint * 16 * sizeof(float),
16 * sizeof(float), m.pointer());
#endif
}