Instancing: Support for alpha ref shadow.

This commit is contained in:
vlj 2014-03-31 22:06:37 +02:00
parent 52018bbdea
commit 0fb6515bca
5 changed files with 96 additions and 10 deletions

View File

@ -3,6 +3,9 @@ in vec3 Orientation;
in vec3 Scale;
in vec3 Position;
in vec2 Texcoord;
out vec2 tc;
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
@ -11,4 +14,5 @@ void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
gl_Position = ModelMatrix * vec4(Position, 1.);
tc = Texcoord;
}

View File

@ -346,6 +346,7 @@ void Shaders::loadShaders()
MeshShader::ShadowShader::init();
MeshShader::InstancedShadowShader::init();
MeshShader::RefShadowShader::init();
MeshShader::InstancedRefShadowShader::init();
MeshShader::GrassShadowShader::init();
MeshShader::SkyboxShader::init();
ParticleShader::FlipParticleRender::init();
@ -1453,7 +1454,8 @@ namespace MeshShader
GLuint RefShadowShader::Program;
GLuint RefShadowShader::attrib_position;
GLuint RefShadowShader::attrib_texcoord;
GLuint RefShadowShader::uniform_MVP;
GLuint RefShadowShader::uniform_VP;
GLuint RefShadowShader::uniform_MM;
GLuint RefShadowShader::uniform_tex;
void RefShadowShader::init()
@ -1471,18 +1473,64 @@ namespace MeshShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
}
void RefShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix, unsigned TU_tex)
{
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
delete[] tmp;
}
GLuint InstancedRefShadowShader::Program;
GLuint InstancedRefShadowShader::attrib_position;
GLuint InstancedRefShadowShader::attrib_texcoord;
GLuint InstancedRefShadowShader::attrib_origin;
GLuint InstancedRefShadowShader::attrib_orientation;
GLuint InstancedRefShadowShader::attrib_scale;
GLuint InstancedRefShadowShader::uniform_VP;
GLuint InstancedRefShadowShader::uniform_tex;
void InstancedRefShadowShader::init()
{
// Geometry shader needed
if (irr_driver->getGLSLVersion() < 150)
{
attrib_position = -1;
attrib_texcoord = -1;
return;
}
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/utils/getworldmatrix.vert").c_str(),
GL_VERTEX_SHADER, file_manager->getAsset("shaders/instanciedshadow.vert").c_str(),
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.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[0]");
uniform_tex = glGetUniformLocation(Program, "tex");
}
void RefShadowShader::setUniforms(const std::vector<core::matrix4> &ModelViewProjectionMatrix, unsigned TU_tex)
void InstancedRefShadowShader::setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix, unsigned TU_tex)
{
size_t size = ModelViewProjectionMatrix.size();
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ModelViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_MVP, size, GL_FALSE, tmp);
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
glUniform1i(uniform_tex, TU_tex);
delete[] tmp;
}

View File

@ -348,7 +348,18 @@ class RefShadowShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord;
static GLuint uniform_MVP, uniform_tex;
static GLuint uniform_VP, uniform_MM, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ModelViewProjectionMatrix, unsigned TU_tex);
};
class InstancedRefShadowShader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_VP, uniform_tex;
static void init();
static void setUniforms(const std::vector<core::matrix4> &ModelViewProjectionMatrix, unsigned TU_tex);

View File

@ -87,6 +87,9 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader>();
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedRefShadowShader>();
break;
case FPSM_GRASS:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
@ -213,6 +216,23 @@ static void drawFSPMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelView
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedRefShadowShader::setUniforms(ShadowMVP, 0);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_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();
@ -327,6 +347,11 @@ void STKInstancedSceneNode::render()
glUseProgram(MeshShader::InstancedShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawShadowDefault(*GeometricMesh[FPSM_DEFAULT][i], instance_pos.size() / 9);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::InstancedRefShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
drawShadowAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], instance_pos.size() / 9);
return;
}
}

View File

@ -666,11 +666,9 @@ void drawShadowRef(const GLMesh &mesh)
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
for (unsigned i = 0; i < ShadowMVP.size(); i++)
ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0);
MeshShader::RefShadowShader::setUniforms(irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD), ShadowMVP, 0);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);