GL3: Use one projection-view matrix in shaders

instead of separate projection and view matrices - this way there is
one less mat4 multiplication in the 3D vertex shaders.
This commit is contained in:
Daniel Gibson 2020-02-29 06:11:46 +01:00
parent 1eabde6b55
commit c936e43420
4 changed files with 29 additions and 25 deletions

View file

@ -1316,6 +1316,7 @@ GL3_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zF
// the following emulates glFrustum(left, right, bottom, top, zNear, zFar)
// see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml
// or http://docs.gl/gl2/glFrustum#description (looks better in non-Firefox browsers)
A = (right+left)/(right-left);
B = (top+bottom)/(top-bottom);
C = -(zFar+zNear)/(zFar-zNear);
@ -1431,7 +1432,7 @@ SetupGL(void)
{
float screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height;
float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f;
gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(gl3_newrefdef.fov_y, screenaspect, 4, dist);
gl3state.projMat3D = GL3_MYgluPerspective(gl3_newrefdef.fov_y, screenaspect, 4, dist);
}
glCullFace(GL_FRONT);
@ -1440,7 +1441,7 @@ SetupGL(void)
{
// first put Z axis going up
hmm_mat4 viewMat = {{
{ 0, 0, -1, 0 }, // first *column* (the matrix is colum-major)
{ 0, 0, -1, 0 }, // first *column* (the matrix is column-major)
{ -1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 1 }
@ -1455,9 +1456,13 @@ SetupGL(void)
hmm_vec3 trans = HMM_Vec3(-gl3_newrefdef.vieworg[0], -gl3_newrefdef.vieworg[1], -gl3_newrefdef.vieworg[2]);
viewMat = HMM_MultiplyMat4( viewMat, HMM_Translate(trans) );
gl3state.uni3DData.transViewMat4 = viewMat;
gl3state.viewMat3D = viewMat;
}
// just use one projection-view-matrix (premultiplied here)
// so we have one less mat4 multiplication in the 3D shaders
gl3state.uni3DData.transProjViewMat4 = HMM_MultiplyMat4(gl3state.projMat3D, gl3state.viewMat3D);
gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
gl3state.uni3DData.time = gl3_newrefdef.time;

View file

@ -650,7 +650,7 @@ GL3_DrawAliasModel(entity_t *entity)
vec3_t shadelight;
vec3_t shadevector;
gl3image_t *skin;
hmm_mat4 origProjMat = {0}; // use for left-handed rendering
hmm_mat4 origProjViewMat = {0}; // use for left-handed rendering
// used to restore ModelView matrix after changing it for this entities position/rotation
hmm_mat4 origModelMat = {0};
@ -817,19 +817,20 @@ GL3_DrawAliasModel(entity_t *entity)
{
extern hmm_mat4 GL3_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
origProjMat = gl3state.uni3DData.transProjMat4;
origProjViewMat = gl3state.uni3DData.transProjViewMat4;
// render weapon with a different FOV (r_gunfov) so it's not distorted at high view FOV
float screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height;
float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f;
hmm_mat4 projMat;
if (r_gunfov->value < 0)
{
gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(gl3_newrefdef.fov_y, screenaspect, 4, dist);
projMat = GL3_MYgluPerspective(gl3_newrefdef.fov_y, screenaspect, 4, dist);
}
else
{
gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(r_gunfov->value, screenaspect, 4, dist);
projMat = GL3_MYgluPerspective(r_gunfov->value, screenaspect, 4, dist);
}
if(gl_lefthand->value == 1.0F)
@ -838,12 +839,13 @@ GL3_DrawAliasModel(entity_t *entity)
// of projection matrix
for(int i=0; i<4; ++i)
{
gl3state.uni3DData.transProjMat4.Elements[0][i] = -gl3state.uni3DData.transProjMat4.Elements[0][i];
projMat.Elements[0][i] = - projMat.Elements[0][i];
}
//GL3_UpdateUBO3D(); Note: GL3_RotateForEntity() will call this,no need to do it twice before drawing
glCullFace(GL_BACK);
}
gl3state.uni3DData.transProjViewMat4 = HMM_MultiplyMat4(projMat, gl3state.viewMat3D);
}
@ -916,7 +918,7 @@ GL3_DrawAliasModel(entity_t *entity)
if (entity->flags & RF_WEAPONMODEL)
{
gl3state.uni3DData.transProjMat4 = origProjMat;
gl3state.uni3DData.transProjViewMat4 = origProjViewMat;
GL3_UpdateUBO3D();
if(gl_lefthand->value == 1.0F)
glCullFace(GL_FRONT);

View file

@ -359,8 +359,7 @@ static const char* vertexCommon3D = MULTILINE_STRING(
// for UBO shared between all 3D shaders
layout (std140) uniform uni3D
{
mat4 transProj;
mat4 transView;
mat4 transProjView;
mat4 transModel;
float scroll; // for SURF_FLOWING
@ -388,13 +387,11 @@ static const char* fragmentCommon3D = MULTILINE_STRING(
float intensity2D; // for HUD, menus etc
vec4 color; // really?
};
// for UBO shared between all 3D shaders
layout (std140) uniform uni3D
{
mat4 transProj;
mat4 transView;
mat4 transProjView;
mat4 transModel;
float scroll; // for SURF_FLOWING
@ -415,7 +412,7 @@ static const char* vertexSrc3D = MULTILINE_STRING(
void main()
{
passTexCoord = texCoord;
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
gl_Position = transProjView * transModel * vec4(position, 1.0);
}
);
@ -426,7 +423,7 @@ static const char* vertexSrc3Dflow = MULTILINE_STRING(
void main()
{
passTexCoord = texCoord + vec2(scroll, 0);
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
gl_Position = transProjView * transModel * vec4(position, 1.0);
}
);
@ -449,7 +446,7 @@ static const char* vertexSrc3Dlm = MULTILINE_STRING(
passNormal = normalize(worldNormal.xyz);
passLightFlags = lightFlags;
gl_Position = transProj * transView * worldCoord;
gl_Position = transProjView * worldCoord;
}
);
@ -472,7 +469,7 @@ static const char* vertexSrc3DlmFlow = MULTILINE_STRING(
passNormal = normalize(worldNormal.xyz);
passLightFlags = lightFlags;
gl_Position = transProj * transView * worldCoord;
gl_Position = transProjView * worldCoord;
}
);
@ -771,7 +768,7 @@ static const char* vertexSrc3Dwater = MULTILINE_STRING(
{
passTexCoord = texCoord;
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
gl_Position = transProjView * transModel * vec4(position, 1.0);
}
);
@ -785,7 +782,7 @@ static const char* vertexSrcAlias = MULTILINE_STRING(
{
passColor = vertColor*overbrightbits;
passTexCoord = texCoord;
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
gl_Position = transProjView* transModel * vec4(position, 1.0);
}
);
@ -838,7 +835,7 @@ static const char* vertexSrcParticles = MULTILINE_STRING(
void main()
{
passColor = vertColor;
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
gl_Position = transProjView * transModel * vec4(position, 1.0);
// abusing texCoord for pointSize, pointDist for particles
float pointDist = texCoord.y*0.1; // with factor 0.1 it looks good.
@ -1167,8 +1164,7 @@ static void initUBOs(void)
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uni2DData), &gl3state.uni2DData, GL_DYNAMIC_DRAW);
// the matrices will be set to something more useful later, before being used
gl3state.uni3DData.transProjMat4 = HMM_Mat4();
gl3state.uni3DData.transViewMat4 = HMM_Mat4();
gl3state.uni3DData.transProjViewMat4 = HMM_Mat4();
gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
gl3state.uni3DData.scroll = 0.0f;
gl3state.uni3DData.time = 0.0f;

View file

@ -155,8 +155,7 @@ typedef struct
typedef struct
{
hmm_mat4 transProjMat4;
hmm_mat4 transViewMat4;
hmm_mat4 transProjViewMat4; // gl3state.projMat3D * gl3state.viewMat3D - so we don't have to do this in the shader
hmm_mat4 transModelMat4;
GLfloat scroll; // for SURF_FLOWING
@ -269,6 +268,8 @@ typedef struct
GLuint uni3DUBO;
GLuint uniLightsUBO;
hmm_mat4 projMat3D;
hmm_mat4 viewMat3D;
} gl3state_t;
extern gl3config_t gl3config;