Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2017-10-23 09:45:20 +11:00
commit d6251054cb
16 changed files with 160 additions and 255 deletions

View File

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

View File

@ -63,35 +63,17 @@ 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.);
if (Weight[0] < 0.01) for (int i = 0; i < 4; i++)
{ {
skinned_position = idle_position; mat4 joint_matrix = mat4(
skinned_normal = idle_normal; texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4),
skinned_tangent = idle_tangent; texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
skinned_bitangent = idle_bitangent; texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
} texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
else skinned_position += Weight[i] * joint_matrix * idle_position;
{ skinned_normal += Weight[i] * joint_matrix * idle_normal;
for (int i = 0; i < 4; i++) skinned_tangent += Weight[i] * joint_matrix * idle_tangent;
{ skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent;
if (Weight[i] < 0.01)
{
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;
skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent;
}
} }
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position; gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;

View File

@ -45,29 +45,14 @@ 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.);
if (Weight[0] < 0.01) for (int i = 0; i < 4; i++)
{ {
skinned_position = idle_position; mat4 joint_matrix = mat4(
} texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4),
else texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
{ texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
for (int i = 0; i < 4; i++) texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
{ skinned_position += Weight[i] * joint_matrix * idle_position;
if (Weight[i] < 0.01)
{
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;
}
} }
#ifdef VSLayer #ifdef VSLayer

View File

@ -60,41 +60,26 @@ 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.);
if (Weight[0] < 0.01)
for (int i = 0; i < 4; i++)
{ {
skinned_position = idle_position; #ifdef GL_ES
skinned_normal = idle_normal; mat4 joint_matrix = mat4(
skinned_tangent = idle_tangent; texelFetch(skinning_tex, ivec2(0, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
skinned_bitangent = idle_bitangent; texelFetch(skinning_tex, ivec2(1, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
} texelFetch(skinning_tex, ivec2(2, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
else texelFetch(skinning_tex, ivec2(3, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0));
{
for (int i = 0; i < 4; i++)
{
if (Weight[i] < 0.01)
{
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 #else
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3)); texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
#endif #endif
skinned_position += Weight[i] * joint_matrix * idle_position; skinned_position += Weight[i] * joint_matrix * idle_position;
skinned_normal += Weight[i] * joint_matrix * idle_normal; skinned_normal += Weight[i] * joint_matrix * idle_normal;
skinned_tangent += Weight[i] * joint_matrix * idle_tangent; skinned_tangent += Weight[i] * joint_matrix * idle_tangent;
skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent; skinned_bitangent += Weight[i] * joint_matrix * idle_bitangent;
}
} }
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position; gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;

View File

@ -1,7 +1,11 @@
uniform mat4 ModelMatrix; uniform mat4 ModelMatrix;
uniform int skinning_offset; uniform int skinning_offset;
uniform int layer; uniform int layer;
#ifdef GL_ES
uniform sampler2D skinning_tex;
#else
uniform samplerBuffer skinning_tex; 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;
@ -26,35 +30,23 @@ 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.);
if (Weight[0] < 0.01)
for (int i = 0; i < 4; i++)
{ {
skinned_position = idle_position; #ifdef GL_ES
} mat4 joint_matrix = mat4(
else texelFetch(skinning_tex, ivec2(0, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
{ texelFetch(skinning_tex, ivec2(1, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
for (int i = 0; i < 4; i++) texelFetch(skinning_tex, ivec2(2, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0),
{ texelFetch(skinning_tex, ivec2(3, clamp(Joint[i] + skinning_offset, 0, MAX_BONES)), 0));
if (Weight[i] < 0.01)
{
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 #else
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 1),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2), texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 2),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3)); texelFetch(skinning_tex, clamp(Joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3));
#endif #endif
skinned_position += Weight[i] * joint_matrix * idle_position; skinned_position += Weight[i] * joint_matrix * idle_position;
}
} }
#ifdef VSLayer #ifdef VSLayer

View File

@ -1502,8 +1502,8 @@ void CSkinnedMesh::convertForSkinning()
for (u32 j = 0; j < 4; j++) for (u32 j = 0; j < 4; j++)
{ {
JointInfluence influence; JointInfluence influence;
influence.joint_idx = -100000; influence.joint_idx = -32768;
influence.weight = 0.0f; influence.weight = j == 0 ? 1.0f : 0.0f;
this_influence.push_back(influence); this_influence.push_back(influence);
} }
float total_weight = 0.0f; float total_weight = 0.0f;

View File

@ -259,9 +259,9 @@ 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(); skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
if (skinning_offset + am->getTotalJoints() > if (skinning_offset + am->getTotalJoints() >
stk_config->m_max_skinning_bones) (int)stk_config->m_max_skinning_bones)
{ {
Log::error("DrawCalls", "Don't have enough space to render skinned" Log::error("DrawCalls", "Don't have enough space to render skinned"
" mesh %s! Max joints can hold: %d", " mesh %s! Max joints can hold: %d",
@ -685,31 +685,19 @@ 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();
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2 #ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture()); glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
#else #else
glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ? glBindBuffer(GL_TEXTURE_BUFFER, SharedGPUObjects::getSkinningBuffer());
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningBuffer());
#endif #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();
}
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, 0);
#else
glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER, 0);
#endif
}
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();

View File

@ -383,44 +383,28 @@ public:
class SkinnedMeshShader class SkinnedMeshShader
{ {
private: private:
GLuint m_skinning_location; GLuint m_skinning_tex_location;
public: public:
SkinnedMeshShader() : m_skinning_location(0) {} SkinnedMeshShader() : m_skinning_tex_location(0) {}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
template <typename Shader> template <typename Shader>
void init(Shader* s) void init(Shader* s)
{ {
s->use(); s->use();
#ifndef USE_GLES2 m_skinning_tex_location = s->getUniformLocation("skinning_tex");
if (CVS->isARBShaderStorageBufferObjectUsable() && glUniform1i(m_skinning_tex_location, 15);
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() void bindSkinningTexture()
{ {
#ifdef USE_GLES2
glActiveTexture(GL_TEXTURE0 + 15); glActiveTexture(GL_TEXTURE0 + 15);
#ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture()); glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
glBindSampler(15, 0);
#else #else
if (!CVS->isARBShaderStorageBufferObjectUsable()) glBindTexture(GL_TEXTURE_BUFFER,
{ SharedGPUObjects::getSkinningTexture());
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningTexture());
glBindSampler(15, 0);
}
#endif #endif
glBindSampler(15, 0);
} }
}; };

View File

@ -152,6 +152,39 @@ 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)
@ -449,8 +482,6 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
m_draw_calls.setFenceSync();
// Render particles // Render particles
{ {
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
@ -458,6 +489,9 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
renderParticles(); renderParticles();
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
} }
m_draw_calls.setFenceSync();
if (!CVS->isDefferedEnabled() && !forceRTT) if (!CVS->isDefferedEnabled() && !forceRTT)
{ {
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
@ -777,9 +811,11 @@ void ShaderBasedRenderer::render(float dt)
glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_FRAMEBUFFER_SRGB);
#endif #endif
PROFILER_PUSH_CPU_MARKER("Update camera matrices", 0x0, 0xFF, 0x0); PROFILER_PUSH_CPU_MARKER("UBO upload", 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);
@ -886,6 +922,9 @@ 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));

View File

@ -61,6 +61,8 @@ 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);

View File

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

View File

@ -26,7 +26,6 @@
#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"
@ -312,55 +311,6 @@ 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
@ -388,11 +338,12 @@ 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();
memcpy(m_ubo_data, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float)); float tmp[16 * 9 + 2];
memcpy(&m_ubo_data[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float)); memcpy(tmp, irr_driver->getViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&m_ubo_data[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float)); memcpy(&tmp[16], irr_driver->getProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&m_ubo_data[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float)); memcpy(&tmp[32], irr_driver->getInvViewMatrix().pointer(), 16 * sizeof(float));
memcpy(&m_ubo_data[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float)); memcpy(&tmp[48], irr_driver->getInvProjMatrix().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++)
@ -518,23 +469,27 @@ 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(&m_ubo_data[16 * i + 80], memcpy(&tmp[16 * i + 80],
m_sun_ortho_matrices[i].pointer(), m_sun_ortho_matrices[i].pointer(),
16 * sizeof(float)); 16 * sizeof(float));
} }
m_ubo_data[144] = float(width); if(!CVS->isARBUniformBufferObjectUsable())
m_ubo_data[145] = float(height); return;
tmp[144] = float(width);
tmp[145] = float(height);
glBindBuffer(GL_UNIFORM_BUFFER,
SharedGPUObjects::getViewProjectionMatricesUBO());
if (CVS->isSDSMEnabled()) if (CVS->isSDSMEnabled())
{ {
glBindBuffer(GL_UNIFORM_BUFFER, glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 5) * sizeof(float), tmp);
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), &m_ubo_data[144]); 2 * sizeof(float), &tmp[144]);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
} }
else
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float),
tmp);
} // computeMatrixesAndCameras } // computeMatrixesAndCameras
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -49,7 +49,6 @@ 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;
@ -105,7 +104,6 @@ public:
return m_shadow_scales; return m_shadow_scales;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void updateUBO();
}; // class ShadowMatrices }; // class ShadowMatrices

