Move instanced rendering code to render_geometry.cpp

Shadows are disabled temporary
This commit is contained in:
Vlj
2014-08-13 04:11:02 +02:00
parent 98bb7e3959
commit ce5d09f159
3 changed files with 169 additions and 240 deletions

View File

@@ -141,6 +141,56 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
}
}
template<int...List>
struct instanced_custom_unroll_args;
template<>
struct instanced_custom_unroll_args<>
{
template<typename T, typename ...TupleTypes, typename ...Args>
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
{
const GLMesh *mesh = STK::tuple_get<0>(t);
size_t instance_count = STK::tuple_get<1>(t);
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh->PrimitiveType;
GLenum itype = mesh->IndexType;
size_t count = mesh->IndexCount;
Shader->setUniforms(args...);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
};
template<int N, int...List>
struct instanced_custom_unroll_args<N, List...>
{
template<typename T, typename ...TupleTypes, typename ...Args>
static void exec(const T *Shader, const STK::Tuple<TupleTypes...> &t, Args... args)
{
instanced_custom_unroll_args<List...>::template exec<T>(Shader, t, STK::tuple_get<N>(t), args...);
}
};
template<typename Shader, int ...List, typename... TupleType>
void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
{
glUseProgram(Shader::getInstance()->Program);
for (unsigned i = 0; i < meshes->size(); i++)
{
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
glBindVertexArray(mesh.vao);
for (unsigned j = 0; j < TexUnits.size(); j++)
{
if (!mesh.textures[j])
mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[j], TexUnits[j].m_premul_alpha);
setTexture(TexUnits[j].m_id, getTextureGLuint(mesh.textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
}
}
void IrrDriver::renderSolidFirstPass()
{
m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).Bind();
@@ -162,6 +212,9 @@ void IrrDriver::renderSolidFirstPass()
ListMatNormalMap::getInstance()->clear();
ListMatGrass::getInstance()->clear();
ListMatSplatting::getInstance()->clear();
ListInstancedMatDefault::getInstance()->clear();
ListInstancedMatAlphaRef::getInstance()->clear();
ListInstancedMatGrass::getInstance()->clear();
m_scene_manager->drawAll(scene::ESNRP_SOLID);
if (!UserConfigParams::m_dynamic_lights)
@@ -182,6 +235,16 @@ void IrrDriver::renderSolidFirstPass()
TexUnit(MeshShader::NormalMapShader::getInstance()->TU_glossy, true),
TexUnit(MeshShader::NormalMapShader::getInstance()->TU_normalmap, false)
), ListMatNormalMap::getInstance());
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader>(
TexUnits(TexUnit(MeshShader::InstancedObjectPass1Shader::getInstance()->TU_tex, true)),
ListInstancedMatDefault::getInstance());
renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader>(
TexUnits(TexUnit(MeshShader::InstancedObjectRefPass1Shader::getInstance()->TU_tex, true)),
ListInstancedMatAlphaRef::getInstance());
renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, 2>(
TexUnits(TexUnit(MeshShader::InstancedGrassPass1Shader::getInstance()->TU_tex, true)),
ListInstancedMatGrass::getInstance());
}
}
@@ -222,6 +285,36 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
}
}
template<typename Shader, int...List, typename... TupleType>
void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > *meshes)
{
glUseProgram(Shader::getInstance()->Program);
for (unsigned i = 0; i < meshes->size(); i++)
{
GLMesh &mesh = *(STK::tuple_get<0>(meshes->at(i)));
glBindVertexArray(mesh.vao);
for (unsigned j = 0; j < TexUnits.size(); j++)
{
if (!mesh.textures[j])
mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[j], TexUnits[j].m_premul_alpha);
setTexture(TexUnits[j].m_id, getTextureGLuint(mesh.textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
{
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
else
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
}
instanced_custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes->at(i));
}
}
void IrrDriver::renderSolidSecondPass()
{
SColor clearColor(0, 150, 150, 150);
@@ -290,6 +383,19 @@ void IrrDriver::renderSolidSecondPass()
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS, 3, 1>(TexUnits(
TexUnit(MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, true)
), ListMatNormalMap::getInstance());
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader>(
TexUnits(TexUnit(MeshShader::InstancedObjectPass2Shader::getInstance()->TU_Albedo, true)),
ListInstancedMatDefault::getInstance());
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader>(
TexUnits(TexUnit(MeshShader::InstancedObjectRefPass2Shader::getInstance()->TU_Albedo, true)),
ListInstancedMatAlphaRef::getInstance());
setTexture(MeshShader::InstancedGrassPass2Shader::getInstance()->TU_dtex,
irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, 3, 2>(
TexUnits(TexUnit(MeshShader::InstancedGrassPass2Shader::getInstance()->TU_Albedo, true)),
ListInstancedMatGrass::getInstance());
}
}
@@ -503,6 +609,52 @@ void renderShadow(const std::vector<GLuint> TextureUnits, const std::vector<STK:
}
}
static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::InstancedShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedRefShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedRefShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
static void drawShadowGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedGrassShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedGrassShadowShader::getInstance()->setUniforms(windDir);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
template<int...List>
struct rsm_custom_unroll_args;

