Use global VAO for rendering

This commit is contained in:
vlj 2014-06-25 14:53:49 +02:00
parent afd97345f7
commit 6276cafba2
9 changed files with 703 additions and 477 deletions

View File

@ -1,18 +1,15 @@
uniform sampler2D tex;
#if __VERSION__ >= 130
in vec2 uv;
in vec4 color;
out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main()
{
vec4 Color = texture(tex, uv) * pow(color, vec4(2.2));
vec4 Color = texture(tex, uv);
Color.xyz *= pow(color.xyz, vec3(2.2));
Color.a *= color.a;
// Premultiply alpha
FragColor = vec4(Color.rgb * Color.a, Color.a);
}

View File

@ -18,31 +18,28 @@ layout (std140) uniform MatrixesData
vec2 screen;
};
#if __VERSION__ >= 130
in vec2 uv;
in vec4 color;
out vec4 FragColor;
#else
varying vec2 uv;
#define FragColor gl_FragColor
#endif
void main()
{
vec4 diffusecolor = texture(tex, uv) * pow(color, vec4(2.2));
vec3 tmp = vec3(gl_FragCoord.xy / screen, gl_FragCoord.z);
tmp = 2. * tmp - 1.;
vec4 diffusecolor = texture(tex, uv);
diffusecolor.xyz *= pow(color.xyz, vec3(2.2));
diffusecolor.a *= color.a;
vec3 tmp = vec3(gl_FragCoord.xy / screen, gl_FragCoord.z);
tmp = 2. * tmp - 1.;
vec4 xpos = vec4(tmp, 1.0);
xpos = InverseProjectionMatrix * xpos;
xpos.xyz /= xpos.w;
vec4 xpos = vec4(tmp, 1.0);
xpos = InverseProjectionMatrix * xpos;
xpos.xyz /= xpos.w;
float dist = length(xpos.xyz);
float fog = smoothstep(start, end, dist);
float dist = length(xpos.xyz);
float fog = smoothstep(start, end, dist);
fog = min(fog, fogmax);
fog = min(fog, fogmax);
vec4 color = vec4(vec4(col, 0.) * fog + diffusecolor *(1. - fog));
FragColor = vec4(color.rgb * color.a, color.a);
vec4 finalcolor = vec4(col, 0.) * fog + diffusecolor *(1. - fog);
FragColor = vec4(finalcolor.rgb * finalcolor.a, finalcolor.a);
}

View File

@ -512,7 +512,8 @@ void IrrDriver::renderSolidFirstPass()
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
GroupedFPSM<FPSM_DEFAULT>::reset();
GroupedFPSM<FPSM_DEFAULT_STANDARD>::reset();
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::reset();
GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset();
GroupedFPSM<FPSM_NORMAL_MAP>::reset();
m_scene_manager->drawAll(scene::ESNRP_SOLID);
@ -523,34 +524,58 @@ void IrrDriver::renderSolidFirstPass()
{
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
glUseProgram(MeshShader::ObjectPass1Shader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
glBindVertexArray(getVAO(video::EVT_STANDARD));
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet.size(); ++i)
{
GLMesh &mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
GLMesh &mesh = *GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet[i];
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::ObjectPass1Shader>(mesh, mesh.vao, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i], 0);
draw<MeshShader::ObjectPass1Shader>(mesh, GroupedFPSM<FPSM_DEFAULT_STANDARD>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT_STANDARD>::TIMVSet[i], 0);
}
glBindVertexArray(getVAO(video::EVT_2TCOORDS));
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet.size(); ++i)
{
GLMesh &mesh = *GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet[i];
if (!mesh.textures[0])
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::ObjectPass1Shader>(mesh, GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT_2TCOORD>::TIMVSet[i], 0);
}
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
{
const GLMesh &mesh = *GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i];
if (mesh.VAOType != video::EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to alpha ref pass 1 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
continue;
}
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::ObjectRefPass1Shader>(mesh, mesh.vao, GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix, 0);
draw<MeshShader::ObjectRefPass1Shader>(mesh, GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix, 0);
}
glUseProgram(MeshShader::NormalMapShader::Program);
glBindVertexArray(getVAO(EVT_TANGENTS));
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
{
const GLMesh &mesh = *GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i];
assert(mesh.VAOType == video::EVT_TANGENTS);
assert(mesh.textures[1]);
compressTexture(mesh.textures[1], false);
setTexture(0, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
compressTexture(mesh.textures[0], true);
setTexture(1, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::NormalMapShader>(mesh, mesh.vao, GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i], 0, 1);
draw<MeshShader::NormalMapShader>(mesh, GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i], 0, 1);
}
}
}
@ -577,7 +602,8 @@ void IrrDriver::renderSolidSecondPass()
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
GroupedSM<SM_DEFAULT>::reset();
GroupedSM<SM_DEFAULT_STANDARD>::reset();
GroupedSM<SM_DEFAULT_TANGENT>::reset();
GroupedSM<SM_ALPHA_REF_TEXTURE>::reset();
GroupedSM<SM_RIMLIT>::reset();
GroupedSM<SM_SPHEREMAP>::reset();
@ -595,32 +621,177 @@ void IrrDriver::renderSolidSecondPass()
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glUseProgram(MeshShader::ObjectPass2Shader::Program);
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT>::MeshSet.size(); i++)
drawObjectPass2(*GroupedSM<SM_DEFAULT>::MeshSet[i], GroupedSM<SM_DEFAULT>::MVPSet[i], GroupedSM<SM_DEFAULT>::MeshSet[i]->TextureMatrix);
glBindVertexArray(getVAO(video::EVT_STANDARD));
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT_STANDARD>::MeshSet.size(); i++)
{
const GLMesh &mesh = *GroupedSM<SM_DEFAULT_STANDARD>::MeshSet[i];
if (mesh.VAOType != video::EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to pass 2 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
continue;
}
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectPass2Shader::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);
}
draw<MeshShader::ObjectPass2Shader>(mesh, GroupedSM<SM_DEFAULT_STANDARD>::MVPSet[i], GroupedSM<SM_DEFAULT_STANDARD>::MeshSet[i]->TextureMatrix);
}
glBindVertexArray(getVAO(video::EVT_TANGENTS));
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT_TANGENT>::MeshSet.size(); i++)
{
const GLMesh &mesh = *GroupedSM<SM_DEFAULT_TANGENT>::MeshSet[i];
assert(mesh.VAOType == video::EVT_TANGENTS);
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectPass2Shader::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);
}
draw<MeshShader::ObjectPass2Shader>(mesh, GroupedSM<SM_DEFAULT_TANGENT>::MVPSet[i], GroupedSM<SM_DEFAULT_TANGENT>::MeshSet[i]->TextureMatrix);
}
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet.size(); i++)
drawObjectRefPass2(*GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i];
if (mesh.VAOType != video::EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to alpha ref pass 2 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
continue;
}
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectRefPass2Shader::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);
}
draw<MeshShader::ObjectRefPass2Shader>(mesh, GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
}
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedSM<SM_RIMLIT>::MeshSet.size(); i++)
drawObjectRimLimit(*GroupedSM<SM_RIMLIT>::MeshSet[i], GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *GroupedSM<SM_RIMLIT>::MeshSet[i];
assert(mesh.VAOType == EVT_STANDARD);
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectRimLimitShader::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);
}
draw<MeshShader::ObjectRimLimitShader>(mesh, GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
}
glUseProgram(MeshShader::SphereMapShader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedSM<SM_SPHEREMAP>::MeshSet.size(); i++)
drawSphereMap(*GroupedSM<SM_SPHEREMAP>::MeshSet[i], GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i]);
{
const GLMesh &mesh = *GroupedSM<SM_SPHEREMAP>::MeshSet[i];
assert(mesh.VAOType == EVT_STANDARD);
compressTexture(mesh.textures[0], 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::SphereMapShader::TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::SphereMapShader>(mesh, GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i], irr_driver->getSceneManager()->getAmbientLight());
}
glUseProgram(MeshShader::SplattingShader::Program);
glBindVertexArray(getVAO(EVT_2TCOORDS));
for (unsigned i = 0; i < GroupedSM<SM_SPLATTING>::MeshSet.size(); i++)
drawSplatting(*GroupedSM<SM_SPLATTING>::MeshSet[i], GroupedSM<SM_SPLATTING>::MVPSet[i]);
glUseProgram(MeshShader::ObjectUnlitShader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedSM<SM_UNLIT>::MeshSet.size(); i++)
drawObjectUnlit(*GroupedSM<SM_UNLIT>::MeshSet[i], GroupedSM<SM_UNLIT>::MVPSet[i]);
{
const GLMesh &mesh = *GroupedSM<SM_UNLIT>::MeshSet[i];
assert(mesh.VAOType == EVT_STANDARD);
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectUnlitShader::TU_tex, 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);
}
draw<MeshShader::ObjectUnlitShader>(mesh, GroupedSM<SM_UNLIT>::MVPSet[i]);
}
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
glBindVertexArray(getVAO(EVT_2TCOORDS));
for (unsigned i = 0; i < GroupedSM<SM_DETAILS>::MeshSet.size(); i++)
drawDetailledObjectPass2(*GroupedSM<SM_DETAILS>::MeshSet[i], GroupedSM<SM_DETAILS>::MVPSet[i]);
{
GLMesh &mesh = *GroupedSM<SM_DETAILS>::MeshSet[i];
assert(mesh.VAOType == EVT_2TCOORDS);
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::DetailledObjectPass2Shader::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);
}
if (!mesh.textures[1])
{
#ifdef DEBUG
Log::error("Materials", "No detail/lightmap texture provided for detail/lightmap material.");
#endif
mesh.textures[1] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
}
compressTexture(mesh.textures[1], true);
setTexture(MeshShader::DetailledObjectPass2Shader::TU_detail, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::DetailledObjectPass2Shader>(mesh, GroupedSM<SM_DETAILS>::MVPSet[i]);
}
}
}
@ -637,25 +808,112 @@ void IrrDriver::renderTransparent()
TransparentMeshes<TM_ADDITIVE>::reset();
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT);
glBindVertexArray(getVAO(EVT_STANDARD));
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
const Track * const track = World::getWorld()->getTrack();
// This function is only called once per frame - thus no need for setters.
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
core::vector3df col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
glUseProgram(MeshShader::TransparentFogShader::Program);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
for (unsigned i = 0; i < TransparentMeshes<TM_DEFAULT>::MeshSet.size(); i++)
drawTransparentFogObject(*TransparentMeshes<TM_DEFAULT>::MeshSet[i], TransparentMeshes<TM_DEFAULT>::MVPSet[i], TransparentMeshes<TM_DEFAULT>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *TransparentMeshes<TM_DEFAULT>::MeshSet[i];
if (mesh.VAOType != EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to fog + transparent blend (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
glBindVertexArray(getVAO(mesh.VAOType));
}
if (mesh.textures[0] != NULL)
{
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
draw<MeshShader::TransparentFogShader>(mesh, TransparentMeshes<TM_DEFAULT>::MVPSet[i], TransparentMeshes<TM_DEFAULT>::MeshSet[i]->TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0);
if (mesh.VAOType != EVT_STANDARD)
glBindVertexArray(getVAO(EVT_STANDARD));
}
glBlendFunc(GL_ONE, GL_ONE);
for (unsigned i = 0; i < TransparentMeshes<TM_ADDITIVE>::MeshSet.size(); i++)
drawTransparentFogObject(*TransparentMeshes<TM_ADDITIVE>::MeshSet[i], TransparentMeshes<TM_ADDITIVE>::MVPSet[i], TransparentMeshes<TM_ADDITIVE>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *TransparentMeshes<TM_ADDITIVE>::MeshSet[i];
if (mesh.VAOType != EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
glBindVertexArray(getVAO(mesh.VAOType));
}
glBindVertexArray(getVAO(mesh.VAOType));
if (mesh.textures[0] != NULL)
{
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
draw<MeshShader::TransparentFogShader>(mesh, TransparentMeshes<TM_ADDITIVE>::MVPSet[i], TransparentMeshes<TM_ADDITIVE>::MeshSet[i]->TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0);
if (mesh.VAOType != EVT_STANDARD)
glBindVertexArray(getVAO(EVT_STANDARD));
}
}
else
{
glUseProgram(MeshShader::TransparentShader::Program);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
for (unsigned i = 0; i < TransparentMeshes<TM_DEFAULT>::MeshSet.size(); i++)
drawTransparentObject(*TransparentMeshes<TM_DEFAULT>::MeshSet[i], TransparentMeshes<TM_DEFAULT>::MVPSet[i], TransparentMeshes<TM_DEFAULT>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *TransparentMeshes<TM_DEFAULT>::MeshSet[i];
if (mesh.VAOType != EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
glBindVertexArray(getVAO(mesh.VAOType));
}
glBindVertexArray(getVAO(mesh.VAOType));
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::TransparentShader>(mesh, TransparentMeshes<TM_DEFAULT>::MVPSet[i], TransparentMeshes<TM_DEFAULT>::MeshSet[i]->TextureMatrix, 0);
if (mesh.VAOType != EVT_STANDARD)
glBindVertexArray(getVAO(EVT_STANDARD));
}
glBlendFunc(GL_ONE, GL_ONE);
for (unsigned i = 0; i < TransparentMeshes<TM_ADDITIVE>::MeshSet.size(); i++)
drawTransparentObject(*TransparentMeshes<TM_ADDITIVE>::MeshSet[i], TransparentMeshes<TM_ADDITIVE>::MVPSet[i], TransparentMeshes<TM_ADDITIVE>::MeshSet[i]->TextureMatrix);
{
const GLMesh &mesh = *TransparentMeshes<TM_ADDITIVE>::MeshSet[i];
if (mesh.VAOType != EVT_STANDARD)
{
#ifdef DEBUG
Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
#endif
glBindVertexArray(getVAO(mesh.VAOType));
}
glBindVertexArray(getVAO(mesh.VAOType));
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::TransparentShader>(mesh, TransparentMeshes<TM_ADDITIVE>::MVPSet[i], TransparentMeshes<TM_ADDITIVE>::MeshSet[i]->TextureMatrix, 0);
if (mesh.VAOType != EVT_STANDARD)
glBindVertexArray(getVAO(EVT_STANDARD));
}
}
}
@ -857,9 +1115,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, siz
void IrrDriver::renderShadows()
{
GroupedFPSM<FPSM_DEFAULT>::reset();
GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset();
GroupedFPSM<FPSM_NORMAL_MAP>::reset();
irr_driver->setPhase(SHADOW_PASS);
glDisable(GL_BLEND);
glEnable(GL_POLYGON_OFFSET_FILL);
@ -873,12 +1128,18 @@ void IrrDriver::renderShadows()
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glUseProgram(MeshShader::ShadowShader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
drawShadow(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i]);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet.size(); ++i)
drawShadow(*GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT_STANDARD>::MVPSet[i]);
glBindVertexArray(getVAO(EVT_2TCOORDS));
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet.size(); ++i)
drawShadow(*GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MVPSet[i]);
glBindVertexArray(getVAO(EVT_TANGENTS));
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
drawShadow(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i]);
glUseProgram(MeshShader::RefShadowShader::Program);
glBindVertexArray(getVAO(EVT_STANDARD));
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
drawShadowRef(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i]);
@ -891,14 +1152,14 @@ void IrrDriver::renderShadows()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(MeshShader::RSMShader::Program);
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet.size(); ++i)
{
const GLMesh mesh = *GroupedFPSM<FPSM_DEFAULT>::MeshSet[i];
const GLMesh mesh = *GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet[i];
if (!mesh.textures[0])
continue;
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
draw<MeshShader::RSMShader>(mesh, mesh.vao, rsm_matrix, GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], 0);
draw<MeshShader::RSMShader>(mesh, rsm_matrix, GroupedFPSM<FPSM_DEFAULT_STANDARD>::MVPSet[i], 0);
}
}
@ -954,6 +1215,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
glBindVertexArray(getVAO(EVT_STANDARD));
for (u32 i = 0; i < glowcount; i++)
{
const GlowData &dat = glows[i];
@ -1661,6 +1923,7 @@ void IrrDriver::renderDisplacement()
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glBindVertexArray(getVAO(EVT_2TCOORDS));
for (int i = 0; i < displacingcount; i++)
{
m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT);

View File

@ -93,17 +93,19 @@ void STKAnimatedMesh::render()
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
initvaostate(mesh, TranspMat);
TransparentMesh[TranspMat].push_back(&mesh);
}
else
{
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
initvaostate(mesh, GeometricType, ShadedType);
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType());
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType());
GeometricMesh[GeometricType].push_back(&mesh);
ShadedMesh[ShadedType].push_back(&mesh);
}
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
}
}
firstTime = false;
@ -117,8 +119,9 @@ void STKAnimatedMesh::render()
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());
glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType()));
glBufferSubData(GL_ARRAY_BUFFER, GLmeshes[i].vaoBaseVertex * GLmeshes[i].Stride, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices());
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
if (mb)
@ -133,7 +136,7 @@ void STKAnimatedMesh::render()
continue;
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
@ -141,11 +144,18 @@ void STKAnimatedMesh::render()
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, GeometricMesh[FPSM_DEFAULT])
for_in(mesh, GeometricMesh[FPSM_DEFAULT_STANDARD])
{
GroupedFPSM<FPSM_DEFAULT>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT>::TIMVSet.push_back(invmodel);
GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT_STANDARD>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT_STANDARD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, GeometricMesh[FPSM_DEFAULT_2TCOORD])
{
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, GeometricMesh[FPSM_ALPHA_REF_TEXTURE])
@ -164,11 +174,18 @@ void STKAnimatedMesh::render()
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, ShadedMesh[SM_DEFAULT])
for_in(mesh, ShadedMesh[SM_DEFAULT_STANDARD])
{
GroupedSM<SM_DEFAULT>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT>::TIMVSet.push_back(invmodel);
GroupedSM<SM_DEFAULT_STANDARD>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT_STANDARD>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT_STANDARD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, ShadedMesh[SM_DEFAULT_TANGENT])
{
GroupedSM<SM_DEFAULT_TANGENT>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT_TANGENT>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT_TANGENT>::TIMVSet.push_back(invmodel);
}
for_in(mesh, ShadedMesh[SM_ALPHA_REF_TEXTURE])

View File

@ -50,6 +50,7 @@ void STKInstancedSceneNode::createGLMeshes()
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
GLmeshes.push_back(allocateMeshBuffer(mb));
fillLocalBuffer(GLmeshes.back(), mb);
}
isMaterialInitialized = false;
}
@ -98,8 +99,8 @@ void STKInstancedSceneNode::setFirstTimeMaterial()
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
GLMesh &mesh = GLmeshes[i];
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type);
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures);
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType());
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType());
initinstancedvaostate(mesh, GeometricType, ShadedType);
GeometricMesh[GeometricType].push_back(&mesh);
ShadedMesh[ShadedType].push_back(&mesh);
@ -302,10 +303,10 @@ void STKInstancedSceneNode::render()
ModelViewProjectionMatrix = irr_driver->getProjMatrix();
ModelViewProjectionMatrix *= irr_driver->getViewMatrix();
if (!GeometricMesh[FPSM_DEFAULT].empty())
if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty())
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT][i], instance_pos.size() / 9);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++)
drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedObjectRefPass1Shader::Program);
@ -322,10 +323,10 @@ void STKInstancedSceneNode::render()
if (irr_driver->getPhase() == SOLID_LIT_PASS)
{
if (!ShadedMesh[SM_DEFAULT].empty())
if (!ShadedMesh[SM_DEFAULT_STANDARD].empty())
glUseProgram(MeshShader::InstancedObjectPass2Shader::Program);
for (unsigned i = 0; i < ShadedMesh[FPSM_DEFAULT].size(); i++)
drawSMDefault(*ShadedMesh[FPSM_DEFAULT][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT_STANDARD].size(); i++)
drawSMDefault(*ShadedMesh[SM_DEFAULT_STANDARD][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
if (!ShadedMesh[SM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedObjectRefPass2Shader::Program);
@ -341,10 +342,10 @@ void STKInstancedSceneNode::render()
if (irr_driver->getPhase() == SHADOW_PASS)
{
if (!GeometricMesh[FPSM_DEFAULT].empty())
if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty())
glUseProgram(MeshShader::InstancedShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawShadowDefault(*GeometricMesh[FPSM_DEFAULT][i], instance_pos.size() / 9);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++)
drawShadowDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedRefShadowShader::Program);

View File

@ -9,7 +9,7 @@
#include "graphics/camera.hpp"
#include "modes/world.hpp"
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE MaterialType)
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE MaterialType, video::E_VERTEX_TYPE tp)
{
if (MaterialType == irr_driver->getShader(ES_NORMAL_MAP))
return FPSM_NORMAL_MAP;
@ -17,11 +17,13 @@ GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE Materia
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;
else if (tp == video::EVT_2TCOORDS)
return FPSM_DEFAULT_2TCOORD;
assert(tp == video::EVT_STANDARD);
return FPSM_DEFAULT_STANDARD;
}
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, video::ITexture **textures)
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, video::ITexture **textures, video::E_VERTEX_TYPE tp)
{
if (type == irr_driver->getShader(ES_SPHERE_MAP))
return SM_SPHEREMAP;
@ -35,10 +37,11 @@ ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, video::
return SM_GRASS;
else if (type == irr_driver->getShader(ES_OBJECT_UNLIT))
return SM_UNLIT;
else if (textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP))
else if (tp == video::EVT_2TCOORDS)
return SM_DETAILS;
else
return SM_DEFAULT;
else if (tp == video::EVT_TANGENTS)
return SM_DEFAULT_TANGENT;
return SM_DEFAULT_STANDARD;
}
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE type, f32 MaterialTypeParam)
@ -137,46 +140,28 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
GLMesh result = {};
if (!mb)
return result;
glBindVertexArray(0);
glGenBuffers(1, &(result.vertex_buffer));
glGenBuffers(1, &(result.index_buffer));
glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer);
const void* vertices = mb->getVertices();
const u32 vertexCount = mb->getVertexCount();
const irr::video::E_VERTEX_TYPE vType = mb->getVertexType();
result.Stride = getVertexPitchFromType(vType);
const c8* vbuf = static_cast<const c8*>(vertices);
glBufferData(GL_ARRAY_BUFFER, vertexCount * result.Stride, vbuf, GL_STATIC_DRAW);
assert(vertexCount);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer);
const void* indices = mb->getIndices();
u32 indexCount = mb->getIndexCount();
size_t indexSize = 0;
result.IndexCount = mb->getIndexCount();
switch (mb->getIndexType())
{
case irr::video::EIT_16BIT:
{
indexSize = sizeof(u16);
result.IndexType = GL_UNSIGNED_SHORT;
break;
}
case irr::video::EIT_32BIT:
{
indexSize = sizeof(u32);
result.IndexType = GL_UNSIGNED_INT;
break;
}
default:
{
assert(0 && "Wrong index size");
}
case irr::video::EIT_16BIT:
{
result.IndexType = GL_UNSIGNED_SHORT;
break;
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW);
case irr::video::EIT_32BIT:
{
result.IndexType = GL_UNSIGNED_INT;
break;
}
default:
{
assert(0 && "Wrong index size");
}
}
result.VAOType = mb->getVertexType();
result.Stride = getVertexPitchFromType(result.VAOType);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
result.IndexCount = mb->getIndexCount();
switch (mb->getPrimitiveType())
@ -210,6 +195,44 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
return result;
}
static
size_t getUnsignedSize(unsigned tp)
{
switch (tp)
{
case GL_UNSIGNED_SHORT:
return sizeof(u16);
case GL_UNSIGNED_INT:
return sizeof(u32);
default:
assert(0 && "Unsupported index type");
return 0;
}
}
void fillLocalBuffer(GLMesh &mesh, scene::IMeshBuffer* mb)
{
glBindVertexArray(0);
glGenBuffers(1, &(mesh.vertex_buffer));
glGenBuffers(1, &(mesh.index_buffer));
glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer);
const void* vertices = mb->getVertices();
const u32 vertexCount = mb->getVertexCount();
const c8* vbuf = static_cast<const c8*>(vertices);
glBufferData(GL_ARRAY_BUFFER, vertexCount * mesh.Stride, vbuf, GL_STATIC_DRAW);
assert(vertexCount);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer);
const void* indices = mb->getIndices();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.IndexCount * getUnsignedSize(mesh.IndexType), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
{
@ -243,149 +266,93 @@ void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(mesh.VAOType == video::EVT_STANDARD);
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, windDir, 0);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], 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::SphereMapShader::TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::SphereMapShader::setUniforms(ModelMatrix, InverseModelMatrix, irr_driver->getSceneManager()->getAmbientLight());
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
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;
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
// Texlayout
compressTexture(mesh.textures[1], true);
setTexture(MeshShader::SplattingShader::TU_tex_layout, getTextureGLuint(mesh.textures[1]), 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);
}
//Tex detail0
compressTexture(mesh.textures[2], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail0, getTextureGLuint(mesh.textures[2]), 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);
}
//Tex detail1
compressTexture(mesh.textures[3], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail1, getTextureGLuint(mesh.textures[3]), 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);
}
compressTexture(mesh.textures[4], true);
//Tex detail2
setTexture(MeshShader::SplattingShader::TU_tex_detail2, getTextureGLuint(mesh.textures[4]), 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);
}
//Tex detail3
compressTexture(mesh.textures[5], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail3, getTextureGLuint(mesh.textures[5]), 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);
}
// Texlayout
compressTexture(mesh.textures[1], true);
setTexture(MeshShader::SplattingShader::TU_tex_layout, getTextureGLuint(mesh.textures[1]), 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);
}
//Tex detail0
compressTexture(mesh.textures[2], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail0, getTextureGLuint(mesh.textures[2]), 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);
}
//Tex detail1
compressTexture(mesh.textures[3], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail1, getTextureGLuint(mesh.textures[3]), 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);
}
compressTexture(mesh.textures[4], true);
//Tex detail2
setTexture(MeshShader::SplattingShader::TU_tex_detail2, getTextureGLuint(mesh.textures[4]), 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);
}
//Tex detail3
compressTexture(mesh.textures[5], true);
setTexture(MeshShader::SplattingShader::TU_tex_detail3, getTextureGLuint(mesh.textures[5]), 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::SplattingShader::setUniforms(ModelViewProjectionMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
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;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectRefPass2Shader::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::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir)
{
@ -393,7 +360,10 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(mesh.VAOType == video::EVT_STANDARD);
if (!mesh.textures[0])
const_cast<GLMesh &>(mesh).textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::GrassPass2Shader::TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
@ -408,136 +378,7 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio
}
MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::UntexturedObjectShader::setUniforms(ModelMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
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;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectRimLimitShader::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::ObjectRimLimitShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
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;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectUnlitShader::TU_tex, 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::ObjectUnlitShader::setUniforms(ModelViewProjectionMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
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;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::DetailledObjectPass2Shader::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);
}
compressTexture(mesh.textures[1], true);
setTexture(MeshShader::DetailledObjectPass2Shader::TU_detail, getTextureGLuint(mesh.textures[1]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::DetailledObjectPass2Shader::setUniforms(ModelViewProjectionMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
}
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;
if (!mesh.textures[0])
const_cast<GLMesh &>(mesh).textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::ObjectPass2Shader::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::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix)
@ -606,10 +447,7 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::BubbleShader::setUniforms(ModelViewProjectionMatrix, 0, time, transparency);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
@ -622,10 +460,7 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::RefShadowShader::setUniforms(ModelMatrix, 0);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, 4);
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, 4, mesh.vaoBaseVertex);
}
void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
@ -636,10 +471,7 @@ void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
size_t count = mesh.IndexCount;
MeshShader::ShadowShader::setUniforms(ModelMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElementsInstanced(ptype, count, itype, 0, 4);
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *) mesh.vaoOffset, 4, mesh.vaoBaseVertex);
}
bool isObject(video::E_MATERIAL_TYPE type)

View File

@ -12,7 +12,8 @@
enum GeometricMaterial
{
FPSM_DEFAULT,
FPSM_DEFAULT_STANDARD,
FPSM_DEFAULT_2TCOORD,
FPSM_ALPHA_REF_TEXTURE,
FPSM_NORMAL_MAP,
FPSM_GRASS,
@ -21,7 +22,8 @@ enum GeometricMaterial
enum ShadedMaterial
{
SM_DEFAULT,
SM_DEFAULT_STANDARD,
SM_DEFAULT_TANGENT,
SM_ALPHA_REF_TEXTURE,
SM_RIMLIT,
SM_SPHEREMAP,
@ -51,9 +53,13 @@ struct GLMesh {
size_t IndexCount;
size_t Stride;
core::matrix4 TextureMatrix;
size_t vaoBaseVertex;
size_t vaoOffset;
video::E_VERTEX_TYPE VAOType;
};
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
void fillLocalBuffer(GLMesh &, scene::IMeshBuffer* mb);
video::E_VERTEX_TYPE getVTXTYPEFromStride(size_t stride);
GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
@ -89,7 +95,7 @@ std::vector<core::matrix4> GroupedFPSM<T>::TIMVSet;
template<typename Shader, typename...uniforms>
void draw(const GLMesh &mesh, GLuint vao, uniforms... Args)
void draw(const GLMesh &mesh, uniforms... Args)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
@ -97,10 +103,7 @@ void draw(const GLMesh &mesh, GLuint vao, uniforms... Args)
size_t count = mesh.IndexCount;
Shader::setUniforms(Args...);
assert(vao);
glBindVertexArray(vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir);
@ -128,15 +131,8 @@ std::vector<core::matrix4> GroupedSM<T>::MVPSet;
template<enum ShadedMaterial T>
std::vector<core::matrix4> GroupedSM<T>::TIMVSet;
void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir);
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, const core::matrix4 &ModelMatrix);
@ -166,8 +162,8 @@ void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewPro
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE);
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE, irr::video::ITexture **textures);
GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE);
ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE, irr::video::ITexture **textures, video::E_VERTEX_TYPE tp);
TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam);
#endif // STKMESH_H

View File

@ -16,13 +16,16 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
const irr::core::vector3df& scale) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
reload_each_frame = false;
immediate_draw = false;
update_each_frame = false;
createGLMeshes();
}
void STKMeshSceneNode::setReloadEachFrame(bool val)
{
reload_each_frame = val;
update_each_frame = val;
if (val)
immediate_draw = true;
}
void STKMeshSceneNode::createGLMeshes()
@ -60,16 +63,38 @@ void STKMeshSceneNode::setFirstTimeMaterial()
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
initvaostate(mesh, TranspMat);
TransparentMesh[TranspMat].push_back(&mesh);
if (immediate_draw)
{
fillLocalBuffer(mesh, mb);
initvaostate(mesh, TranspMat);
glBindVertexArray(0);
}
else
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);
GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType());
ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType());
if (immediate_draw)
{
fillLocalBuffer(mesh, mb);
initvaostate(mesh, GeometricType, ShadedType);
glBindVertexArray(0);
}
else
{
GeometricMesh[GeometricType].push_back(&mesh);
ShadedMesh[ShadedType].push_back(&mesh);
}
}
if (!immediate_draw)
{
std::pair<unsigned, unsigned> p = getVAOOffsetAndBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
mesh.VAOType = mb->getVertexType();
}
}
isMaterialInitialized = true;
@ -109,22 +134,26 @@ STKMeshSceneNode::~STKMeshSceneNode()
void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
{
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
assert(mesh.VAOType == video::EVT_STANDARD);
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ColorizeShader::setUniforms(AbsoluteTransformation, cb->getRed(), cb->getGreen(), cb->getBlue());
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, 4, mesh.vaoBaseVertex);
}
static video::ITexture *displaceTex = 0;
void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
{
if (mesh.VAOType != video::EVT_2TCOORDS)
{
Log::error("Materials", "Displacement has wrong vertex type");
return;
}
glBindVertexArray(getVAO(video::EVT_2TCOORDS));
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
GLenum ptype = mesh.PrimitiveType;
@ -137,9 +166,7 @@ void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
glUseProgram(MeshShader::DisplaceMaskShader::Program);
MeshShader::DisplaceMaskShader::setUniforms(AbsoluteTransformation);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, 4, mesh.vaoBaseVertex);
// Render the effect
if (!displaceTex)
@ -156,7 +183,7 @@ void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
float(UserConfigParams::m_height)),
0, 1, 2);
glDrawElements(ptype, count, itype, 0);
glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, 4, mesh.vaoBaseVertex);
}
void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
@ -174,33 +201,6 @@ void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYP
return;
}
void STKMeshSceneNode::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type)
{
irr_driver->IncreaseObjectCount();
windDir = getWind();
switch (type)
{
case FPSM_GRASS:
drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
break;
default:
assert(0 && "wrong geometric material");
}
}
void STKMeshSceneNode::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type)
{
switch (type)
{
case SM_GRASS:
drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir);
break;
default:
assert(0 && "Wrong shaded material");
break;
}
}
void STKMeshSceneNode::updatevbo()
{
for (unsigned i = 0; i < Mesh->getMeshBufferCount(); ++i)
@ -243,8 +243,8 @@ void STKMeshSceneNode::render()
if (!Mesh || !driver)
return;
if (reload_each_frame)
updatevbo();
bool isTransparentPass =
SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;
++PassCount;
@ -260,20 +260,52 @@ void STKMeshSceneNode::render()
GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0);
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
if (reload_each_frame)
glDisable(GL_CULL_FACE);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, GeometricMesh[FPSM_DEFAULT])
if (immediate_draw)
{
GroupedFPSM<FPSM_DEFAULT>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT>::TIMVSet.push_back(invmodel);
glDisable(GL_CULL_FACE);
if (update_each_frame)
updatevbo();
glUseProgram(MeshShader::ObjectPass1Shader::Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ObjectPass1Shader::setUniforms(AbsoluteTransformation, invmodel, 0);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
}
GLMesh* mesh;
for_in(mesh, GeometricMesh[FPSM_DEFAULT_STANDARD])
{
GroupedFPSM<FPSM_DEFAULT_STANDARD>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT_STANDARD>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT_STANDARD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, GeometricMesh[FPSM_DEFAULT_2TCOORD])
{
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MeshSet.push_back(mesh);
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::MVPSet.push_back(AbsoluteTransformation);
GroupedFPSM<FPSM_DEFAULT_2TCOORD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, GeometricMesh[FPSM_ALPHA_REF_TEXTURE])
@ -290,33 +322,57 @@ void STKMeshSceneNode::render()
GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet.push_back(invmodel);
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
if (!GeometricMesh[FPSM_GRASS].empty())
glUseProgram(MeshShader::GrassPass1Shader::Program);
for_in(mesh, GeometricMesh[FPSM_GRASS])
drawSolidPass1(*mesh, FPSM_GRASS);
}
if (!GeometricMesh[FPSM_GRASS].empty())
glUseProgram(MeshShader::GrassPass1Shader::Program);
windDir = getWind();
glBindVertexArray(getVAO(video::EVT_STANDARD));
for_in(mesh, GeometricMesh[FPSM_GRASS])
drawGrassPass1(*mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
if (reload_each_frame)
glEnable(GL_CULL_FACE);
return;
}
if (irr_driver->getPhase() == SOLID_LIT_PASS)
{
if (reload_each_frame)
glDisable(GL_CULL_FACE);
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, ShadedMesh[SM_DEFAULT])
if (immediate_draw)
{
GroupedSM<SM_DEFAULT>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT>::TIMVSet.push_back(invmodel);
glDisable(GL_CULL_FACE);
glUseProgram(MeshShader::UntexturedObjectShader::Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::UntexturedObjectShader::setUniforms(AbsoluteTransformation);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
glEnable(GL_CULL_FACE);
return;
}
GLMesh* mesh;
for_in(mesh, ShadedMesh[SM_DEFAULT_STANDARD])
{
GroupedSM<SM_DEFAULT_STANDARD>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT_STANDARD>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT_STANDARD>::TIMVSet.push_back(invmodel);
}
for_in(mesh, ShadedMesh[SM_DEFAULT_TANGENT])
{
GroupedSM<SM_DEFAULT_TANGENT>::MeshSet.push_back(mesh);
GroupedSM<SM_DEFAULT_TANGENT>::MVPSet.push_back(AbsoluteTransformation);
GroupedSM<SM_DEFAULT_TANGENT>::TIMVSet.push_back(invmodel);
}
for_in(mesh, ShadedMesh[SM_ALPHA_REF_TEXTURE])
@ -364,11 +420,10 @@ void STKMeshSceneNode::render()
if (!ShadedMesh[SM_GRASS].empty())
glUseProgram(MeshShader::GrassPass2Shader::Program);
glBindVertexArray(getVAO(video::EVT_STANDARD));
for_in(mesh, ShadedMesh[SM_GRASS])
drawSolidPass2(*mesh, SM_GRASS);
drawGrassPass2(*mesh, ModelViewProjectionMatrix, windDir);
if (reload_each_frame)
glEnable(GL_CULL_FACE);
return;
}
@ -380,6 +435,7 @@ void STKMeshSceneNode::render()
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
glBindVertexArray(getVAO(video::EVT_STANDARD));
drawGlow(GLmeshes[i]);
}
}
@ -388,6 +444,71 @@ void STKMeshSceneNode::render()
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
if (immediate_draw)
{
if (update_each_frame)
updatevbo();
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
glUseProgram(MeshShader::TransparentFogShader::Program);
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
GLMesh &mesh = GLmeshes[i];
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
const Track * const track = World::getWorld()->getTrack();
// This function is only called once per frame - thus no need for setters.
const float fogmax = track->getFogMax();
const float startH = track->getFogStartHeight();
const float endH = track->getFogEndHeight();
const float start = track->getFogStart();
const float end = track->getFogEnd();
const video::SColor tmpcol = track->getFogColor();
core::vector3df col(tmpcol.getRed() / 255.0f,
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::TransparentFogShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
}
else
{
glUseProgram(MeshShader::TransparentShader::Program);
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
irr_driver->IncreaseObjectCount();
GLMesh &mesh = GLmeshes[i];
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::TransparentShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix, 0);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
}
}
return;
}
GLMesh* mesh;
for_in(mesh, TransparentMesh[TM_DEFAULT])
@ -404,6 +525,7 @@ void STKMeshSceneNode::render()
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);
glBindVertexArray(getVAO(video::EVT_STANDARD));
for_in(mesh, TransparentMesh[TM_BUBBLE])
drawBubble(*mesh, ModelViewProjectionMatrix);
return;

View File

@ -26,7 +26,8 @@ protected:
void setFirstTimeMaterial();
void updatevbo();
bool isMaterialInitialized;
bool reload_each_frame;
bool immediate_draw;
bool update_each_frame;
public:
void setReloadEachFrame(bool);
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,