Use a non-hardcoded values for mat4 array (max 1024)

Also cull mesh that doesn't have enough space to be rendered
This commit is contained in:
Benau 2016-12-11 15:50:53 +08:00
parent f6490b6fa6
commit e9b68a8a1f
7 changed files with 27 additions and 6 deletions

View File

@ -1,6 +1,5 @@
#ifndef HEADER_TXT
#define HEADER_TXT
#define MAX_BONES 1000
#ifdef UBO_DISABLED
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

View File

@ -1450,7 +1450,7 @@ void CSkinnedMesh::convertForSkinning()
influence = reported_weight[j];
else
{
influence.joint_idx = -1000;
influence.joint_idx = -100000;
influence.weight = remaining_weight;
}
remaining_weight -= influence.weight;

View File

@ -256,6 +256,15 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
{
skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
if (skinning_offset + am->getTotalJoints() >
SharedGPUObjects::getMaxMat4Size())
{
Log::error("DrawCalls", "Don't have enough space to render skinned"
" mesh %s! Max joints can hold: %d",
am->getMeshDebugName().c_str(),
SharedGPUObjects::getMaxMat4Size());
return;
}
m_mesh_for_skinning.insert(am);
am->setSkinningOffset(skinning_offset * 16 * sizeof(float));
}

View File

@ -117,12 +117,13 @@ GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
#else
int range[2], precision;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
if (precision > 0)
code << "precision highp float;\n";
else
code << "precision mediump float;\n";
#endif
code << "#define MAX_BONES " << SharedGPUObjects::getMaxMat4Size() << "\n";
code << getHeader();

View File

@ -21,6 +21,7 @@
#include "graphics/central_settings.hpp"
#include "matrix4.h"
#include <algorithm>
GLuint SharedGPUObjects::m_billboard_vbo;
GLuint SharedGPUObjects::m_sky_tri_vbo;
@ -34,6 +35,7 @@ GLuint SharedGPUObjects::m_ui_vao;
GLuint SharedGPUObjects::m_quad_buffer;
GLuint SharedGPUObjects::m_quad_vbo;
GLuint SharedGPUObjects::m_skinning_ubo;
int SharedGPUObjects::m_max_mat4_size = 1024;
bool SharedGPUObjects::m_has_been_initialised = false;
/** Initialises m_full_screen_quad_vbo.
@ -178,8 +180,11 @@ void SharedGPUObjects::initSkinningUBO()
irr::core::matrix4 m;
glGenBuffers(1, &m_skinning_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, m_skinning_ubo);
glBufferData(GL_UNIFORM_BUFFER, 1000 * 16 * sizeof(float), 0,
GL_STREAM_DRAW);
int max_size = 0;
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
max_size = std::min(max_size, 65536);
m_max_mat4_size = max_size / 16 / sizeof(float);
glBufferData(GL_UNIFORM_BUFFER, max_size, 0, GL_STREAM_DRAW);
// Reserve a identity matrix for non moving mesh in animated model used by
// vertex shader calculation
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * sizeof(float), m.pointer());

View File

@ -38,6 +38,7 @@ private:
static GLuint m_quad_buffer;
static GLuint m_quad_vbo;
static GLuint m_skinning_ubo;
static int m_max_mat4_size;
static void initQuadVBO();
static void initQuadBuffer();
@ -124,7 +125,12 @@ public:
assert(m_has_been_initialised);
return m_skinning_ubo;
} // getSkinningUBO
}; // class SharedGPUObjecctS
// ------------------------------------------------------------------------
static int getMaxMat4Size()
{
return m_max_mat4_size;
} // getMaxMat4Size
}; // class SharedGPUObjects
#endif

View File

@ -91,6 +91,7 @@ public:
virtual void updateGL() = 0;
virtual bool glow() const = 0;
virtual bool isImmediateDraw() const { return false; }
const std::string& getMeshDebugName() const { return m_debug_name; }
}; // STKMeshCommon