View File

@ -35,6 +35,8 @@ GLuint SharedGPUObjects::m_skinning_tex;
GLuint SharedGPUObjects::m_skinning_buf; GLuint SharedGPUObjects::m_skinning_buf;
bool SharedGPUObjects::m_has_been_initialised = false; bool SharedGPUObjects::m_has_been_initialised = false;
#include "matrix4.h"
/** Initialises m_full_screen_quad_vbo. /** Initialises m_full_screen_quad_vbo.
*/ */
void SharedGPUObjects::initQuadVBO() void SharedGPUObjects::initQuadVBO()
@ -159,6 +161,8 @@ void SharedGPUObjects::initLightingDataUBO()
void SharedGPUObjects::initSkinning() void SharedGPUObjects::initSkinning()
{ {
glGenTextures(1, &m_skinning_tex); glGenTextures(1, &m_skinning_tex);
// Reserve 1 identity matrix for non-weighted vertices
const irr::core::matrix4 m;
int max_size = 0; int max_size = 0;
#ifdef USE_GLES2 #ifdef USE_GLES2
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
@ -180,36 +184,32 @@ void SharedGPUObjects::initSkinning()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16,
stk_config->m_max_skinning_bones, 0, GL_RGBA, GL_FLOAT, NULL); stk_config->m_max_skinning_bones, 0, GL_RGBA, GL_FLOAT, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 1, GL_RGBA, GL_FLOAT,
m.pointer());
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
#else #else
glGenBuffers(1, &m_skinning_buf); glGenBuffers(1, &m_skinning_buf);
const bool ssbo = CVS->isARBShaderStorageBufferObjectUsable(); glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
glGetIntegerv(ssbo ? GL_MAX_SHADER_STORAGE_BLOCK_SIZE :
GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
if (stk_config->m_max_skinning_bones * 64 > (unsigned)max_size) if (stk_config->m_max_skinning_bones * 64 > (unsigned)max_size)
{ {
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d", Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
max_size >> 6); max_size >> 6);
stk_config->m_max_skinning_bones = max_size >> 6; stk_config->m_max_skinning_bones = max_size >> 6;
} }
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: %s, " Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: TBO, "
"max bones: %u", CVS->isARBShaderStorageBufferObjectUsable() ? "max bones: %u", stk_config->m_max_skinning_bones);
"SSBO" : "TBO", stk_config->m_max_skinning_bones);
const GLenum buffer = ssbo ? GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER; glBindBuffer(GL_TEXTURE_BUFFER, m_skinning_buf);
glBindBuffer(buffer, m_skinning_buf); glBufferData(GL_TEXTURE_BUFFER, stk_config->m_max_skinning_bones * 64,
glBufferData(buffer, stk_config->m_max_skinning_bones * 64, NULL, NULL, GL_DYNAMIC_DRAW);
GL_DYNAMIC_DRAW); glBufferSubData(GL_TEXTURE_BUFFER, 0, 16 * sizeof(float), m.pointer());
if (!ssbo) glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex);
{ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf);
glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex); glBindTexture(GL_TEXTURE_BUFFER, 0);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf); glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, 0);
}
glBindBuffer(buffer, 0);
#endif #endif
} // initSkinning } // initSkinning
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -382,9 +382,7 @@ void STKAnimatedMesh::uploadJoints(const irr::core::matrix4& m,
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (offset >> 6) + joint, 16, 1, GL_RGBA, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (offset >> 6) + joint, 16, 1, GL_RGBA,
GL_FLOAT, m.pointer()); GL_FLOAT, m.pointer());
#else #else
glBufferSubData(CVS->isARBShaderStorageBufferObjectUsable() ? glBufferSubData(GL_TEXTURE_BUFFER, offset + joint * 16 * sizeof(float),
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
offset + joint * 16 * sizeof(float),
16 * sizeof(float), m.pointer()); 16 * sizeof(float), m.pointer());
#endif #endif
} }

View File

@ -22,6 +22,7 @@
#include "graphics/gl_headers.hpp" #include "graphics/gl_headers.hpp"
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h" #include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
#include <cassert>
#include <vector> #include <vector>
using namespace irr; using namespace irr;
@ -145,9 +146,14 @@ public:
glDeleteBuffers(1, &m_flips_buffer); glDeleteBuffers(1, &m_flips_buffer);
m_flips_buffer = 0; m_flips_buffer = 0;
} }
m_flips_data.clear();
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
static GLuint getFlipsBuffer() { return m_flips_buffer; } static GLuint getFlipsBuffer()
{
assert(m_flips_buffer != 0);
return m_flips_buffer;
}
}; };
#endif #endif