View File

@@ -140,188 +140,6 @@ core::matrix4 STKInstancedSceneNode::getInstanceTransform(int id)
return mat;
}
static void drawFSPMDefault(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (mesh.textures[0])
{
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedObjectPass1Shader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
else
{
setTexture(MeshShader::InstancedObjectPass1Shader::getInstance()->TU_tex, 0, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, false);
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
MeshShader::InstancedObjectPass1Shader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
if (!mesh.textures[0])
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
}
static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::InstancedShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
static void drawFSPMAlphaRefTexture(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedObjectRefPass1Shader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectRefPass1Shader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedRefShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedRefShadowShader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
static void drawShadowGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedGrassShadowShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedGrassShadowShader::getInstance()->setUniforms(windDir);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, 4 * instance_count);
}
static void drawFSPMGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedGrassPass1Shader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedGrassPass1Shader::getInstance()->setUniforms(windDir);
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMDefault(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::InstancedObjectPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
{
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
else
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
MeshShader::InstancedObjectPass2Shader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMAlphaRefTexture(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedObjectRefPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
{
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
else
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
MeshShader::InstancedObjectRefPass2Shader::getInstance()->setUniforms();
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::InstancedGrassPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
{
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
else
{
GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
setTexture(MeshShader::InstancedGrassPass2Shader::getInstance()->TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
MeshShader::InstancedGrassPass2Shader::getInstance()->setUniforms(windDir, cb->getPosition());
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
void STKInstancedSceneNode::render()
{
if (!irr_driver->isGLSL())
@@ -332,64 +150,14 @@ void STKInstancedSceneNode::render()
setFirstTimeMaterial();
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
ModelViewProjectionMatrix = irr_driver->getProjMatrix();
ModelViewProjectionMatrix *= irr_driver->getViewMatrix();
for (auto mesh : MeshSolidMaterial[MAT_DEFAULT])
ListInstancedMatDefault::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
if (!MeshSolidMaterial[MAT_DEFAULT].empty())
glUseProgram(MeshShader::InstancedObjectPass1Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
drawFSPMDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9);
for (auto mesh : MeshSolidMaterial[MAT_ALPHA_REF])
ListInstancedMatAlphaRef::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9));
if (!MeshSolidMaterial[MAT_ALPHA_REF].empty())
glUseProgram(MeshShader::InstancedObjectRefPass1Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
drawFSPMAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9);
windDir = getWind();
if (!MeshSolidMaterial[MAT_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassPass1Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
drawFSPMGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9);
return;
}
if (irr_driver->getPhase() == SOLID_LIT_PASS)
{
if (!MeshSolidMaterial[MAT_DEFAULT].empty())
glUseProgram(MeshShader::InstancedObjectPass2Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
drawSMDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_ALPHA_REF].empty())
glUseProgram(MeshShader::InstancedObjectRefPass2Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
drawSMAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassPass2Shader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
drawSMGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9);
return;
}
if (irr_driver->getPhase() == SHADOW_PASS)
{
if (!MeshSolidMaterial[MAT_DEFAULT].empty())
glUseProgram(MeshShader::InstancedShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++)
drawShadowDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_ALPHA_REF].empty())
glUseProgram(MeshShader::InstancedRefShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++)
drawShadowAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9);
if (!MeshSolidMaterial[MAT_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassShadowShader::getInstance()->Program);
for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++)
drawShadowGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9);
return;
}
windDir = getWind();
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
for (auto mesh : MeshSolidMaterial[MAT_GRASS])
ListInstancedMatGrass::getInstance()->push_back(STK::make_tuple(mesh, instance_pos.size() / 9, windDir, cb->getPosition()));
}

View File

@@ -4,6 +4,15 @@
#include "stkmesh.hpp"
#include "utils/leak_check.hpp"
class ListInstancedMatDefault : public MeshList<ListInstancedMatDefault, GLMesh *, size_t>
{};
class ListInstancedMatAlphaRef : public MeshList<ListInstancedMatAlphaRef, GLMesh *, size_t>
{};
class ListInstancedMatGrass : public MeshList<ListInstancedMatGrass, GLMesh *, size_t, core::vector3df, core::vector3df>
{};
class STKInstancedSceneNode : public irr::scene::CMeshSceneNode
{
protected: