- 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])
{
float g;
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);
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);
k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] * (1.f/16384.f);
k2 = k0*(1-k4)+k1*k5;
k3 = k1*(1-k4)-k0*k5;
k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang;
mat[0] = k4*k6 + k5*k7; mat[4] = gchang*gstang; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7;
k6 = f*gctang + gsinang*gstang; k7 = g*gctang - gcosang*gstang;
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[2] = k4*k6 + k5*k7; mat[6] =-gshang*gvrcorrection; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7;
k6 = - gsinang;
k7 = gcosang;
mat[0] = k4*k6 + k5*k7; mat[4] = 0; mat[ 8] = k4*k7 - k5*k6; mat[12] = k2*k6 + k3*k7;
mat[1] = 0; mat[5] = 1; mat[ 9] = 0; mat[13] = 0;
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[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();
GLInterface.SetClamp(0);
auto matrixindex = GLInterface.SetIdentityMatrix(Matrix_Model);
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
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
GLInterface.SetMatrix(Matrix_ModelView, mat);
GLInterface.SetMatrix(Matrix_Model, mat);
// PLAG: End
bool exact = false;
@ -1786,7 +1790,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
GLInterface.SetCull(Cull_None);
VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
GLInterface.RestoreMatrix(Matrix_Model, matrixindex);
GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
GLInterface.SetClamp(prevClamp);

View file

@ -302,7 +302,7 @@ static void resizeglcheck(void)
m[2][3] = 1.f;
m[3][2] = -(2.f * farclip * nearclip) / (farclip - nearclip);
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);
}
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_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);
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;
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 };
}
#if !SOFTROTMAT
if (inpreparemirror)
gstang = -gstang;
#endif
polymost_updaterotmat();
//Clip to SCISDIST plane
int n = 0;
@ -3354,8 +3348,6 @@ void polymost_drawrooms()
//else if (!g_nodraw) { videoEndDrawing(); return; }
#endif
polymost_updaterotmat();
numscans = numbunches = 0;
// MASKWALL_BAD_ACCESS
@ -3418,7 +3410,6 @@ void polymost_drawrooms()
}
GLInterface.SetDepthFunc(Depth_LessEqual);
polymost_identityrotmat();
videoEndDrawing();
}
@ -3626,9 +3617,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
pow2xsplit = 0;
skyclamphack = 0;
polymost_updaterotmat();
polymost_drawpoly(dpxy, n, method, tilesiz[globalpicnum]);
polymost_identityrotmat();
}
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;
gctang = (gctang > 0.f) ? 1.f : -1.f;
}
polymost_updaterotmat();
grhalfxdown10x = grhalfxdown10;
//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)
return;
polymost_updaterotmat();
vec2f_t const ftsiz = { (float) tsiz.x, (float) tsiz.y };
switch ((globalorientation >> 4) & 3)
@ -4421,7 +4409,7 @@ void polymost_drawsprite(int32_t snum)
show2dsprite[spritenum>>3] |= pow2char[spritenum&7];
_drawsprite_return:
polymost_identityrotmat();
;
}
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)",
sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, uniqid);
float const ogchang = gchang; gchang = 1.f;
float const ogshang = gshang; gshang = 0.f; d = (float) z*(1.0f/(65536.f*16384.f));
float const ogctang = gctang; gctang = (float) sintable[(a+512)&2047]*d;
float const ogstang = gstang; gstang = (float) sintable[a&2047]*d;
gchang = 1.f;
gshang = 0.f; d = (float) z*(1.0f/(65536.f*16384.f));
gctang = (float) sintable[(a+512)&2047]*d;
gstang = (float) sintable[a&2047]*d;
gvrcorrection = 1.f;
polymost_updaterotmat();
int const ogshade = globalshade; globalshade = dashade;
int const ogpal = globalpal; globalpal = (int32_t) ((uint8_t) dapalnum);
double const ogxyaspect = gxyaspect; gxyaspect = 1.f;
int const oldviewingrange = viewingrange; viewingrange = 65536;
float const oldfviewingrange = fviewingrange; fviewingrange = 65536.f;
float const ogvrcorrection = gvrcorrection; gvrcorrection = 1.f;
polymost_updaterotmat();
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]);
VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
}
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)
polymost_mddraw(&tspr);
gvrcorrection = ogvrcorrection;
viewingrange = oldviewingrange;
fviewingrange = oldfviewingrange;
gxyaspect = ogxyaspect;
globalshade = ogshade;
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
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 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);
}
VSMatrix identity(0);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
GLInterface.RestoreMatrix(Matrix_Model, matrixindex);
GLInterface.SetFadeDisable(false);
GLInterface.SetTinting(-1, 0xffffff, 0xffffff);
return 1;

View file

@ -10,7 +10,7 @@ enum EMatrixType
{
Matrix_View,
Matrix_Projection,
Matrix_ModelView,
Matrix_Model,
Matrix_Detail,
Matrix_Texture,
// These are the only ones being used.
@ -69,7 +69,7 @@ struct PolymostRenderState
float AlphaThreshold = 0.5f;
bool AlphaTest = true;
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;
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());
if (matrixIndex[Matrix_Projection] != -1)
shader->ProjectionMatrix.Set(matrixArray[matrixIndex[Matrix_Projection]].get());
if (matrixIndex[Matrix_ModelView] != -1)
shader->ModelMatrix.Set(matrixArray[matrixIndex[Matrix_ModelView]].get());
if (matrixIndex[Matrix_Model] != -1)
shader->ModelMatrix.Set(matrixArray[matrixIndex[Matrix_Model]].get());
if (matrixIndex[Matrix_Detail] != -1)
shader->DetailMatrix.Set(matrixArray[matrixIndex[Matrix_Detail]].get());
if (matrixIndex[Matrix_Texture] != -1)

View file

@ -98,7 +98,7 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
{
VSMatrix mat(0);
SetIdentityMatrix(Matrix_View);
SetIdentityMatrix(Matrix_ModelView);
SetIdentityMatrix(Matrix_Model);
SetIdentityMatrix(Matrix_Detail);
mat.ortho(0, xdim, ydim, 0, -1, 1);
SetMatrix(Matrix_Projection, mat.get());
@ -226,42 +226,36 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
//drawer->mIsFirstPass = false;
EnableBlend(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
GLInterface.SetIdentityMatrix(Matrix_Projection);
GLInterface.SetIdentityMatrix(Matrix_ModelView);
GLInterface.EnableDepthTest(false);
GLInterface.EnableAlphaTest(false);
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
GLInterface.EnableBlend(true);
GLInterface.SetColorub (pe.r, pe.g, pe.b, pe.a);
GLInterface.UseColorOnly(true);
GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta);
GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
GLInterface.UseColorOnly(false);
}
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)
{
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.EnableBlend(true);
GLInterface.UseColorOnly(true);
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);
@ -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.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);
}