- completely separated view and model matrix.

This way the view matrix will remain constant per scene and an update of the model matrix is only needed for rendering a model or voxel, reducing the total amount of generated matrices to the point where they can be written to a buffer instead of constantly uploading them as uniforms.
This commit is contained in:
Christoph Oelckers 2020-01-19 16:06:31 +01:00
parent 11cbdb9fef
commit c8fa2443d3
6 changed files with 67 additions and 95 deletions

View file

@ -1427,23 +1427,26 @@ int md3postload_polymer(md3model_t *m)
void md3_vox_calcmat_common(tspriteptr_t tspr, const vec3f_t *a0, float f, float mat[16]) void md3_vox_calcmat_common(tspriteptr_t tspr, const vec3f_t *a0, float f, float mat[16])
{ {
float g;
float k0, k1, k2, k3, k4, k5, k6, k7; float k0, k1, k2, k3, k4, k5, k6, k7;
k0 = ((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))*f*(1.f/1024.f); k0 = ((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))*f*(1.f/1024.f);
k1 = ((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy))*f*(1.f/1024.f); k1 = ((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy))*f*(1.f/1024.f);
f = gcosang2*gshang/gvrcorrection;
g = gsinang2*gshang/gvrcorrection;
k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] * (1.f/16384.f); k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] * (1.f/16384.f);
k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] * (1.f/16384.f); k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] * (1.f/16384.f);
k2 = k0*(1-k4)+k1*k5; k2 = k0*(1-k4)+k1*k5;
k3 = k1*(1-k4)-k0*k5; k3 = k1*(1-k4)-k0*k5;
k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang; k6 = - gsinang;
mat[0] = k4*k6 + k5*k7; mat[4] = gchang*gstang; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7; k7 = gcosang;
k6 = f*gctang + gsinang*gstang; k7 = g*gctang - gcosang*gstang; mat[0] = k4*k6 + k5*k7; mat[4] = 0; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7;
mat[1] = k4*k6 + k5*k7; mat[5] = gchang*gctang; mat[ 9] = k4*k7 - k5*k6; mat[13] = k2*k6 + k3*k7;
k6 = gcosang2*gchang; k7 = gsinang2*gchang; mat[1] = 0; mat[5] = 1; mat[ 9] = 0; mat[13] = 0;
mat[2] = k4*k6 + k5*k7; mat[6] =-gshang*gvrcorrection; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7;
k6 = gcosang2;
k7 = gsinang2;
mat[2] = k4*k6 + k5*k7;
mat[6] =0;
mat[10] = k4*k7 - k5*k6;
mat[14] = k2*k6 + k3*k7;
mat[12] = (mat[12] + a0->y*mat[0]) + (a0->z*mat[4] + a0->x*mat[ 8]); mat[12] = (mat[12] + a0->y*mat[0]) + (a0->z*mat[4] + a0->x*mat[ 8]);
mat[13] = (mat[13] + a0->y*mat[1]) + (a0->z*mat[5] + a0->x*mat[ 9]); mat[13] = (mat[13] + a0->y*mat[1]) + (a0->z*mat[5] + a0->x*mat[ 9]);
@ -1642,6 +1645,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
int prevClamp = GLInterface.GetClamp(); int prevClamp = GLInterface.GetClamp();
GLInterface.SetClamp(0); GLInterface.SetClamp(0);
auto matrixindex = GLInterface.SetIdentityMatrix(Matrix_Model);
for (surfi=0; surfi<m->head.numsurfs; surfi++) for (surfi=0; surfi<m->head.numsurfs; surfi++)
{ {
@ -1696,7 +1700,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
//Let OpenGL (and perhaps hardware :) handle the matrix rotation //Let OpenGL (and perhaps hardware :) handle the matrix rotation
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
GLInterface.SetMatrix(Matrix_ModelView, mat); GLInterface.SetMatrix(Matrix_Model, mat);
// PLAG: End // PLAG: End
bool exact = false; bool exact = false;
@ -1786,7 +1790,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
GLInterface.SetCull(Cull_None); GLInterface.SetCull(Cull_None);
VSMatrix identity(0); VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView); GLInterface.RestoreMatrix(Matrix_Model, matrixindex);
GLInterface.SetTinting(-1, 0xffffff, 0xffffff); GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
GLInterface.SetClamp(prevClamp); GLInterface.SetClamp(prevClamp);

View file

@ -302,7 +302,7 @@ static void resizeglcheck(void)
m[2][3] = 1.f; m[2][3] = 1.f;
m[3][2] = -(2.f * farclip * nearclip) / (farclip - nearclip); m[3][2] = -(2.f * farclip * nearclip) / (farclip - nearclip);
GLInterface.SetMatrix(Matrix_Projection, &m[0][0]); GLInterface.SetMatrix(Matrix_Projection, &m[0][0]);
GLInterface.SetIdentityMatrix(Matrix_ModelView); GLInterface.SetIdentityMatrix(Matrix_Model);
} }
} }
@ -391,11 +391,6 @@ static void polymost_updaterotmat(void)
GLInterface.SetMatrix(Matrix_View, matrix); GLInterface.SetMatrix(Matrix_View, matrix);
} }
static void polymost_identityrotmat(void)
{
GLInterface.SetIdentityMatrix(Matrix_View);
}
static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t& tilesiz); static void polymost_flatskyrender(vec2f_t const* const dpxy, int32_t const n, int32_t method, const vec2_16_t& tilesiz);
static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize) static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize)
@ -3232,7 +3227,7 @@ void polymost_drawrooms()
gctang = cosf(gtang); gctang = cosf(gtang);
gstang = sinf(gtang); gstang = sinf(gtang);
if (Bfabsf(gstang) < .001f) // This hack avoids nasty precision bugs in domost() if (Bfabsf(gstang) < .001f) // This avoids nasty precision bugs in domost()
{ {
gstang = 0.f; gstang = 0.f;
gctang = (gctang > 0.f) ? 1.f : -1.f; gctang = (gctang > 0.f) ? 1.f : -1.f;
@ -3257,10 +3252,9 @@ void polymost_drawrooms()
v = { o2.x, o2.y * gchang + o2.z * gshang, o2.z * gchang - o2.y * gshang }; v = { o2.x, o2.y * gchang + o2.z * gshang, o2.z * gchang - o2.y * gshang };
} }
#if !SOFTROTMAT
if (inpreparemirror) if (inpreparemirror)
gstang = -gstang; gstang = -gstang;
#endif polymost_updaterotmat();
//Clip to SCISDIST plane //Clip to SCISDIST plane
int n = 0; int n = 0;
@ -3354,8 +3348,6 @@ void polymost_drawrooms()
//else if (!g_nodraw) { videoEndDrawing(); return; } //else if (!g_nodraw) { videoEndDrawing(); return; }
#endif #endif
polymost_updaterotmat();
numscans = numbunches = 0; numscans = numbunches = 0;
// MASKWALL_BAD_ACCESS // MASKWALL_BAD_ACCESS
@ -3418,7 +3410,6 @@ void polymost_drawrooms()
} }
GLInterface.SetDepthFunc(Depth_LessEqual); GLInterface.SetDepthFunc(Depth_LessEqual);
polymost_identityrotmat();
videoEndDrawing(); videoEndDrawing();
} }
@ -3626,9 +3617,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
pow2xsplit = 0; pow2xsplit = 0;
skyclamphack = 0; skyclamphack = 0;
polymost_updaterotmat();
polymost_drawpoly(dpxy, n, method, tilesiz[globalpicnum]); polymost_drawpoly(dpxy, n, method, tilesiz[globalpicnum]);
polymost_identityrotmat();
} }
void polymost_drawmaskwall(int32_t damaskwallcnt) void polymost_drawmaskwall(int32_t damaskwallcnt)
@ -3692,6 +3681,7 @@ void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang
gstang = 0.f; gstang = 0.f;
gctang = (gctang > 0.f) ? 1.f : -1.f; gctang = (gctang > 0.f) ? 1.f : -1.f;
} }
polymost_updaterotmat();
grhalfxdown10x = grhalfxdown10; grhalfxdown10x = grhalfxdown10;
//POGO: write the mirror region to the stencil buffer to allow showing mirrors & skyboxes at the same time //POGO: write the mirror region to the stencil buffer to allow showing mirrors & skyboxes at the same time
@ -3899,8 +3889,6 @@ void polymost_drawsprite(int32_t snum)
if (tsiz.x <= 0 || tsiz.y <= 0) if (tsiz.x <= 0 || tsiz.y <= 0)
return; return;
polymost_updaterotmat();
vec2f_t const ftsiz = { (float) tsiz.x, (float) tsiz.y }; vec2f_t const ftsiz = { (float) tsiz.x, (float) tsiz.y };
switch ((globalorientation >> 4) & 3) switch ((globalorientation >> 4) & 3)
@ -4421,7 +4409,7 @@ void polymost_drawsprite(int32_t snum)
show2dsprite[spritenum>>3] |= pow2char[spritenum&7]; show2dsprite[spritenum>>3] |= pow2char[spritenum&7];
_drawsprite_return: _drawsprite_return:
polymost_identityrotmat(); ;
} }
EDUKE32_STATIC_ASSERT((int)RS_YFLIP == (int)HUDFLAG_FLIPPED); EDUKE32_STATIC_ASSERT((int)RS_YFLIP == (int)HUDFLAG_FLIPPED);
@ -4462,18 +4450,19 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
polymost_outputGLDebugMessage(3, "polymost_dorotatespritemodel(sx:%d, sy:%d, z:%d, a:%hd, picnum:%hd, dashade:%hhd, dapalnum:%hhu, dastat:%d, daalpha:%hhu, dablend:%hhu, uniqid:%d)", polymost_outputGLDebugMessage(3, "polymost_dorotatespritemodel(sx:%d, sy:%d, z:%d, a:%hd, picnum:%hd, dashade:%hhd, dapalnum:%hhu, dastat:%d, daalpha:%hhu, dablend:%hhu, uniqid:%d)",
sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, uniqid); sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, uniqid);
float const ogchang = gchang; gchang = 1.f; gchang = 1.f;
float const ogshang = gshang; gshang = 0.f; d = (float) z*(1.0f/(65536.f*16384.f)); gshang = 0.f; d = (float) z*(1.0f/(65536.f*16384.f));
float const ogctang = gctang; gctang = (float) sintable[(a+512)&2047]*d; gctang = (float) sintable[(a+512)&2047]*d;
float const ogstang = gstang; gstang = (float) sintable[a&2047]*d; gstang = (float) sintable[a&2047]*d;
gvrcorrection = 1.f;
polymost_updaterotmat();
int const ogshade = globalshade; globalshade = dashade; int const ogshade = globalshade; globalshade = dashade;
int const ogpal = globalpal; globalpal = (int32_t) ((uint8_t) dapalnum); int const ogpal = globalpal; globalpal = (int32_t) ((uint8_t) dapalnum);
double const ogxyaspect = gxyaspect; gxyaspect = 1.f; double const ogxyaspect = gxyaspect; gxyaspect = 1.f;
int const oldviewingrange = viewingrange; viewingrange = 65536; int const oldviewingrange = viewingrange; viewingrange = 65536;
float const oldfviewingrange = fviewingrange; fviewingrange = 65536.f; float const oldfviewingrange = fviewingrange; fviewingrange = 65536.f;
float const ogvrcorrection = gvrcorrection; gvrcorrection = 1.f;
polymost_updaterotmat();
vec1 = hud->add; vec1 = hud->add;
@ -4572,7 +4561,6 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
GLInterface.SetMatrix(Matrix_Projection, &m[0][0]); GLInterface.SetMatrix(Matrix_Projection, &m[0][0]);
VSMatrix identity(0); VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
} }
if (hud->flags & HUDFLAG_NODEPTH) if (hud->flags & HUDFLAG_NODEPTH)
@ -4596,17 +4584,11 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
if (videoGetRenderMode() == REND_POLYMOST) if (videoGetRenderMode() == REND_POLYMOST)
polymost_mddraw(&tspr); polymost_mddraw(&tspr);
gvrcorrection = ogvrcorrection;
viewingrange = oldviewingrange; viewingrange = oldviewingrange;
fviewingrange = oldfviewingrange; fviewingrange = oldfviewingrange;
gxyaspect = ogxyaspect; gxyaspect = ogxyaspect;
globalshade = ogshade; globalshade = ogshade;
globalpal = ogpal; globalpal = ogpal;
gchang = ogchang;
gshang = ogshang;
gctang = ogctang;
gstang = ogstang;
polymost_identityrotmat();
} }

