Explicitly build the inverse matrix

Some drivers does not support inverse function although they advertise
glsl 140 support, and it's faster  to do it manually as we know the
structure of the matrix.
This commit is contained in:
vlj
2014-03-27 19:12:55 +01:00
parent 3538fd46d2
commit c70b9ba0f8
4 changed files with 34 additions and 31 deletions

View File

@@ -1,6 +1,6 @@
uniform vec3 windDir;
uniform mat4 ViewProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 InverseViewMatrix;
in vec3 Origin;
in vec3 Orientation;
@@ -13,8 +13,9 @@ in vec4 Color;
out vec3 nor;
out vec2 uv;
mat4 getWorldMatrix(vec3 origin, vec3 rotation)
mat4 getMatrixFromRotation(vec3 rotation)
{
// from irrlicht
float cr = cos( rotation.z );
float sr = sin( rotation.z );
@@ -26,37 +27,33 @@ mat4 getWorldMatrix(vec3 origin, vec3 rotation)
float srsp = sr*sp;
float crsp = cr*sp;
// rotation part
mat4 result = mat4(
return mat4(
vec4(cp * cy, srsp * cy - cr * sy, crsp * cy + sr * sy, 0.),
vec4(cp * sy, srsp * sy + cr * cy, crsp * sy - sr * cy, 0.),
vec4(-sp, sr * cp, cr * cp, 0.),
vec4(0., 0., 0., 1.));
// translation
result[3].xyz += origin;
return result;
/* M[0] = (T)( cp*cy );
M[1] = (T)( cp*sy );
M[2] = (T)( -sp );
const f64 srsp = sr*sp;
const f64 crsp = cr*sp;
M[4] = (T)( srsp*cy-cr*sy );
M[5] = (T)( srsp*sy+cr*cy );
M[6] = (T)( sr*cp );
M[8] = (T)( crsp*cy+sr*sy );
M[9] = (T)( crsp*sy-sr*cy );
M[10] = (T)( cr*cp );*/
}
mat4 getWorldMatrix(vec3 translation, vec3 rotation)
{
mat4 result = getMatrixFromRotation(rotation);
// translation
result[3].xyz += translation;
return result;
}
mat4 getInverseWorldMatrix(vec3 translation, vec3 rotation)
{
mat4 result = transpose(getMatrixFromRotation(rotation));
// FIXME: it's wrong but the fourth column is not used
result[3].xyz -= translation;
return result;
}
void main()
{
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation);
mat4 TransposeInverseModelView = transpose(inverse(ViewMatrix * ModelMatrix));
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation) * InverseViewMatrix);
gl_Position = ViewProjectionMatrix * ModelMatrix * vec4(Position + windDir * Color.r, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
uv = Texcoord;

View File

@@ -538,7 +538,7 @@ namespace MeshShader
GLuint InstancedGrassPass1Shader::attrib_texcoord;
GLuint InstancedGrassPass1Shader::attrib_color;
GLuint InstancedGrassPass1Shader::uniform_MP;
GLuint InstancedGrassPass1Shader::uniform_VM;
GLuint InstancedGrassPass1Shader::uniform_IVM;
GLuint InstancedGrassPass1Shader::uniform_windDir;
GLuint InstancedGrassPass1Shader::uniform_tex;
@@ -555,15 +555,15 @@ namespace MeshShader
attrib_color = glGetAttribLocation(Program, "Color");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
uniform_VM = glGetUniformLocation(Program, "ViewMatrix");
uniform_IVM = glGetUniformLocation(Program, "InverseViewMatrix");
uniform_windDir = glGetUniformLocation(Program, "windDir");
uniform_tex = glGetUniformLocation(Program, "tex");
}
void InstancedGrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix, const core::vector3df &windDir, unsigned TU_tex)
void InstancedGrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::vector3df &windDir, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
glUniformMatrix4fv(uniform_IVM, 1, GL_FALSE, InverseViewMatrix.pointer());
glUniform3f(uniform_windDir, windDir.X, windDir.Y, windDir.Z);
glUniform1i(uniform_tex, TU_tex);
}

View File

@@ -93,10 +93,10 @@ class InstancedGrassPass1Shader
public:
static GLuint Program;
static GLuint attrib_position, attrib_normal, attrib_origin, attrib_orientation, attrib_color, attrib_texcoord;
static GLuint uniform_MP, uniform_VM, uniform_windDir, uniform_tex;
static GLuint uniform_MP, uniform_IVM, uniform_windDir, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix, const core::vector3df &windDir, unsigned TU_tex);
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &InverseViewMatrix, const core::vector3df &windDir, unsigned TU_tex);
};
class ObjectPass2Shader

View File

@@ -120,7 +120,10 @@ static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjecti
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
core::matrix4 InverseViewMatrix;
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
@@ -133,8 +136,11 @@ static void drawFSPMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjection
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::InstancedGrassPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW), windDir, 0);
MeshShader::InstancedGrassPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, windDir, 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);