Clean code to make it extendable later

This commit is contained in:
Vincent Lejeune 2014-03-23 19:50:33 +01:00
parent 5c8ef365a5
commit 76cf04f548
3 changed files with 60 additions and 58 deletions

View File

@ -23,47 +23,45 @@ void STKInstancedSceneNode::createGLMeshes()
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
{ {
glGenVertexArrays(1, &mesh.vao_first_pass); switch (GeoMat)
glBindVertexArray(mesh.vao_first_pass); {
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer); case FPSM_DEFAULT:
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_position); mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_normal); MeshShader::InstancedObjectPass1Shader::attrib_position, -1, -1, MeshShader::InstancedObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_position, 3, GL_FLOAT, GL_FALSE, mesh.Stride, 0); break;
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_normal, 3, GL_FLOAT, GL_FALSE, mesh.Stride, (GLvoid*)12); default:
return;
}
glGenBuffers(1, &instances_vbo); glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_origin); glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_origin, 1); glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_origin, 1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer); switch (ShadedMat)
{
glGenVertexArrays(1, &mesh.vao_second_pass); case SM_DEFAULT:
glBindVertexArray(mesh.vao_second_pass); mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer); break;
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_position); default:
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_texcoord); return;
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_position, 3, GL_FLOAT, GL_FALSE, mesh.Stride, 0); }
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_texcoord, 3, GL_FLOAT, GL_FALSE, mesh.Stride, (GLvoid*)28);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo); glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_origin); glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_origin, 1); glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_origin, 1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer); glBindVertexArray(0);
} }
void STKInstancedSceneNode::setFirstTimeMaterial() void STKInstancedSceneNode::setFirstTimeMaterial()
{ {
if (isMaterialInitialized) if (isMaterialInitialized)
return; return;
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i) for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
@ -74,10 +72,13 @@ void STKInstancedSceneNode::setFirstTimeMaterial()
GLMesh &mesh = GLmeshes[i]; GLMesh &mesh = GLmeshes[i];
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type); GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures); ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
initinstancedvaostate(mesh, GeometricType, ShadedType); initvaostate(mesh, GeometricType, ShadedType);
if (mesh.vao_first_pass)
GeometricMesh[GeometricType].push_back(&mesh);
if (mesh.vao_second_pass)
ShadedMesh[ShadedType].push_back(&mesh);
} }
isMaterialInitialized = true; isMaterialInitialized = true;
printf("instance count : %d\n", instance_pos.size() / 3);
} }
void STKInstancedSceneNode::addWorldMatrix(const core::vector3df &v) void STKInstancedSceneNode::addWorldMatrix(const core::vector3df &v)
@ -87,12 +88,39 @@ void STKInstancedSceneNode::addWorldMatrix(const core::vector3df &v)
instance_pos.push_back(v.Z); instance_pos.push_back(v.Z);
} }
static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::InstancedObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
assert(mesh.vao_second_pass);
glBindVertexArray(mesh.vao_second_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
void STKInstancedSceneNode::render() void STKInstancedSceneNode::render()
{ {
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
setFirstTimeMaterial(); setFirstTimeMaterial();
// AbsoluteTransformation.setTranslation(vector3df(0., 0., 10.)); printf("instance count is %d\n", instance_pos.size() / 3);
// driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{ {
@ -101,19 +129,7 @@ void STKInstancedSceneNode::render()
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program); glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);
for (unsigned i = 0; i < GLmeshes.size(); i++) for (unsigned i = 0; i < GLmeshes.size(); i++)
{ drawFSPMDefault(GLmeshes[i], ModelViewProjectionMatrix, instance_pos.size() / 3);
GLMesh &mesh = GLmeshes[i];
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_pos.size() / 3);
}
return; return;
} }
@ -121,22 +137,7 @@ void STKInstancedSceneNode::render()
{ {
glUseProgram(MeshShader::InstancedObjectPass2Shader::Program); glUseProgram(MeshShader::InstancedObjectPass2Shader::Program);
for (unsigned i = 0; i < GLmeshes.size(); i++) for (unsigned i = 0; i < GLmeshes.size(); i++)
{ drawSMDefault(GLmeshes[i], ModelViewProjectionMatrix, instance_pos.size() / 3);
GLMesh &mesh = GLmeshes[i];
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::InstancedObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
assert(mesh.vao_second_pass);
glBindVertexArray(mesh.vao_second_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_pos.size() / 3);
}
return; return;
} }
} }

View File

@ -6,6 +6,8 @@
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
{ {
protected: protected:
std::vector<GLMesh *> GeometricMesh[FPSM_COUNT];
std::vector<GLMesh *> ShadedMesh[SM_COUNT];
std::vector<GLMesh> GLmeshes; std::vector<GLMesh> GLmeshes;
std::vector<float> instance_pos; std::vector<float> instance_pos;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
@ -23,4 +25,4 @@ public:
void addWorldMatrix(const core::vector3df &); void addWorldMatrix(const core::vector3df &);
}; };
#endif #endif

View File

@ -102,7 +102,6 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t
glVertexAttribPointer(attrib_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (GLvoid*)24); glVertexAttribPointer(attrib_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (GLvoid*)24);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx);
glBindVertexArray(0);
return vao; return vao;
} }