Add support for alpha ref instancied materials.

This commit is contained in:
Vincent Lejeune 2014-03-31 19:16:26 +02:00
parent 8c3c380ded
commit 551e6cc9c8
3 changed files with 186 additions and 36 deletions

View File

@ -320,9 +320,11 @@ void Shaders::loadShaders()
MeshShader::ObjectPass1Shader::init();
MeshShader::ObjectRefPass1Shader::init();
MeshShader::InstancedObjectPass1Shader::init();
MeshShader::InstancedObjectRefPass1Shader::init();
MeshShader::InstancedGrassPass1Shader::init();
MeshShader::ObjectPass2Shader::init();
MeshShader::InstancedObjectPass2Shader::init();
MeshShader::InstancedObjectRefPass2Shader::init();
MeshShader::InstancedGrassPass2Shader::init();
MeshShader::DetailledObjectPass2Shader::init();
MeshShader::ObjectRimLimitShader::init();
@ -537,6 +539,42 @@ namespace MeshShader
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
}
GLuint InstancedObjectRefPass1Shader::Program;
GLuint InstancedObjectRefPass1Shader::attrib_position;
GLuint InstancedObjectRefPass1Shader::attrib_normal;
GLuint InstancedObjectRefPass1Shader::attrib_texcoord;
GLuint InstancedObjectRefPass1Shader::attrib_orientation;
GLuint InstancedObjectRefPass1Shader::attrib_origin;
GLuint InstancedObjectRefPass1Shader::attrib_scale;
GLuint InstancedObjectRefPass1Shader::uniform_MP;
GLuint InstancedObjectRefPass1Shader::uniform_VM;
GLuint InstancedObjectRefPass1Shader::uniform_tex;
void InstancedObjectRefPass1Shader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation");
attrib_position = glGetAttribLocation(Program, "Position");
attrib_scale = glGetAttribLocation(Program, "Scale");
attrib_normal = glGetAttribLocation(Program, "Normal");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
uniform_VM = glGetUniformLocation(Program, "InverseViewMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
}
void InstancedObjectRefPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
}
GLuint InstancedGrassPass1Shader::Program;
GLuint InstancedGrassPass1Shader::attrib_position;
GLuint InstancedGrassPass1Shader::attrib_normal;
@ -667,6 +705,57 @@ namespace MeshShader
}
void InstancedObjectPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
{
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());
glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height);
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
glUniform3f(uniform_ambient, s.r, s.g, s.b);
}
GLuint InstancedObjectRefPass2Shader::Program;
GLuint InstancedObjectRefPass2Shader::attrib_position;
GLuint InstancedObjectRefPass2Shader::attrib_texcoord;
GLuint InstancedObjectRefPass2Shader::attrib_origin;
GLuint InstancedObjectRefPass2Shader::attrib_orientation;
GLuint InstancedObjectRefPass2Shader::attrib_scale;
GLuint InstancedObjectRefPass2Shader::uniform_VP;
GLuint InstancedObjectRefPass2Shader::uniform_TM;
GLuint InstancedObjectRefPass2Shader::uniform_screen;
GLuint InstancedObjectRefPass2Shader::uniform_ambient;
GLuint InstancedObjectRefPass2Shader::TU_Albedo;
void InstancedObjectRefPass2Shader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanced_object_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass2.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation");
attrib_scale = glGetAttribLocation(Program, "Scale");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix");
uniform_TM = glGetUniformLocation(Program, "TextureMatrix");
GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo");
GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap");
GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO");
uniform_screen = glGetUniformLocation(Program, "screen");
uniform_ambient = glGetUniformLocation(Program, "ambient");
TU_Albedo = 3;
glUseProgram(Program);
glUniform1i(uniform_DiffuseMap, 0);
glUniform1i(uniform_SpecularMap, 1);
glUniform1i(uniform_SSAO, 2);
glUniform1i(uniform_Albedo, TU_Albedo);
glUseProgram(0);
}
void InstancedObjectRefPass2Shader::setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix)
{
glUniformMatrix4fv(uniform_VP, 1, GL_FALSE, ViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer());

View File

@ -88,6 +88,17 @@ public:
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix);
};
class InstancedObjectRefPass1Shader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_normal, attrib_texcoord, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_MP, uniform_VM, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex);
};
class InstancedGrassPass1Shader
{
public:
@ -123,6 +134,18 @@ public:
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
};
class InstancedObjectRefPass2Shader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_VP, uniform_TM, uniform_screen, uniform_ambient;
static GLuint TU_Albedo;
static void init();
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &TextureMatrix);
};
class DetailledObjectPass2Shader
{
public:

View File

@ -51,6 +51,20 @@ void STKInstancedSceneNode::createGLMeshes()
isMaterialInitialized = false;
}
template<typename T>
void setInstanceAttribPointer()
{
glEnableVertexAttribArray(T::attrib_origin);
glVertexAttribPointer(T::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(T::attrib_origin, 1);
glEnableVertexAttribArray(T::attrib_orientation);
glVertexAttribPointer(T::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(T::attrib_orientation, 1);
glEnableVertexAttribArray(T::attrib_scale);
glVertexAttribPointer(T::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(T::attrib_scale, 1);
}
void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat)
{
switch (GeoMat)
@ -61,15 +75,15 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_origin, 1);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_orientation);
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_orientation, 1);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass1Shader::attrib_scale);
glVertexAttribPointer(MeshShader::InstancedObjectPass1Shader::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedObjectPass1Shader::attrib_scale, 1);
setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader>();
break;
case FPSM_ALPHA_REF_TEXTURE:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectRefPass1Shader::attrib_position, MeshShader::InstancedObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::InstancedObjectRefPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader>();
break;
case FPSM_GRASS:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
@ -77,15 +91,7 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glGenBuffers(1, &instances_vbo);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass1Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedGrassPass1Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedGrassPass1Shader::attrib_origin, 1);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass1Shader::attrib_orientation);
glVertexAttribPointer(MeshShader::InstancedGrassPass1Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedGrassPass1Shader::attrib_orientation, 1);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass1Shader::attrib_scale);
glVertexAttribPointer(MeshShader::InstancedGrassPass1Shader::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedGrassPass1Shader::attrib_scale, 1);
setInstanceAttribPointer<MeshShader::InstancedGrassPass1Shader>();
break;
default:
return;
@ -99,29 +105,19 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectPass2Shader::attrib_position, MeshShader::InstancedObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_origin, 1);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_orientation);
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_orientation, 1);
glEnableVertexAttribArray(MeshShader::InstancedObjectPass2Shader::attrib_scale);
glVertexAttribPointer(MeshShader::InstancedObjectPass2Shader::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedObjectPass2Shader::attrib_scale, 1);
setInstanceAttribPointer<MeshShader::InstancedObjectPass2Shader>();
break;
case SM_ALPHA_REF_TEXTURE:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedObjectRefPass2Shader::attrib_position, MeshShader::InstancedObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass2Shader>();
break;
case SM_GRASS:
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::InstancedGrassPass2Shader::attrib_position, MeshShader::InstancedGrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::InstancedGrassPass2Shader::attrib_color, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass2Shader::attrib_origin);
glVertexAttribPointer(MeshShader::InstancedGrassPass2Shader::attrib_origin, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), 0);
glVertexAttribDivisor(MeshShader::InstancedGrassPass2Shader::attrib_origin, 1);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass2Shader::attrib_orientation);
glVertexAttribPointer(MeshShader::InstancedGrassPass2Shader::attrib_orientation, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*) (3 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedGrassPass2Shader::attrib_orientation, 1);
glEnableVertexAttribArray(MeshShader::InstancedGrassPass2Shader::attrib_scale);
glVertexAttribPointer(MeshShader::InstancedGrassPass2Shader::attrib_scale, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (GLvoid*)(6 * sizeof(float)));
glVertexAttribDivisor(MeshShader::InstancedGrassPass2Shader::attrib_scale, 1);
setInstanceAttribPointer<MeshShader::InstancedGrassPass2Shader>();
break;
default:
return;
@ -182,6 +178,23 @@ static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjecti
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawFSPMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
core::matrix4 InverseViewMatrix;
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawFSPMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
@ -214,6 +227,21 @@ static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjection
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::InstancedObjectRefPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, core::matrix4::EM4CONST_IDENTITY);
glBindVertexArray(mesh.vao_second_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDir, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
@ -243,6 +271,11 @@ void STKInstancedSceneNode::render()
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedObjectRefPass1Shader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
drawFSPMAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
windDir = getWind();
if (!GeometricMesh[FPSM_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassPass1Shader::Program);
@ -258,6 +291,11 @@ void STKInstancedSceneNode::render()
for (unsigned i = 0; i < ShadedMesh[FPSM_DEFAULT].size(); i++)
drawSMDefault(*ShadedMesh[FPSM_DEFAULT][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
if (!ShadedMesh[SM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedObjectRefPass2Shader::Program);
for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++)
drawSMAlphaRefTexture(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], ModelViewProjectionMatrix, instance_pos.size() / 9);
if (!ShadedMesh[SM_GRASS].empty())
glUseProgram(MeshShader::InstancedGrassPass2Shader::Program);
for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++)