STKMesh:Displace support

This commit is contained in:
Vincent Lejeune 2014-01-21 01:46:39 +01:00
parent 7faed75a84
commit f95c6f0277
3 changed files with 116 additions and 65 deletions

View File

@ -828,10 +828,7 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
{
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_DISPLACE), false, false);
glClearColor(0, 0, 0, 0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, ~0);
glEnable(GL_STENCIL_TEST);
glClear(GL_COLOR_BUFFER_BIT);
overridemat.Enabled = 1;
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE | video::EMF_TEXTURE0;
@ -845,9 +842,14 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
overridemat.Material.TextureLayer[0].TextureWrapU =
overridemat.Material.TextureLayer[0].TextureWrapV = video::ETC_REPEAT;
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
cb->update();
const int displacingcount = m_displacing.size();
irr_driver->setPhase(4);
for (int i = 0; i < displacingcount; i++)
{
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_displacing[i]->render();
@ -858,9 +860,6 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
overridemat.Enabled = 0;
// Blur it
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 1, ~0);
video::SMaterial minimat;
minimat.Lighting = false;
minimat.ZWriteEnable = false;
@ -872,6 +871,5 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
m_post_processing->renderGaussian3Blur(m_rtts->getRTT(RTT_DISPLACE), m_rtts->getRTT(RTT_TMP2), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height);
glDisable(GL_STENCIL_TEST);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
}

View File

@ -452,6 +452,30 @@ void STKMesh::drawGlow(const GLMesh &mesh)
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void STKMesh::drawDisplace(const GLMesh &mesh)
{
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
computeMVP(ModelViewProjectionMatrix);
core::matrix4 ModelViewMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
setTexture(0, static_cast<irr::video::COpenGLTexture*>(irr_driver->getTexture(FileManager::TEXTURE, "displace.png"))->getOpenGLTextureName(), GL_LINEAR, GL_LINEAR);
glUseProgram(MeshShader::DisplaceShader::Program);
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, cb->getDirX(), cb->getDirY(), cb->getDir2X(), cb->getDir2Y(), 0);
glBindVertexArray(mesh.vao_displace_pass);
glDrawElements(ptype, count, itype, 0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
{
glEnable(GL_DEPTH_TEST);
@ -551,65 +575,86 @@ static bool isObject(video::E_MATERIAL_TYPE type)
static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
{
if (mesh.vao_first_pass)
switch (irr_driver->getPhase())
{
case 0: // Solid Pass 1
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 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
{
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 1: // Solid pass 2
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_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
{
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 2: // Glow
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 3: // Transparent
if (mesh.vao_first_pass)
return;
if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
{
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 4:
if (mesh.vao_displace_pass)
return;
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;
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 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 (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL)
{
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);
}
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);
}
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_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
{
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);
}
mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
}
void STKMesh::render()
@ -639,6 +684,12 @@ void STKMesh::render()
if (isTransparentPass != transparent)
continue;
if (irr_driver->getPhase() == 4)
{
initvaostate(GLmeshes[i], material.MaterialType);
drawDisplace(GLmeshes[i]);
continue;
}
if (!isObject(material.MaterialType))
{
driver->setMaterial(material);

View File

@ -12,6 +12,7 @@ struct GLMesh {
GLuint vao_first_pass;
GLuint vao_second_pass;
GLuint vao_glow_pass;
GLuint vao_displace_pass;
GLuint vertex_buffer;
GLuint index_buffer;
GLuint textures[6];
@ -49,6 +50,7 @@ protected:
// Misc passes shaders (glow, displace...)
void drawGlow(const GLMesh &mesh);
void drawDisplace(const GLMesh &mesh);
public:
STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),