View file

@ -1120,7 +1120,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
//Let OpenGL (and perhaps hardware :) handle the matrix rotation //Let OpenGL (and perhaps hardware :) handle the matrix rotation
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
GLInterface.SetMatrix(Matrix_ModelView, mat); int matrixindex = GLInterface.SetMatrix(Matrix_Model, mat);
const float ru = 1.f/((float)m->mytexx); const float ru = 1.f/((float)m->mytexx);
const float rv = 1.f/((float)m->mytexy); const float rv = 1.f/((float)m->mytexy);
@ -1195,7 +1195,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr)
GLInterface.SetDepthFunc(Depth_Less); GLInterface.SetDepthFunc(Depth_Less);
} }
VSMatrix identity(0); VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView); GLInterface.RestoreMatrix(Matrix_Model, matrixindex);
GLInterface.SetFadeDisable(false); GLInterface.SetFadeDisable(false);
GLInterface.SetTinting(-1, 0xffffff, 0xffffff); GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
return 1; return 1;

View file

@ -10,7 +10,7 @@ enum EMatrixType
{ {
Matrix_View, Matrix_View,
Matrix_Projection, Matrix_Projection,
Matrix_ModelView, Matrix_Model,
Matrix_Detail, Matrix_Detail,
Matrix_Texture, Matrix_Texture,
// These are the only ones being used. // These are the only ones being used.
@ -69,7 +69,7 @@ struct PolymostRenderState
float AlphaThreshold = 0.5f; float AlphaThreshold = 0.5f;
bool AlphaTest = true; bool AlphaTest = true;
float Color[4] = { 1,1,1,1 }; float Color[4] = { 1,1,1,1 };
short matrixIndex[NUMMATRICES] = { -1,-1,-1,-1,-1 }; short matrixIndex[NUMMATRICES] = { 0,0,0,0,0 };
PalEntry fullscreenTint = 0xffffff, hictint = 0xffffff, hictint_overlay = 0xffffff; PalEntry fullscreenTint = 0xffffff, hictint = 0xffffff, hictint_overlay = 0xffffff;
int hictint_flags = -1; int hictint_flags = -1;

View file

@ -464,8 +464,8 @@ void PolymostRenderState::Apply(PolymostShader* shader, GLState &oldState)
shader->RotMatrix.Set(matrixArray[matrixIndex[Matrix_View]].get()); shader->RotMatrix.Set(matrixArray[matrixIndex[Matrix_View]].get());
if (matrixIndex[Matrix_Projection] != -1) if (matrixIndex[Matrix_Projection] != -1)
shader->ProjectionMatrix.Set(matrixArray[matrixIndex[Matrix_Projection]].get()); shader->ProjectionMatrix.Set(matrixArray[matrixIndex[Matrix_Projection]].get());
if (matrixIndex[Matrix_ModelView] != -1) if (matrixIndex[Matrix_Model] != -1)
shader->ModelMatrix.Set(matrixArray[matrixIndex[Matrix_ModelView]].get()); shader->ModelMatrix.Set(matrixArray[matrixIndex[Matrix_Model]].get());
if (matrixIndex[Matrix_Detail] != -1) if (matrixIndex[Matrix_Detail] != -1)
shader->DetailMatrix.Set(matrixArray[matrixIndex[Matrix_Detail]].get()); shader->DetailMatrix.Set(matrixArray[matrixIndex[Matrix_Detail]].get());
if (matrixIndex[Matrix_Texture] != -1) if (matrixIndex[Matrix_Texture] != -1)

View file

@ -98,7 +98,7 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
{ {
VSMatrix mat(0); VSMatrix mat(0);
SetIdentityMatrix(Matrix_View); SetIdentityMatrix(Matrix_View);
SetIdentityMatrix(Matrix_ModelView); SetIdentityMatrix(Matrix_Model);
SetIdentityMatrix(Matrix_Detail); SetIdentityMatrix(Matrix_Detail);
mat.ortho(0, xdim, ydim, 0, -1, 1); mat.ortho(0, xdim, ydim, 0, -1, 1);
SetMatrix(Matrix_Projection, mat.get()); SetMatrix(Matrix_Projection, mat.get());
@ -226,42 +226,36 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
//drawer->mIsFirstPass = false; //drawer->mIsFirstPass = false;
EnableBlend(true); EnableBlend(true);
EnableMultisampling(true); EnableMultisampling(true);
SetIdentityMatrix(Matrix_Projection);
} }
void fullscreen_tint_gl(PalEntry pe) static int32_t tint_blood_r = 0, tint_blood_g = 0, tint_blood_b = 0;
extern palette_t palfadergb;
extern char palfadedelta ;
void DrawFullscreenBlends()
{
GLInterface.SetIdentityMatrix(Matrix_Projection);
GLInterface.SetIdentityMatrix(Matrix_Model);
GLInterface.SetIdentityMatrix(Matrix_View);
GLInterface.EnableDepthTest(false);
GLInterface.EnableAlphaTest(false);
GLInterface.EnableBlend(true);
GLInterface.UseColorOnly(true);
if (palfadedelta)
{ {
// Todo: reroute to the 2D drawer // Todo: reroute to the 2D drawer
GLInterface.SetIdentityMatrix(Matrix_Projection);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
GLInterface.EnableDepthTest(false);
GLInterface.EnableAlphaTest(false);
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
GLInterface.EnableBlend(true); GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta);
GLInterface.SetColorub (pe.r, pe.g, pe.b, pe.a);
GLInterface.UseColorOnly(true);
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
GLInterface.UseColorOnly(false);
} }
if (tint_blood_r | tint_blood_g | tint_blood_b)
void fullscreen_tint_gl_blood(int tint_blood_r, int tint_blood_g, int tint_blood_b)
{ {
if (!(tint_blood_r | tint_blood_g | tint_blood_b))
return;
GLInterface.SetIdentityMatrix(Matrix_Projection);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
GLInterface.EnableDepthTest(false);
GLInterface.EnableAlphaTest(false);
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Add]); GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Add]);
GLInterface.EnableBlend(true);
GLInterface.UseColorOnly(true);
GLInterface.SetColorub(max(tint_blood_r, 0), max(tint_blood_g, 0), max(tint_blood_b, 0), 255); GLInterface.SetColorub(max(tint_blood_r, 0), max(tint_blood_g, 0), max(tint_blood_b, 0), 255);
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
@ -271,17 +265,9 @@ void fullscreen_tint_gl_blood(int tint_blood_r, int tint_blood_g, int tint_blood
GLInterface.SetColorub(255, 255, 255, 255); GLInterface.SetColorub(255, 255, 255, 255);
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
GLInterface.UseColorOnly(false);
} }
GLInterface.UseColorOnly(false);
static int32_t tint_blood_r = 0, tint_blood_g = 0, tint_blood_b = 0;
extern palette_t palfadergb;
extern char palfadedelta ;
void DrawFullscreenBlends()
{
if (palfadedelta) fullscreen_tint_gl(PalEntry(palfadedelta, palfadergb.r, palfadergb.g, palfadergb.b));
fullscreen_tint_gl_blood(tint_blood_r, tint_blood_g, tint_blood_b);
} }