diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index f3e1eccd9..3009d1595 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -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); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 2b852d100..fafebf94a 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -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_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); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index be4a411d5..7a3352153 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -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),