Add a transparent fog aware shader

This commit is contained in:
Vincent Lejeune 2014-02-03 20:03:20 +01:00
parent 6e93178d68
commit 8a341dc800
5 changed files with 107 additions and 5 deletions

View File

@ -254,6 +254,7 @@ void Shaders::loadShaders()
MeshShader::GrassPass2Shader::init();
MeshShader::BubbleShader::init();
MeshShader::TransparentShader::init();
MeshShader::TransparentFogShader::init();
MeshShader::BillboardShader::init();
MeshShader::DisplaceShader::init();
ParticleShader::FlipParticleRender::init();
@ -777,6 +778,51 @@ namespace MeshShader
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
}
GLuint TransparentFogShader::Program;
GLuint TransparentFogShader::attrib_position;
GLuint TransparentFogShader::attrib_texcoord;
GLuint TransparentFogShader::uniform_MVP;
GLuint TransparentFogShader::uniform_tex;
GLuint TransparentFogShader::uniform_fogmax;
GLuint TransparentFogShader::uniform_startH;
GLuint TransparentFogShader::uniform_endH;
GLuint TransparentFogShader::uniform_start;
GLuint TransparentFogShader::uniform_end;
GLuint TransparentFogShader::uniform_col;
GLuint TransparentFogShader::uniform_screen;
GLuint TransparentFogShader::uniform_ipvmat;
void TransparentFogShader::init()
{
Program = LoadProgram(file_manager->getAsset("shaders/transparent.vert").c_str(), file_manager->getAsset("shaders/transparentfog.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_fogmax = glGetUniformLocation(Program, "fogmax");
uniform_startH = glGetUniformLocation(Program, "startH");
uniform_endH = glGetUniformLocation(Program, "endH");
uniform_start = glGetUniformLocation(Program, "start");
uniform_end = glGetUniformLocation(Program, "end");
uniform_col = glGetUniformLocation(Program, "col");
uniform_screen = glGetUniformLocation(Program, "screen");
uniform_ipvmat = glGetUniformLocation(Program, "ipvmat");
}
void TransparentFogShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniform1f(uniform_fogmax, fogmax);
glUniform1f(uniform_startH, startH);
glUniform1f(uniform_endH, endH);
glUniform1f(uniform_start, start);
glUniform1f(uniform_end, end);
glUniform3f(uniform_col, col.X, col.Y, col.Z);
glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height);
glUniformMatrix4fv(uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer());
glUniform1i(uniform_tex, TU_tex);
}
GLuint BillboardShader::Program;
GLuint BillboardShader::attrib_corner;

View File

@ -191,6 +191,17 @@ public:
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex);
};
class TransparentFogShader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord;
static GLuint uniform_MVP, uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_screen, uniform_ipvmat;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_tex);
};
class BillboardShader
{
public:
@ -417,11 +428,11 @@ class FogShader
{
public:
static GLuint Program;
static GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_campos, uniform_ipvmat;
static GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_ipvmat;
static GLuint vao;
static void init();
static void setUniforms(const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_ntex);
static void setUniforms(const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, unsigned TU_ntex);
};
}

View File

@ -4,6 +4,8 @@
#include <ISkinnedMesh.h>
#include "graphics/irr_driver.hpp"
#include "config/user_config.hpp"
#include "modes/world.hpp"
#include "tracks/track.hpp"
using namespace irr;
@ -30,7 +32,10 @@ void STKAnimatedMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE
computeMVP(ModelViewProjectionMatrix);
drawTransparentObject(mesh, ModelViewProjectionMatrix);
if (World::getWorld()->getTrack()->isFogEnabled())
drawTransparentFogObject(mesh, ModelViewProjectionMatrix);
else
drawTransparentObject(mesh, ModelViewProjectionMatrix);
return;
}

View File

@ -1,10 +1,13 @@
#include "stkmesh.hpp"
#include "graphics/irr_driver.hpp"
#include "tracks/track.hpp"
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
#include "config/user_config.hpp"
#include "graphics/callbacks.hpp"
#include "utils/helpers.hpp"
#include "graphics/camera.hpp"
#include "modes/world.hpp"
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)
@ -623,6 +626,35 @@ void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewPro
glDrawElements(ptype, count, itype, 0);
}
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
{
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);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
glUseProgram(MeshShader::TransparentFogShader::Program);
MeshShader::TransparentFogShader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvProjMatrix(), fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElements(ptype, count, itype, 0);
}
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
{
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
@ -682,8 +714,10 @@ void STKMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
computeMVP(ModelViewProjectionMatrix);
if (type == irr_driver->getShader(ES_BUBBLES))
drawBubble(mesh, ModelViewProjectionMatrix);
if (type == irr_driver->getShader(ES_BUBBLES))
drawBubble(mesh, ModelViewProjectionMatrix);
else if (World::getWorld()->getTrack()->isFogEnabled())
drawTransparentFogObject(mesh, ModelViewProjectionMatrix);
else
drawTransparentObject(mesh, ModelViewProjectionMatrix);
return;
@ -860,6 +894,11 @@ void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
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,

View File

@ -47,6 +47,7 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio
// Forward pass (for transparents meshes)
void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
class STKMesh : public irr::scene::CMeshSceneNode