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) // the following emulates glFrustum(left, right, bottom, top, zNear, zFar)
// see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glFrustum.xml // 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); A = (right+left)/(right-left);
B = (top+bottom)/(top-bottom); B = (top+bottom)/(top-bottom);
C = -(zFar+zNear)/(zFar-zNear); C = -(zFar+zNear)/(zFar-zNear);
@ -1431,7 +1432,7 @@ SetupGL(void)
{ {
float screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height; float screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height;
float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; 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); glCullFace(GL_FRONT);
@ -1440,7 +1441,7 @@ SetupGL(void)
{ {
// first put Z axis going up // first put Z axis going up
hmm_mat4 viewMat = {{ 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 }, { -1, 0, 0, 0 },
{ 0, 1, 0, 0 }, { 0, 1, 0, 0 },
{ 0, 0, 0, 1 } { 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]); hmm_vec3 trans = HMM_Vec3(-gl3_newrefdef.vieworg[0], -gl3_newrefdef.vieworg[1], -gl3_newrefdef.vieworg[2]);
viewMat = HMM_MultiplyMat4( viewMat, HMM_Translate(trans) ); 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.transModelMat4 = gl3_identityMat4;
gl3state.uni3DData.time = gl3_newrefdef.time; gl3state.uni3DData.time = gl3_newrefdef.time;

View file

@ -650,7 +650,7 @@ GL3_DrawAliasModel(entity_t *entity)
vec3_t shadelight; vec3_t shadelight;
vec3_t shadevector; vec3_t shadevector;
gl3image_t *skin; 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 // used to restore ModelView matrix after changing it for this entities position/rotation
hmm_mat4 origModelMat = {0}; 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); 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 // 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 screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height;
float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f;
hmm_mat4 projMat;
if (r_gunfov->value < 0) 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 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) if(gl_lefthand->value == 1.0F)
@ -838,12 +839,13 @@ GL3_DrawAliasModel(entity_t *entity)
// of projection matrix // of projection matrix
for(int i=0; i<4; ++i) 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 //GL3_UpdateUBO3D(); Note: GL3_RotateForEntity() will call this,no need to do it twice before drawing
glCullFace(GL_BACK); 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) if (entity->flags & RF_WEAPONMODEL)
{ {
gl3state.uni3DData.transProjMat4 = origProjMat; gl3state.uni3DData.transProjViewMat4 = origProjViewMat;
GL3_UpdateUBO3D(); GL3_UpdateUBO3D();
if(gl_lefthand->value == 1.0F) if(gl_lefthand->value == 1.0F)
glCullFace(GL_FRONT); glCullFace(GL_FRONT);

View file

@ -359,8 +359,7 @@ static const char* vertexCommon3D = MULTILINE_STRING(
// for UBO shared between all 3D shaders // for UBO shared between all 3D shaders
layout (std140) uniform uni3D layout (std140) uniform uni3D
{ {
mat4 transProj; mat4 transProjView;
mat4 transView;
mat4 transModel; mat4 transModel;
float scroll; // for SURF_FLOWING float scroll; // for SURF_FLOWING
@ -388,13 +387,11 @@ static const char* fragmentCommon3D = MULTILINE_STRING(
float intensity2D; // for HUD, menus etc float intensity2D; // for HUD, menus etc
vec4 color; // really? vec4 color; // really?
}; };
// for UBO shared between all 3D shaders // for UBO shared between all 3D shaders
layout (std140) uniform uni3D layout (std140) uniform uni3D
{ {
mat4 transProj; mat4 transProjView;
mat4 transView;
mat4 transModel; mat4 transModel;
float scroll; // for SURF_FLOWING float scroll; // for SURF_FLOWING
@ -415,7 +412,7 @@ static const char* vertexSrc3D = MULTILINE_STRING(
void main() void main()
{ {
passTexCoord = texCoord; 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() void main()
{ {
passTexCoord = texCoord + vec2(scroll, 0); 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); passNormal = normalize(worldNormal.xyz);
passLightFlags = lightFlags; 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); passNormal = normalize(worldNormal.xyz);
passLightFlags = lightFlags; passLightFlags = lightFlags;
gl_Position = transProj * transView * worldCoord; gl_Position = transProjView * worldCoord;
} }
); );
@ -771,7 +768,7 @@ static const char* vertexSrc3Dwater = MULTILINE_STRING(
{ {
passTexCoord = texCoord; 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; passColor = vertColor*overbrightbits;
passTexCoord = texCoord; 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() void main()
{ {
passColor = vertColor; 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 // abusing texCoord for pointSize, pointDist for particles
float pointDist = texCoord.y*0.1; // with factor 0.1 it looks good. 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); 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 // the matrices will be set to something more useful later, before being used
gl3state.uni3DData.transProjMat4 = HMM_Mat4(); gl3state.uni3DData.transProjViewMat4 = HMM_Mat4();
gl3state.uni3DData.transViewMat4 = HMM_Mat4();
gl3state.uni3DData.transModelMat4 = gl3_identityMat4; gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
gl3state.uni3DData.scroll = 0.0f; gl3state.uni3DData.scroll = 0.0f;
gl3state.uni3DData.time = 0.0f; gl3state.uni3DData.time = 0.0f;

View file

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