Batch draw calls
This commit is contained in:
parent
4eb4ce1511
commit
cf2035ca0a
@ -745,7 +745,7 @@ bool CIrrDeviceLinux::createWindow()
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||
// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||
None
|
||||
};
|
||||
|
@ -23,72 +23,52 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
|
||||
{
|
||||
firstTime = true;
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < FPSM_COUNT; i++)
|
||||
GeometricMesh[i].clear();
|
||||
for (unsigned i = 0; i < SM_COUNT; i++)
|
||||
ShadedMesh[i].clear();
|
||||
CAnimatedMeshSceneNode::setMesh(mesh);
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void STKAnimatedMesh::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type)
|
||||
{
|
||||
assert(irr_driver->getPhase() == TRANSPARENT_PASS);
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
|
||||
if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
|
||||
return;
|
||||
switch (type)
|
||||
{
|
||||
case FPSM_ALPHA_REF_TEXTURE:
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix);
|
||||
break;
|
||||
case FPSM_DEFAULT:
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Wrong geometric material");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void STKAnimatedMesh::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type)
|
||||
{
|
||||
switch (irr_driver->getPhase())
|
||||
{
|
||||
case SOLID_NORMAL_AND_DEPTH_PASS:
|
||||
{
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix);
|
||||
else
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
}
|
||||
case SOLID_LIT_PASS:
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
else if (mesh.textures[1])
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
else
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0 && "wrong pass");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::drawShadow(const GLMesh &mesh)
|
||||
{
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
assert(irr_driver->getPhase() == SHADOW_PASS);
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
MeshShader::ShadowShader::setUniforms(ShadowMVP);
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
switch (type)
|
||||
{
|
||||
case SM_ALPHA_REF_TEXTURE:
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix);
|
||||
break;
|
||||
case SM_RIMLIT:
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix);
|
||||
break;
|
||||
case SM_UNLIT:
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_DETAILS:
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_DEFAULT:
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Wrong shaded material");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::render()
|
||||
@ -114,54 +94,142 @@ void STKAnimatedMesh::render()
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
if (firstTime)
|
||||
for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
if (firstTime)
|
||||
{
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
if (!isObject(type))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (animated) material type : %d", type);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
if (rnd->isTransparent())
|
||||
{
|
||||
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type);
|
||||
initvaostate(mesh, TranspMat);
|
||||
TransparentMesh[TranspMat].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
|
||||
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
|
||||
initvaostate(mesh, GeometricType, ShadedType);
|
||||
GeometricMesh[GeometricType].push_back(&mesh);
|
||||
ShadedMesh[ShadedType].push_back(&mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
|
||||
// render original meshes
|
||||
for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (transparent != isTransparentPass)
|
||||
continue;
|
||||
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
|
||||
TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
if (RenderFromIdentity)
|
||||
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
else if (Mesh->getMeshType() == scene::EAMT_SKINNED)
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation);
|
||||
for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
if (isObject(material.MaterialType))
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
|
||||
}
|
||||
if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
drawShadow(GLmeshes[i]);
|
||||
else if (isTransparentPass)
|
||||
drawTransparent(GLmeshes[i], material.MaterialType);
|
||||
else
|
||||
drawSolid(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (animated) material type : %d", material.MaterialType);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
|
||||
}
|
||||
}
|
||||
if (mb)
|
||||
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (transparent != isTransparentPass)
|
||||
continue;
|
||||
|
||||
if (RenderFromIdentity)
|
||||
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
else if (Mesh->getMeshType() == scene::EAMT_SKINNED)
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation);
|
||||
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
|
||||
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_DEFAULT][i], FPSM_DEFAULT);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], FPSM_ALPHA_REF_TEXTURE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||
{
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_DEFAULT][i], SM_DEFAULT);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], SM_ALPHA_REF_TEXTURE);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_RIMLIT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_RIMLIT][i], SM_RIMLIT);
|
||||
|
||||
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_UNLIT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_UNLIT][i], SM_UNLIT);
|
||||
|
||||
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_DETAILS].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_DETAILS][i], SM_DETAILS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawShadow(*GeometricMesh[FPSM_DEFAULT][i]);
|
||||
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
{
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
for (unsigned i = 0; i < TransparentMesh[TM_BUBBLE].size(); i++)
|
||||
drawBubble(*TransparentMesh[TM_BUBBLE][i], ModelViewProjectionMatrix);
|
||||
|
||||
glUseProgram(MeshShader::TransparentShader::Program);
|
||||
for (unsigned i = 0; i < TransparentMesh[TM_DEFAULT].size(); i++)
|
||||
drawTransparentObject(*TransparentMesh[TM_DEFAULT][i], ModelViewProjectionMatrix, (*TransparentMesh[TM_DEFAULT][i]).TextureMatrix);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,13 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
bool firstTime;
|
||||
std::vector<GLMesh *> GeometricMesh[FPSM_COUNT];
|
||||
std::vector<GLMesh *> ShadedMesh[SM_COUNT];
|
||||
std::vector<GLMesh *> TransparentMesh[TM_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix;
|
||||
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawShadow(const GLMesh &mesh);
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||
void drawSolidPass1(const GLMesh &mesh, GeometricMaterial type);
|
||||
void drawSolidPass2(const GLMesh &mesh, ShadedMaterial type);
|
||||
public:
|
||||
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
|
||||
irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
|
@ -9,6 +9,49 @@
|
||||
#include "graphics/camera.hpp"
|
||||
#include "modes/world.hpp"
|
||||
|
||||
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE MaterialType)
|
||||
{
|
||||
if (MaterialType == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
return FPSM_NORMAL_MAP;
|
||||
else if (MaterialType == irr_driver->getShader(ES_OBJECTPASS_REF) || MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
|
||||
return FPSM_ALPHA_REF_TEXTURE;
|
||||
else if (MaterialType == irr_driver->getShader(ES_GRASS) || MaterialType == irr_driver->getShader(ES_GRASS_REF))
|
||||
return FPSM_GRASS;
|
||||
else
|
||||
return FPSM_DEFAULT;
|
||||
}
|
||||
|
||||
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, GLuint *textures)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
return SM_SPHEREMAP;
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
return SM_SPLATTING;
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF) || type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
|
||||
return SM_ALPHA_REF_TEXTURE;
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
return SM_RIMLIT;
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
return SM_GRASS;
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
return SM_UNLIT;
|
||||
else if (type == irr_driver->getShader(ES_CAUSTICS))
|
||||
return SM_CAUSTICS;
|
||||
else if (textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP))
|
||||
return SM_DETAILS;
|
||||
else if (!textures[0])
|
||||
return SM_UNTEXTURED;
|
||||
else
|
||||
return SM_DEFAULT;
|
||||
}
|
||||
|
||||
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
return TM_BUBBLE;
|
||||
else
|
||||
return TM_DEFAULT;
|
||||
}
|
||||
|
||||
GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, GLuint attrib_color, size_t stride)
|
||||
{
|
||||
@ -141,6 +184,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
else
|
||||
result.textures[i] = 0;
|
||||
}
|
||||
result.TextureMatrix = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -162,11 +206,11 @@ void computeTIMV(core::matrix4 &TransposeInverseModelView)
|
||||
|
||||
void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
||||
MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
@ -175,6 +219,7 @@ void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjecti
|
||||
|
||||
void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -182,7 +227,6 @@ void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProje
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
||||
MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
@ -191,13 +235,13 @@ void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProje
|
||||
|
||||
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
glUseProgram(MeshShader::GrassPass1Shader::Program);
|
||||
MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, windDir, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
@ -206,6 +250,7 @@ void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
|
||||
void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -213,7 +258,6 @@ void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
assert(mesh.textures[1]);
|
||||
setTexture(0, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
glUseProgram(MeshShader::NormalMapShader::Program);
|
||||
MeshShader::NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
@ -222,6 +266,7 @@ void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
|
||||
void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -234,12 +279,11 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::SphereMapShader::Program);
|
||||
MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -253,6 +297,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
|
||||
|
||||
void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -331,7 +376,6 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::SplattingShader::Program);
|
||||
MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -340,6 +384,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM
|
||||
|
||||
void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -364,7 +409,6 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
|
||||
MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -373,6 +417,7 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec
|
||||
|
||||
void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector2df dir, core::vector2df dir2)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -398,8 +443,6 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
|
||||
glUseProgram(MeshShader::CausticsShader::Program);
|
||||
MeshShader::CausticsShader::setUniforms(ModelViewProjectionMatrix, dir, dir2, core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 2, 3, 4, 1);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -408,6 +451,7 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM
|
||||
|
||||
void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -432,7 +476,6 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::GrassPass2Shader::Program);
|
||||
MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir, 0, 1, 2, 3);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -441,6 +484,7 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
|
||||
void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -453,9 +497,7 @@ void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProj
|
||||
GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE};
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
|
||||
glUseProgram(MeshShader::UntexturedObjectShader::Program);
|
||||
MeshShader::UntexturedObjectShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -464,6 +506,7 @@ void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProj
|
||||
|
||||
void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -489,7 +532,6 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
|
||||
MeshShader::ObjectRimLimitShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0, 1, 2, 3);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -498,6 +540,7 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec
|
||||
|
||||
void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -514,8 +557,6 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
|
||||
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
||||
MeshShader::ObjectUnlitShader::setUniforms(ModelViewProjectionMatrix, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -524,6 +565,7 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio
|
||||
|
||||
void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -551,7 +593,6 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
|
||||
MeshShader::DetailledObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -560,6 +601,7 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView
|
||||
|
||||
void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -585,7 +627,6 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
}
|
||||
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::Program);
|
||||
MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
@ -594,13 +635,13 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio
|
||||
|
||||
void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
glUseProgram(MeshShader::TransparentShader::Program);
|
||||
MeshShader::TransparentShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
@ -609,6 +650,7 @@ void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewPro
|
||||
|
||||
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
@ -638,6 +680,7 @@ void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelView
|
||||
|
||||
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
float transparency = 1.;
|
||||
|
||||
@ -647,13 +690,54 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
MeshShader::BubbleShader::setUniforms(ModelViewProjectionMatrix, 0, time, transparency);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void drawShadowRef(const GLMesh &mesh)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void drawShadow(const GLMesh &mesh)
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
/* if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::GrassShadowShader::Program);
|
||||
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
|
||||
}*/
|
||||
|
||||
MeshShader::ShadowShader::setUniforms(ShadowMVP);
|
||||
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
bool isObject(video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
@ -684,137 +768,119 @@ bool isObject(video::E_MATERIAL_TYPE type)
|
||||
return true;
|
||||
if (type == video::EMT_TRANSPARENT_ADD_COLOR)
|
||||
return true;
|
||||
if (type == video::EMT_SOLID)
|
||||
return true;
|
||||
if (type == video::EMT_LIGHTMAP_LIGHTING)
|
||||
return true;
|
||||
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
|
||||
{
|
||||
switch (irr_driver->getPhase())
|
||||
{
|
||||
case SOLID_NORMAL_AND_DEPTH_PASS:
|
||||
if (mesh.vao_first_pass)
|
||||
return;
|
||||
if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
return;
|
||||
case SOLID_LIT_PASS:
|
||||
if (mesh.vao_second_pass)
|
||||
return;
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectRimLimitShader::attrib_position, MeshShader::ObjectRimLimitShader::attrib_texcoord, -1, MeshShader::ObjectRimLimitShader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectUnlitShader::attrib_position, MeshShader::ObjectUnlitShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_CAUSTICS))
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::CausticsShader::attrib_position, MeshShader::CausticsShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (mesh.textures[1])
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::DetailledObjectPass2Shader::attrib_position, MeshShader::DetailledObjectPass2Shader::attrib_texcoord, MeshShader::DetailledObjectPass2Shader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (!mesh.textures[0])
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::UntexturedObjectShader::attrib_position, -1, -1, -1, -1, -1, MeshShader::UntexturedObjectShader::attrib_color, mesh.Stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
return;
|
||||
case GLOW_PASS:
|
||||
if (mesh.vao_glow_pass)
|
||||
return;
|
||||
mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
return;
|
||||
case TRANSPARENT_PASS:
|
||||
if (mesh.vao_first_pass)
|
||||
return;
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::BubbleShader::attrib_position, MeshShader::BubbleShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::TransparentShader::attrib_position, MeshShader::TransparentShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
return;
|
||||
case DISPLACEMENT_PASS:
|
||||
if (mesh.vao_displace_pass)
|
||||
return;
|
||||
mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position,-1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
return;
|
||||
case SHADOW_PASS:
|
||||
if (mesh.vao_shadow_pass)
|
||||
return;
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
{
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::RefShadowShader::attrib_position, MeshShader::RefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
/*else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::GrassShadowShader::attrib_position, MeshShader::GrassShadowShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassShadowShader::attrib_color, mesh.Stride);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (GeoMat)
|
||||
{
|
||||
case FPSM_DEFAULT:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case FPSM_ALPHA_REF_TEXTURE:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectRefPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectRefPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::RefShadowShader::attrib_position, MeshShader::RefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case FPSM_NORMAL_MAP:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, -1, mesh.Stride);
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case FPSM_GRASS:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride);
|
||||
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::GrassShadowShader::attrib_position, MeshShader::GrassShadowShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassShadowShader::attrib_color, mesh.Stride);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unknow material");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ShadedMat)
|
||||
{
|
||||
case SM_SPHEREMAP:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_SPLATTING:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_ALPHA_REF_TEXTURE:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_RIMLIT:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectRimLimitShader::attrib_position, MeshShader::ObjectRimLimitShader::attrib_texcoord, -1, MeshShader::ObjectRimLimitShader::attrib_normal, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_GRASS:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride);
|
||||
break;
|
||||
case SM_UNLIT:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectUnlitShader::attrib_position, MeshShader::ObjectUnlitShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_CAUSTICS:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::CausticsShader::attrib_position, MeshShader::CausticsShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_DETAILS:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::DetailledObjectPass2Shader::attrib_position, MeshShader::DetailledObjectPass2Shader::attrib_texcoord, MeshShader::DetailledObjectPass2Shader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case SM_UNTEXTURED:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::UntexturedObjectShader::attrib_position, -1, -1, -1, -1, -1, MeshShader::UntexturedObjectShader::attrib_color, mesh.Stride);
|
||||
break;
|
||||
case SM_DEFAULT:
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "unknow shaded material");
|
||||
break;
|
||||
}
|
||||
|
||||
mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
if (mesh.Stride >= 44)
|
||||
mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
|
||||
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat)
|
||||
{
|
||||
switch (TranspMat)
|
||||
{
|
||||
case TM_BUBBLE:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::BubbleShader::attrib_position, MeshShader::BubbleShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
case TM_DEFAULT:
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::TransparentShader::attrib_position, MeshShader::TransparentShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
break;
|
||||
}
|
||||
mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
if (mesh.Stride >= 44)
|
||||
mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride);
|
||||
|
||||
/*
|
||||
else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
|
||||
}*/
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,37 @@
|
||||
#include "glwrap.hpp"
|
||||
#include <vector>
|
||||
|
||||
enum GeometricMaterial
|
||||
{
|
||||
FPSM_DEFAULT,
|
||||
FPSM_ALPHA_REF_TEXTURE,
|
||||
FPSM_NORMAL_MAP,
|
||||
FPSM_GRASS,
|
||||
FPSM_COUNT
|
||||
};
|
||||
|
||||
enum ShadedMaterial
|
||||
{
|
||||
SM_DEFAULT,
|
||||
SM_ALPHA_REF_TEXTURE,
|
||||
SM_RIMLIT,
|
||||
SM_SPHEREMAP,
|
||||
SM_SPLATTING,
|
||||
SM_GRASS,
|
||||
SM_UNLIT,
|
||||
SM_CAUSTICS,
|
||||
SM_DETAILS,
|
||||
SM_UNTEXTURED,
|
||||
SM_COUNT
|
||||
};
|
||||
|
||||
enum TransparentMaterial
|
||||
{
|
||||
TM_DEFAULT,
|
||||
TM_BUBBLE,
|
||||
TM_COUNT
|
||||
};
|
||||
|
||||
struct GLMesh {
|
||||
GLuint vao_first_pass;
|
||||
GLuint vao_second_pass;
|
||||
@ -22,11 +53,13 @@ struct GLMesh {
|
||||
GLenum IndexType;
|
||||
size_t IndexCount;
|
||||
size_t Stride;
|
||||
core::matrix4 TextureMatrix;
|
||||
};
|
||||
|
||||
GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, GLuint attrib_color, size_t stride);
|
||||
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
|
||||
void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
|
||||
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat);
|
||||
void computeMVP(core::matrix4 &ModelViewProjectionMatrix);
|
||||
void computeTIMV(core::matrix4 &TransposeInverseModelView);
|
||||
bool isObject(video::E_MATERIAL_TYPE type);
|
||||
@ -49,9 +82,17 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
|
||||
void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix);
|
||||
void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
|
||||
|
||||
// Shadow pass
|
||||
void drawShadowRef(const GLMesh &mesh);
|
||||
void drawShadow(const GLMesh &mesh);
|
||||
|
||||
// Forward pass (for transparents meshes)
|
||||
void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
|
||||
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
|
||||
|
||||
#endif // STKMESH_H
|
||||
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE);
|
||||
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE, GLuint *textures);
|
||||
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE);
|
||||
|
||||
#endif // STKMESH_H
|
||||
|
@ -42,6 +42,46 @@ void STKMeshSceneNode::createGLMeshes()
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
GLmeshes.push_back(allocateMeshBuffer(mb));
|
||||
}
|
||||
isMaterialInitialized = false;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setFirstTimeMaterial()
|
||||
{
|
||||
if (isMaterialInitialized)
|
||||
return;
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
if (!isObject(type))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", type);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
GLMesh &mesh = GLmeshes[i];
|
||||
if (rnd->isTransparent())
|
||||
{
|
||||
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type);
|
||||
initvaostate(mesh, TranspMat);
|
||||
TransparentMesh[TranspMat].push_back(&mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
|
||||
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
|
||||
initvaostate(mesh, GeometricType, ShadedType);
|
||||
GeometricMesh[GeometricType].push_back(&mesh);
|
||||
ShadedMesh[ShadedType].push_back(&mesh);
|
||||
}
|
||||
}
|
||||
isMaterialInitialized = true;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::cleanGLMeshes()
|
||||
@ -63,6 +103,10 @@ void STKMeshSceneNode::cleanGLMeshes()
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < FPSM_COUNT; i++)
|
||||
GeometricMesh[i].clear();
|
||||
for (unsigned i = 0; i < SM_COUNT; i++)
|
||||
ShadedMesh[i].clear();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
|
||||
@ -86,7 +130,6 @@ void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
glUseProgram(MeshShader::ColorizeShader::Program);
|
||||
MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, cb->getRed(), cb->getGreen(), cb->getBlue());
|
||||
|
||||
glBindVertexArray(mesh.vao_glow_pass);
|
||||
@ -135,114 +178,92 @@ void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYP
|
||||
|
||||
if (type == irr_driver->getShader(ES_BUBBLES))
|
||||
drawBubble(mesh, ModelViewProjectionMatrix);
|
||||
else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
// else if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
// drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else
|
||||
drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
drawTransparentObject(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix);
|
||||
return;
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void STKMeshSceneNode::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type)
|
||||
{
|
||||
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
|
||||
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
|
||||
for (unsigned i = 0; i < ShadowMVP.size(); i++)
|
||||
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
irr_driver->IncreaseObjectCount();
|
||||
windDir = getWind();
|
||||
switch (type)
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0);
|
||||
case FPSM_NORMAL_MAP:
|
||||
drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
case FPSM_ALPHA_REF_TEXTURE:
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix);
|
||||
break;
|
||||
case FPSM_GRASS:
|
||||
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
|
||||
break;
|
||||
case FPSM_DEFAULT:
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "wrong geometric material");
|
||||
}
|
||||
/* else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
{
|
||||
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
|
||||
glUseProgram(MeshShader::GrassShadowShader::Program);
|
||||
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
|
||||
}*/
|
||||
else
|
||||
{
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
MeshShader::ShadowShader::setUniforms(ShadowMVP);
|
||||
}
|
||||
glBindVertexArray(mesh.vao_shadow_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void STKMeshSceneNode::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type)
|
||||
{
|
||||
switch (irr_driver->getPhase())
|
||||
switch (type)
|
||||
{
|
||||
case SOLID_NORMAL_AND_DEPTH_PASS:
|
||||
case SM_SPHEREMAP:
|
||||
drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
break;
|
||||
case SM_SPLATTING:
|
||||
drawSplatting(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_ALPHA_REF_TEXTURE:
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix);
|
||||
break;
|
||||
case SM_GRASS:
|
||||
drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir);
|
||||
break;
|
||||
case SM_RIMLIT:
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, core::matrix4::EM4CONST_IDENTITY);
|
||||
break;
|
||||
case SM_UNLIT:
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_CAUSTICS:
|
||||
{
|
||||
windDir = getWind();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getCausticsSpeed();
|
||||
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f;
|
||||
|
||||
if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
|
||||
else
|
||||
drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
caustic_dir.X += wind.X;
|
||||
caustic_dir.Y += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
caustic_dir2.X += wind.X;
|
||||
caustic_dir2.Y += wind.Z;
|
||||
drawCaustics(mesh, ModelViewProjectionMatrix, caustic_dir, caustic_dir2);
|
||||
break;
|
||||
}
|
||||
case SOLID_LIT_PASS:
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_SPHERE_MAP))
|
||||
drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView);
|
||||
else if (type == irr_driver->getShader(ES_SPLATTING))
|
||||
drawSplatting(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_REF))
|
||||
drawObjectRefPass2(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
|
||||
drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir);
|
||||
else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT))
|
||||
drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix);
|
||||
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
|
||||
drawObjectUnlit(mesh, ModelViewProjectionMatrix);
|
||||
else if (type == irr_driver->getShader(ES_CAUSTICS))
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getCausticsSpeed();
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f;
|
||||
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
caustic_dir.X += wind.X;
|
||||
caustic_dir.Y += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
caustic_dir2.X += wind.X;
|
||||
caustic_dir2.Y += wind.Z;
|
||||
drawCaustics(mesh, ModelViewProjectionMatrix, caustic_dir, caustic_dir2);
|
||||
}
|
||||
else if (mesh.textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
else if (!mesh.textures[0])
|
||||
drawUntexturedObject(mesh, ModelViewProjectionMatrix);
|
||||
else
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix, TextureMatrix);
|
||||
case SM_DETAILS:
|
||||
drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_UNTEXTURED:
|
||||
drawUntexturedObject(mesh, ModelViewProjectionMatrix);
|
||||
break;
|
||||
case SM_DEFAULT:
|
||||
drawObjectPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0 && "wrong pass");
|
||||
}
|
||||
assert(0 && "Wrong shaded material");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,54 +282,131 @@ void STKMeshSceneNode::render()
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
Box = Mesh->getBoundingBox();
|
||||
|
||||
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
|
||||
setFirstTimeMaterial();
|
||||
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (mb)
|
||||
if (!mb)
|
||||
continue;
|
||||
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
|
||||
{
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
computeTIMV(TransposeInverseModelView);
|
||||
|
||||
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_DEFAULT][i], FPSM_DEFAULT);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], FPSM_ALPHA_REF_TEXTURE);
|
||||
|
||||
glUseProgram(MeshShader::NormalMapShader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_NORMAL_MAP].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_NORMAL_MAP][i], FPSM_NORMAL_MAP);
|
||||
|
||||
glUseProgram(MeshShader::GrassPass1Shader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++)
|
||||
drawSolidPass1(*GeometricMesh[FPSM_GRASS][i], FPSM_GRASS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SOLID_LIT_PASS)
|
||||
{
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_DEFAULT][i], SM_DEFAULT);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], SM_ALPHA_REF_TEXTURE);
|
||||
|
||||
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_RIMLIT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_RIMLIT][i], SM_RIMLIT);
|
||||
|
||||
glUseProgram(MeshShader::SphereMapShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_SPHEREMAP].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_SPHEREMAP][i], SM_SPHEREMAP);
|
||||
|
||||
glUseProgram(MeshShader::SplattingShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_SPLATTING].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_SPLATTING][i], SM_SPLATTING);
|
||||
|
||||
glUseProgram(MeshShader::GrassPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_GRASS][i], SM_GRASS);
|
||||
|
||||
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_UNLIT].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_UNLIT][i], SM_UNLIT);
|
||||
|
||||
glUseProgram(MeshShader::CausticsShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_CAUSTICS].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_CAUSTICS][i], SM_CAUSTICS);
|
||||
|
||||
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_DETAILS].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_DETAILS][i], SM_DETAILS);
|
||||
|
||||
glUseProgram(MeshShader::UntexturedObjectShader::Program);
|
||||
for (unsigned i = 0; i < ShadedMesh[SM_UNTEXTURED].size(); i++)
|
||||
drawSolidPass2(*ShadedMesh[SM_UNTEXTURED][i], SM_UNTEXTURED);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
glUseProgram(MeshShader::ShadowShader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
|
||||
drawShadow(*GeometricMesh[FPSM_DEFAULT][i]);
|
||||
|
||||
glUseProgram(MeshShader::RefShadowShader::Program);
|
||||
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
|
||||
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == GLOW_PASS)
|
||||
{
|
||||
glUseProgram(MeshShader::ColorizeShader::Program);
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
TextureMatrix = getMaterial(i).getTextureMatrix(0);
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
if (isTransparentPass != transparent)
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
if (irr_driver->getPhase() == DISPLACEMENT_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
drawDisplace(GLmeshes[i]);
|
||||
continue;
|
||||
}
|
||||
if (!isObject(material.MaterialType))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::warn("material", "Unhandled (static) material type : %d", material.MaterialType);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
drawGlow(GLmeshes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// only render transparent buffer if this is the transparent render pass
|
||||
// and solid only in solid pass
|
||||
if (irr_driver->getPhase() == GLOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
drawGlow(GLmeshes[i]);
|
||||
}
|
||||
else if (irr_driver->getPhase() == SHADOW_PASS)
|
||||
{
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
drawShadow(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
else
|
||||
{
|
||||
irr_driver->IncreaseObjectCount();
|
||||
initvaostate(GLmeshes[i], material.MaterialType);
|
||||
if (transparent)
|
||||
drawTransparent(GLmeshes[i], material.MaterialType);
|
||||
else
|
||||
drawSolid(GLmeshes[i], material.MaterialType);
|
||||
}
|
||||
if (irr_driver->getPhase() == TRANSPARENT_PASS)
|
||||
{
|
||||
computeMVP(ModelViewProjectionMatrix);
|
||||
|
||||
glUseProgram(MeshShader::BubbleShader::Program);
|
||||
for (unsigned i = 0; i < TransparentMesh[TM_BUBBLE].size(); i++)
|
||||
drawBubble(*TransparentMesh[TM_BUBBLE][i], ModelViewProjectionMatrix);
|
||||
|
||||
glUseProgram(MeshShader::TransparentShader::Program);
|
||||
for (unsigned i = 0; i < TransparentMesh[TM_DEFAULT].size(); i++)
|
||||
drawTransparentObject(*TransparentMesh[TM_DEFAULT][i], ModelViewProjectionMatrix, (*TransparentMesh[TM_DEFAULT][i]).TextureMatrix);
|
||||
return;
|
||||
}
|
||||
|
||||
if (irr_driver->getPhase() == DISPLACEMENT_PASS)
|
||||
{
|
||||
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (!mb)
|
||||
continue;
|
||||
drawDisplace(GLmeshes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,19 +6,24 @@
|
||||
class STKMeshSceneNode : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
std::vector<GLMesh *> GeometricMesh[FPSM_COUNT];
|
||||
std::vector<GLMesh *> ShadedMesh[SM_COUNT];
|
||||
std::vector<GLMesh *> TransparentMesh[TM_COUNT];
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix;
|
||||
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
|
||||
core::vector3df windDir;
|
||||
core::vector2df caustic_dir, caustic_dir2;
|
||||
void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void drawSolidPass1(const GLMesh &mesh, GeometricMaterial type);
|
||||
void drawSolidPass2(const GLMesh &mesh, ShadedMaterial type);
|
||||
void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
|
||||
// Misc passes shaders (glow, displace...)
|
||||
void drawGlow(const GLMesh &mesh);
|
||||
void drawDisplace(const GLMesh &mesh);
|
||||
void drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
void createGLMeshes();
|
||||
void cleanGLMeshes();
|
||||
void setFirstTimeMaterial();
|
||||
bool isMaterialInitialized;
|
||||
public:
|
||||
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),
|
||||
@ -30,4 +35,4 @@ public:
|
||||
~STKMeshSceneNode();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user