From c8fa2443d3034f890e7fef3b14ad486d57991cf0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Jan 2020 16:06:31 +0100 Subject: [PATCH] - 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. --- source/build/src/mdsprite.cpp | 26 +++++----- source/build/src/polymost.cpp | 42 +++++----------- source/build/src/voxmodel.cpp | 4 +- source/glbackend/gl_renderstate.h | 4 +- source/glbackend/glbackend.cpp | 4 +- source/glbackend/hw_draw2d.cpp | 82 +++++++++++++------------------ 6 files changed, 67 insertions(+), 95 deletions(-) diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index d135a5ae9..5414a9ed9 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -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; surfihead.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); diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 85cf8bc93..37174f6fc 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -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(); } diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index 18a7359ce..7fd28ed4d 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -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; diff --git a/source/glbackend/gl_renderstate.h b/source/glbackend/gl_renderstate.h index 9174c8117..a7a290246 100644 --- a/source/glbackend/gl_renderstate.h +++ b/source/glbackend/gl_renderstate.h @@ -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; diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index b2b366d11..f9891e7e8 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -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) diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index 60a6140e1..00b9a9cf1 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -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,62 +226,48 @@ void GLInstance::Draw2D(F2DDrawer *drawer) //drawer->mIsFirstPass = false; EnableBlend(true); EnableMultisampling(true); + SetIdentityMatrix(Matrix_Projection); } -void fullscreen_tint_gl(PalEntry pe) -{ - // 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.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)) - 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); - - GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Subtract]); - 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.SetColorub(255, 255, 255, 255); - GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); - 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); + 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.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); + GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); + } + if (tint_blood_r | tint_blood_g | tint_blood_b) + { + GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Add]); + + 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.SetRenderStyle(LegacyRenderStyles[STYLE_Subtract]); + 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.SetColorub(255, 255, 255, 255); + GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); + } + GLInterface.UseColorOnly(false); + }