Instancing: Support shadow.

This commit is contained in:
vlj
2014-03-31 21:52:42 +02:00
parent 008e5e747a
commit 52018bbdea
7 changed files with 107 additions and 15 deletions

View File

@@ -0,0 +1,14 @@
in vec3 Origin;
in vec3 Orientation;
in vec3 Scale;
in vec3 Position;
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
void main(void)
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
gl_Position = ModelMatrix * vec4(Position, 1.);
}

View File

@@ -1,4 +1,4 @@
uniform mat4 ModelViewProjectionMatrix[4];
uniform mat4 ViewProjectionMatrix[4];
#if __VERSION__ >= 400
layout(triangles, invocations=4) in;
@@ -17,7 +17,7 @@ void emitToLayer(int layerId)
for(int i=0; i<3; i++)
{
uv = tc[i];
gl_Position = ModelViewProjectionMatrix[layerId] * gl_in[i].gl_Position;
gl_Position = ViewProjectionMatrix[layerId] * gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();

View File

@@ -1,10 +1,10 @@
uniform mat4 ModelMatrix;
in vec3 Position;
in vec2 Texcoord;
out vec2 tc;
void main(void)
{
tc = Texcoord;

View File

@@ -344,6 +344,7 @@ void Shaders::loadShaders()
MeshShader::DisplaceShader::init();
MeshShader::DisplaceMaskShader::init();
MeshShader::ShadowShader::init();
MeshShader::InstancedShadowShader::init();
MeshShader::RefShadowShader::init();
MeshShader::GrassShadowShader::init();
MeshShader::SkyboxShader::init();
@@ -1379,7 +1380,8 @@ namespace MeshShader
GLuint ShadowShader::Program;
GLuint ShadowShader::attrib_position;
GLuint ShadowShader::uniform_MVP;
GLuint ShadowShader::uniform_VP;
GLuint ShadowShader::uniform_MM;
void ShadowShader::init()
{
@@ -1394,17 +1396,57 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
}
void ShadowShader::setUniforms(const std::vector<core::matrix4> &ModelViewProjectionMatrix)
void ShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix)
{
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);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
delete[] tmp;
}
GLuint InstancedShadowShader::Program;
GLuint InstancedShadowShader::attrib_position;
GLuint InstancedShadowShader::attrib_origin;
GLuint InstancedShadowShader::attrib_orientation;
GLuint InstancedShadowShader::attrib_scale;
GLuint InstancedShadowShader::uniform_VP;
void InstancedShadowShader::init()
{
// Geometry shader needed
if (irr_driver->getGLSLVersion() < 150)
{
attrib_position = -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/white.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation");
attrib_scale = glGetAttribLocation(Program, "Scale");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
}
void InstancedShadowShader::setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix)
{
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);
delete[] tmp;
}

View File

@@ -326,10 +326,21 @@ class ShadowShader
public:
static GLuint Program;
static GLuint attrib_position;
static GLuint uniform_MVP;
static GLuint uniform_VP, uniform_MM;
static void init();
static void setUniforms(const std::vector<core::matrix4> &ModelViewProjectionMatrix);
static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix);
};
class InstancedShadowShader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_VP;
static void init();
static void setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix);
};
class RefShadowShader

View File

@@ -76,6 +76,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::InstancedObjectPass1Shader>();
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedShadowShader>();
break;
case FPSM_ALPHA_REF_TEXTURE:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
@@ -178,6 +181,21 @@ static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjecti
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawShadowDefault(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());
MeshShader::InstancedShadowShader::setUniforms(ShadowMVP);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
}
static void drawFSPMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count)
{
irr_driver->IncreaseObjectCount();
@@ -302,4 +320,13 @@ void STKInstancedSceneNode::render()
drawSMGrass(*ShadedMesh[SM_GRASS][i], ModelViewProjectionMatrix, windDir, instance_pos.size() / 9);
return;
}
if (irr_driver->getPhase() == SHADOW_PASS)
{
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::InstancedShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawShadowDefault(*GeometricMesh[FPSM_DEFAULT][i], instance_pos.size() / 9);
return;
}
}

View File

@@ -685,8 +685,6 @@ void drawShadow(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);
/* if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
{
@@ -695,7 +693,7 @@ void drawShadow(const GLMesh &mesh)
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
}*/
MeshShader::ShadowShader::setUniforms(ShadowMVP);
MeshShader::ShadowShader::setUniforms(irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD), ShadowMVP);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);