mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-13 00:24:44 +00:00
GL3: Split up transModelViewMat4 matrix
This commit is contained in:
parent
ea6dacbc12
commit
35daa08c23
6 changed files with 48 additions and 90 deletions
|
@ -80,6 +80,13 @@ static float v_blend[4]; /* final blending color */
|
||||||
|
|
||||||
int gl3_viewcluster, gl3_viewcluster2, gl3_oldviewcluster, gl3_oldviewcluster2;
|
int gl3_viewcluster, gl3_viewcluster2, gl3_oldviewcluster, gl3_oldviewcluster2;
|
||||||
|
|
||||||
|
const hmm_mat4 gl3_identityMat4 = {{
|
||||||
|
{1, 0, 0, 0},
|
||||||
|
{0, 1, 0, 0},
|
||||||
|
{0, 0, 1, 0},
|
||||||
|
{0, 0, 0, 1},
|
||||||
|
}};
|
||||||
|
|
||||||
cvar_t *gl_msaa_samples;
|
cvar_t *gl_msaa_samples;
|
||||||
cvar_t *gl_swapinterval;
|
cvar_t *gl_swapinterval;
|
||||||
cvar_t *gl_retexturing;
|
cvar_t *gl_retexturing;
|
||||||
|
@ -163,7 +170,7 @@ GL3_RotateForEntity(entity_t *e)
|
||||||
transMat.Elements[3][i] = e->origin[i]; // set translation
|
transMat.Elements[3][i] = e->origin[i]; // set translation
|
||||||
}
|
}
|
||||||
|
|
||||||
gl3state.uni3DData.transModelViewMat4 = HMM_MultiplyMat4(gl3state.uni3DData.transModelViewMat4, transMat);
|
gl3state.uni3DData.transModelMat4 = HMM_MultiplyMat4(gl3state.uni3DData.transModelMat4, transMat);
|
||||||
|
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
}
|
}
|
||||||
|
@ -769,7 +776,7 @@ GL3_DrawNullModel(void)
|
||||||
GL3_LightPoint(currententity->origin, shadelight);
|
GL3_LightPoint(currententity->origin, shadelight);
|
||||||
}
|
}
|
||||||
|
|
||||||
hmm_mat4 origMVmat = gl3state.uni3DData.transModelViewMat4;
|
hmm_mat4 origModelMat = gl3state.uni3DData.transModelMat4;
|
||||||
GL3_RotateForEntity(currententity);
|
GL3_RotateForEntity(currententity);
|
||||||
|
|
||||||
gl3state.uniCommonData.color = HMM_Vec4( shadelight[0], shadelight[1], shadelight[2], 1 );
|
gl3state.uniCommonData.color = HMM_Vec4( shadelight[0], shadelight[1], shadelight[2], 1 );
|
||||||
|
@ -800,7 +807,7 @@ GL3_DrawNullModel(void)
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vtxB), vtxB, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vtxB), vtxB, GL_STREAM_DRAW);
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
|
||||||
|
|
||||||
gl3state.uni3DData.transModelViewMat4 = origMVmat;
|
gl3state.uni3DData.transModelMat4 = origModelMat;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,7 +1261,8 @@ SetupGL(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
gl3state.uni3DData.transProjMat4 = gl3_projectionMatrix;
|
gl3state.uni3DData.transProjMat4 = gl3_projectionMatrix;
|
||||||
gl3state.uni3DData.transModelViewMat4 = gl3_world_matrix;
|
gl3state.uni3DData.transViewMat4 = gl3_world_matrix;
|
||||||
|
gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
|
||||||
|
|
||||||
gl3state.uni3DData.time = gl3_newrefdef.time;
|
gl3state.uni3DData.time = gl3_newrefdef.time;
|
||||||
|
|
||||||
|
|
|
@ -558,7 +558,7 @@ GL3_DrawAliasModel(entity_t *e)
|
||||||
gl3image_t *skin;
|
gl3image_t *skin;
|
||||||
hmm_mat4 origProjMat = {0}; // use for left-handed rendering
|
hmm_mat4 origProjMat = {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 origMVmat = {0};
|
hmm_mat4 origModelMat = {0};
|
||||||
|
|
||||||
if (!(e->flags & RF_WEAPONMODEL))
|
if (!(e->flags & RF_WEAPONMODEL))
|
||||||
{
|
{
|
||||||
|
@ -740,7 +740,7 @@ GL3_DrawAliasModel(entity_t *e)
|
||||||
|
|
||||||
|
|
||||||
//glPushMatrix();
|
//glPushMatrix();
|
||||||
origMVmat = gl3state.uni3DData.transModelViewMat4;
|
origModelMat = gl3state.uni3DData.transModelMat4;
|
||||||
|
|
||||||
e->angles[PITCH] = -e->angles[PITCH];
|
e->angles[PITCH] = -e->angles[PITCH];
|
||||||
GL3_RotateForEntity(e);
|
GL3_RotateForEntity(e);
|
||||||
|
@ -823,7 +823,7 @@ GL3_DrawAliasModel(entity_t *e)
|
||||||
//glShadeModel(GL_FLAT);
|
//glShadeModel(GL_FLAT);
|
||||||
|
|
||||||
//glPopMatrix();
|
//glPopMatrix();
|
||||||
gl3state.uni3DData.transModelViewMat4 = origMVmat;
|
gl3state.uni3DData.transModelMat4 = origModelMat;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,8 @@ static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
|
||||||
layout (std140) uniform uni3D
|
layout (std140) uniform uni3D
|
||||||
{
|
{
|
||||||
mat4 transProj;
|
mat4 transProj;
|
||||||
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
|
mat4 transView;
|
||||||
|
mat4 transModel;
|
||||||
vec2 lmOffset;
|
vec2 lmOffset;
|
||||||
float scroll; // for SURF_FLOWING
|
float scroll; // for SURF_FLOWING
|
||||||
float time;
|
float time;
|
||||||
|
@ -300,7 +301,8 @@ static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n
|
||||||
layout (std140) uniform uni3D
|
layout (std140) uniform uni3D
|
||||||
{
|
{
|
||||||
mat4 transProj;
|
mat4 transProj;
|
||||||
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
|
mat4 transView;
|
||||||
|
mat4 transModel;
|
||||||
vec2 lmOffset;
|
vec2 lmOffset;
|
||||||
float scroll; // for SURF_FLOWING
|
float scroll; // for SURF_FLOWING
|
||||||
float time;
|
float time;
|
||||||
|
@ -317,7 +319,7 @@ static const char* vertexSrc3D = MULTILINE_STRING(
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
passTexCoord = texCoord;
|
passTexCoord = texCoord;
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -328,7 +330,7 @@ static const char* vertexSrc3Dflow = MULTILINE_STRING(
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
passTexCoord = texCoord + vec2(0, scroll);
|
passTexCoord = texCoord + vec2(0, scroll);
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -345,11 +347,13 @@ static const char* vertexSrc3Dlm = MULTILINE_STRING(
|
||||||
{
|
{
|
||||||
passTexCoord = texCoord;
|
passTexCoord = texCoord;
|
||||||
passLMcoord = lmTexCoord;
|
passLMcoord = lmTexCoord;
|
||||||
passWorldCoord = position; // TODO: multiply with model matrix for brush-based entities
|
vec4 worldCoord = transModel * vec4(position, 1.0);
|
||||||
passNormal = normalize(normal); // TODO: multiply with model matrix and normalize
|
passWorldCoord = worldCoord.xyz;
|
||||||
|
vec4 worldNormal = transModel * vec4(normal, 0.0f);
|
||||||
|
passNormal = normalize(worldNormal.xyz);
|
||||||
passLightFlags = lightFlags;
|
passLightFlags = lightFlags;
|
||||||
|
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * worldCoord;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -366,11 +370,13 @@ static const char* vertexSrc3DlmFlow = MULTILINE_STRING(
|
||||||
{
|
{
|
||||||
passTexCoord = texCoord + vec2(0, scroll);
|
passTexCoord = texCoord + vec2(0, scroll);
|
||||||
passLMcoord = lmTexCoord;
|
passLMcoord = lmTexCoord;
|
||||||
passWorldCoord = position; // TODO: multiply with model matrix for brush-based entities
|
vec4 worldCoord = transModel * vec4(position, 1.0);
|
||||||
passNormal = normalize(normal); // TODO: multiply with model matrix and normalize
|
passWorldCoord = worldCoord.xyz;
|
||||||
|
vec4 worldNormal = transModel * vec4(normal, 0.0f);
|
||||||
|
passNormal = normalize(worldNormal.xyz);
|
||||||
passLightFlags = lightFlags;
|
passLightFlags = lightFlags;
|
||||||
|
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * worldCoord;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -458,8 +464,7 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING(
|
||||||
if(passLightFlags != 0u)
|
if(passLightFlags != 0u)
|
||||||
{
|
{
|
||||||
// TODO: or is hardcoding 32 better?
|
// TODO: or is hardcoding 32 better?
|
||||||
//for(uint i=0u; i<numDynLights; ++i)
|
for(uint i=0u; i<numDynLights; ++i)
|
||||||
for(uint i=0u; i < 32u; ++i)
|
|
||||||
{
|
{
|
||||||
// I made the following up, it's probably not too cool..
|
// I made the following up, it's probably not too cool..
|
||||||
// it basically checks if the light is on the right side of the surface
|
// it basically checks if the light is on the right side of the surface
|
||||||
|
@ -572,7 +577,7 @@ static const char* vertexSrc3Dwater = MULTILINE_STRING(
|
||||||
tc *= 1.0/64.0; // do this last
|
tc *= 1.0/64.0; // do this last
|
||||||
passTexCoord = tc;
|
passTexCoord = tc;
|
||||||
|
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -586,7 +591,7 @@ static const char* vertexSrcAlias = MULTILINE_STRING(
|
||||||
{
|
{
|
||||||
passColor = vertColor*overbrightbits;
|
passColor = vertColor*overbrightbits;
|
||||||
passTexCoord = texCoord;
|
passTexCoord = texCoord;
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * transModel * vec4(position, 1.0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -641,7 +646,7 @@ static const char* vertexSrcParticles = MULTILINE_STRING(
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
passColor = vertColor;
|
passColor = vertColor;
|
||||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
gl_Position = transProj * transView * 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.
|
||||||
|
@ -940,7 +945,8 @@ static void initUBOs(void)
|
||||||
|
|
||||||
// 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.transProjMat4 = HMM_Mat4();
|
||||||
gl3state.uni3DData.transModelViewMat4 = HMM_Mat4();
|
gl3state.uni3DData.transViewMat4 = HMM_Mat4();
|
||||||
|
gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
|
||||||
gl3state.uni3DData.lmOffset = HMM_Vec2(0.0f, 0.0f);
|
gl3state.uni3DData.lmOffset = HMM_Vec2(0.0f, 0.0f);
|
||||||
gl3state.uni3DData.scroll = 0.0f;
|
gl3state.uni3DData.scroll = 0.0f;
|
||||||
gl3state.uni3DData.time = 0.0f;
|
gl3state.uni3DData.time = 0.0f;
|
||||||
|
|
|
@ -336,37 +336,9 @@ RenderBrushPoly(msurface_t *fa)
|
||||||
GL3_Bind(image->texnum);
|
GL3_Bind(image->texnum);
|
||||||
|
|
||||||
STUB_ONCE("TODO: do something about inverse intensity on water surfaces b/c they have no lightmap!");
|
STUB_ONCE("TODO: do something about inverse intensity on water surfaces b/c they have no lightmap!");
|
||||||
#if 0 // TODO
|
|
||||||
/* This is a hack ontop of a hack. Warping surfaces like those generated
|
|
||||||
by R_EmitWaterPolys() don't have a lightmap. Original Quake II therefore
|
|
||||||
negated the global intensity on those surfaces, because otherwise they
|
|
||||||
would show up much too bright. When we implemented overbright bits this
|
|
||||||
hack modified the global GL state in an incompatible way. So implement
|
|
||||||
a new hack, based on overbright bits... Depending on the value set to
|
|
||||||
gl_overbrightbits the result is different:
|
|
||||||
|
|
||||||
0: Old behaviour.
|
|
||||||
1: No overbright bits on the global scene but correct lightning on
|
|
||||||
warping surfaces.
|
|
||||||
2: Overbright bits on the global scene but not on warping surfaces.
|
|
||||||
They oversaturate otherwise. */
|
|
||||||
if (gl_overbrightbits->value)
|
|
||||||
{
|
|
||||||
R_TexEnv(GL_COMBINE_EXT);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
R_TexEnv(GL_MODULATE);
|
|
||||||
glColor4f(gl3state.inverse_intensity, gl3state.inverse_intensity,
|
|
||||||
gl3state.inverse_intensity, 1.0f);
|
|
||||||
}
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
GL3_EmitWaterPolys(fa);
|
GL3_EmitWaterPolys(fa);
|
||||||
|
|
||||||
//R_TexEnv(GL_REPLACE); TODO
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -417,7 +389,7 @@ GL3_DrawAlphaSurfaces(void)
|
||||||
msurface_t *s;
|
msurface_t *s;
|
||||||
|
|
||||||
/* go back to the world matrix */
|
/* go back to the world matrix */
|
||||||
gl3state.uni3DData.transModelViewMat4 = gl3_world_matrix;
|
gl3state.uni3DData.transModelMat4 = gl3_identityMat4;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -540,37 +512,6 @@ RenderLightmappedPoly(msurface_t *surf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // TODO!
|
|
||||||
if (is_dynamic)
|
|
||||||
{
|
|
||||||
// Dynamic lights on a surface - NOTE: this is handled via lmScales
|
|
||||||
if (((surf->styles[map] >= 32) || (surf->styles[map] == 0)) && (surf->dlightframe != r_framecount))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else // Normal dynamic lights - NOTE: This is still missing, but will not be done by creating a dynamic lightmap.
|
|
||||||
{
|
|
||||||
smax = (surf->extents[0] >> 4) + 1;
|
|
||||||
tmax = (surf->extents[1] >> 4) + 1;
|
|
||||||
|
|
||||||
GL3_BuildLightMap(surf, (void *) temp, smax * 4);
|
|
||||||
//R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + 0);
|
|
||||||
GL3_BindLightmap(0);
|
|
||||||
|
|
||||||
lmtex = 0;
|
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, surf->light_s, surf->light_t, smax,
|
|
||||||
tmax, GL_LIGHTMAP_FORMAT, GL_UNSIGNED_BYTE, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_brush_polys++;
|
|
||||||
|
|
||||||
R_MBind(GL_TEXTURE0_ARB, image->texnum);
|
|
||||||
R_MBind(GL_TEXTURE1_ARB, gl_state.lightmap_textures + lmtex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
c_brush_polys++;
|
c_brush_polys++;
|
||||||
|
|
||||||
GL3_Bind(image->texnum);
|
GL3_Bind(image->texnum);
|
||||||
|
@ -719,7 +660,7 @@ GL3_DrawBrushModel(entity_t *e)
|
||||||
|
|
||||||
|
|
||||||
//glPushMatrix();
|
//glPushMatrix();
|
||||||
hmm_mat4 oldMat = gl3state.uni3DData.transModelViewMat4;
|
hmm_mat4 oldMat = gl3state.uni3DData.transModelMat4;
|
||||||
|
|
||||||
e->angles[0] = -e->angles[0];
|
e->angles[0] = -e->angles[0];
|
||||||
e->angles[2] = -e->angles[2];
|
e->angles[2] = -e->angles[2];
|
||||||
|
@ -745,7 +686,7 @@ GL3_DrawBrushModel(entity_t *e)
|
||||||
DrawInlineBModel();
|
DrawInlineBModel();
|
||||||
|
|
||||||
// glPopMatrix();
|
// glPopMatrix();
|
||||||
gl3state.uni3DData.transModelViewMat4 = oldMat;
|
gl3state.uni3DData.transModelMat4 = oldMat;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
|
|
||||||
if (gl_zfix->value)
|
if (gl_zfix->value)
|
||||||
|
|
|
@ -681,18 +681,18 @@ GL3_DrawSkyBox(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// glPushMatrix();
|
// glPushMatrix();
|
||||||
hmm_mat4 origMVmat = gl3state.uni3DData.transModelViewMat4;
|
hmm_mat4 origModelMat = gl3state.uni3DData.transModelMat4;
|
||||||
|
|
||||||
// glTranslatef(gl3_origin[0], gl3_origin[1], gl3_origin[2]);
|
// glTranslatef(gl3_origin[0], gl3_origin[1], gl3_origin[2]);
|
||||||
hmm_vec3 transl = HMM_Vec3(gl3_origin[0], gl3_origin[1], gl3_origin[2]);
|
hmm_vec3 transl = HMM_Vec3(gl3_origin[0], gl3_origin[1], gl3_origin[2]);
|
||||||
hmm_mat4 modMVmat = HMM_MultiplyMat4(origMVmat, HMM_Translate(transl));
|
hmm_mat4 modMVmat = HMM_MultiplyMat4(origModelMat, HMM_Translate(transl));
|
||||||
if(skyrotate != 0.0f)
|
if(skyrotate != 0.0f)
|
||||||
{
|
{
|
||||||
// glRotatef(gl3_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]);
|
// glRotatef(gl3_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]);
|
||||||
hmm_vec3 rotAxis = HMM_Vec3(skyaxis[0], skyaxis[1], skyaxis[2]);
|
hmm_vec3 rotAxis = HMM_Vec3(skyaxis[0], skyaxis[1], skyaxis[2]);
|
||||||
modMVmat = HMM_MultiplyMat4(modMVmat, HMM_Rotate(gl3_newrefdef.time * skyrotate, rotAxis));
|
modMVmat = HMM_MultiplyMat4(modMVmat, HMM_Rotate(gl3_newrefdef.time * skyrotate, rotAxis));
|
||||||
}
|
}
|
||||||
gl3state.uni3DData.transModelViewMat4 = modMVmat;
|
gl3state.uni3DData.transModelMat4 = modMVmat;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
|
|
||||||
GL3_UseProgram(gl3state.si3Dsky.shaderProgram);
|
GL3_UseProgram(gl3state.si3Dsky.shaderProgram);
|
||||||
|
@ -731,6 +731,6 @@ GL3_DrawSkyBox(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// glPopMatrix();
|
// glPopMatrix();
|
||||||
gl3state.uni3DData.transModelViewMat4 = origMVmat;
|
gl3state.uni3DData.transModelMat4 = origModelMat;
|
||||||
GL3_UpdateUBO3D();
|
GL3_UpdateUBO3D();
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,8 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
hmm_mat4 transProjMat4;
|
hmm_mat4 transProjMat4;
|
||||||
hmm_mat4 transModelViewMat4;
|
hmm_mat4 transViewMat4;
|
||||||
|
hmm_mat4 transModelMat4;
|
||||||
|
|
||||||
hmm_vec2 lmOffset;
|
hmm_vec2 lmOffset;
|
||||||
|
|
||||||
|
@ -150,6 +151,8 @@ typedef struct
|
||||||
GLfloat _padding[2]; // again, some padding to ensure this has right size
|
GLfloat _padding[2]; // again, some padding to ensure this has right size
|
||||||
} gl3Uni3D_t;
|
} gl3Uni3D_t;
|
||||||
|
|
||||||
|
extern const hmm_mat4 gl3_identityMat4;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
|
|
Loading…
Reference in a new issue