From 964e303dd75a8e813e33861ac0f75428a97cd86b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 31 Dec 2019 15:04:28 +0100 Subject: [PATCH] - draw the textures on the automap with the 2D drawer. --- source/build/include/build.h | 2 - source/build/src/2d.cpp | 22 ----- source/build/src/engine.cpp | 159 +------------------------------- source/build/src/polymost.cpp | 58 ++++-------- source/common/2d/v_2ddrawer.cpp | 152 +++++++++++++----------------- source/common/2d/v_2ddrawer.h | 22 ++++- source/glbackend/hw_draw2d.cpp | 2 +- 7 files changed, 109 insertions(+), 308 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 0f92de43c..73a10f1e9 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1092,8 +1092,6 @@ void renderSetRollAngle(int32_t rolla); // clamping is for sprites, repeating is for walls void tileInvalidate(int16_t tilenume, int32_t pal, int32_t how); -void polymostSet2dView(void); // sets up GL for 2D drawing - void polymost_glreset(void); void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype); void PrecacheHardwareTextures(int nTile); diff --git a/source/build/src/2d.cpp b/source/build/src/2d.cpp index c43c31d72..3da494211 100644 --- a/source/build/src/2d.cpp +++ b/source/build/src/2d.cpp @@ -105,25 +105,3 @@ void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col) } - -// -// setpolymost2dview -// Sets OpenGL for 2D drawing -// -void polymostSet2dView(void) -{ -#ifdef USE_OPENGL - if (videoGetRenderMode() < REND_POLYMOST) return; - - GLInterface.SetViewport(0, 0, xdim, ydim); - - VSMatrix proj(0); - proj.ortho(0, xdim, ydim, 0, -1, 1); - GLInterface.SetMatrix(Matrix_Projection, &proj); - - gloy1 = -1; - - GLInterface.EnableDepthTest(false); - GLInterface.EnableBlend(false); -#endif -} diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 7ecdafbcb..54ace86f5 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -6256,159 +6256,12 @@ static void renderDrawMaskedWall(int16_t damaskwallcnt) // static void renderFillPolygon(int32_t npoints) { - int32_t i, z, y, miny, maxy; - // fix for bad next-point (xb1) values... - for (z=0; z= (unsigned)npoints) xb1[z] = 0; -#ifdef USE_OPENGL - if (videoGetRenderMode() >= REND_POLYMOST && in3dmode()) - { - polymost_fillpolygon(npoints); - return; - } -#endif - - // 1. Calculate y bounds. - miny = INT32_MAX; maxy = INT32_MIN; - for (z=npoints-1; z>=0; z--) - { - y = ry1[z]; - miny = min(miny,y); - maxy = max(maxy,y); - } - - miny >>= 12; - maxy >>= 12; - - if (miny < 0) - miny = 0; - if (maxy >= ydim) - maxy = ydim-1; - - for (i=0, y=miny; y<=maxy; y++, i++) - { - //They're pointers! - watch how you optimize this thing - dotp1[y] = &smost[i*nodesperline]; - dotp2[y] = &smost[i*nodesperline + (nodesperline>>1)]; - } - - for (z=npoints-1; z>=0; z--) - { - const int32_t zz=xb1[z]; - - // NOTE: clamp for crash prevention... :-/ - // r1874 says: "Fix more overheadmap crashes, this time with 'Last - // Pissed Time'" - const int32_t y1 = clamp(ry1[z], 0, (ydim<<12)-1); - const int32_t y2 = clamp(ry1[zz], 0, (ydim<<12)-1); - - const int32_t day1 = y1>>12; - const int32_t day2 = y2>>12; - - if (day1 != day2) - { - int32_t x1=rx1[z], x2=rx1[zz]; - const int32_t xinc = divscale12(x2-x1, y2-y1); - - if (day2 > day1) - { - x1 += mulscale12((day1<<12)+4095-y1, xinc); - for (y=day1; y>12; - x1 += xinc; - } - } - else - { - x2 += mulscale12((day2<<12)+4095-y2, xinc); - for (y=day2; y>12; - x2 += xinc; - } - } - } - } - - globalx1 = mulscale16(globalx1,xyaspect); - globaly2 = mulscale16(globaly2,xyaspect); - - { - const int32_t oy = miny+1-(ydim>>1); - globalposx += oy*(int64_t)globalx1; - globalposy += oy*(int64_t)globaly2; - } - - setuphlineasm4(asm1,asm2); - - for (i=0, y=miny; y<=maxy; y++, i++) - { - int16_t *const xptr = &smost[i*nodesperline]; - int16_t *const xptr2 = &smost[i*nodesperline + (nodesperline>>1)]; - - const bssize_t cnt = dotp1[y]-xptr; - - for (z=cnt-1; z>=0; z--) - { - int32_t x1, x2; - int32_t zz, i1=0, i2=0; // point indices (like loop z) - - for (zz=z; zz>0; zz--) - { - if (xptr[zz] < xptr[i1]) - i1 = zz; - if (xptr2[zz] < xptr2[i2]) - i2 = zz; - } - - x1 = xptr[i1]; - xptr[i1] = xptr[z]; - - x2 = xptr2[i2]-1; - xptr2[i2] = xptr2[z]; - - if (x1 > x2) - continue; - - if ((unsigned)x1 >= xdim+0u || (unsigned)x2 >= xdim+0u) - continue; - - if (globalpolytype < 1) - { - //maphline - const int32_t ox = x2+1-(xdim>>1); - - hlineasm4(x2 - x1, -1L, globalshade << 8, - ox * asm2 - globalposy, ox * asm1 + globalposx, - ylookup[y] + x2 + frameplace); - } - else - { - //maphline - const int32_t ox = x1+1-(xdim>>1); - const int32_t bx = ox*asm1 + globalposx; - const int32_t by = ox*asm2 - globalposy; - - const intptr_t p = ylookup[y]+x1+frameplace; - - if (globalpolytype == 1) - mhline(globalbufplc,bx,(x2-x1)<<16,0L,by,p); - else - thline(globalbufplc,bx,(x2-x1)<<16,0L,by,p); - } - } - - globalposx += (int64_t)globalx1; - globalposy += (int64_t)globaly2; - } - - faketimerhandler(); + polymost_fillpolygon(npoints); } static inline int32_t addscaleclamp(int32_t a, int32_t b, int32_t s1, int32_t s2) @@ -8452,8 +8305,6 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang) int32_t sortnum = 0; - videoBeginDrawing(); //{{{ - usectorptr_t sec; for (s=0,sec=(usectorptr_t)§or[s]; sAllocVertices(n); + for (int i=0; iSetTexCoord(px[i]*xtex.u + py[i]*ytex.u + otex.u, - px[i]*xtex.v + py[i]*ytex.v + otex.v); - vt->SetVertex(px[i],py[i]); + poly->vertices[vt++] = { px[i], py[i], float(px[i] * xtex.u + py[i] * ytex.u + otex.u), float(px[i] * xtex.v + py[i] * ytex.v + otex.v) }; } - GLInterface.Draw(DT_TRIANGLE_FAN, data.first, n); } -static void tessectrap(const float *px, const float *py, const int32_t *point2, int32_t numpoints) +static void tessectrap(const float *px, const float *py, const int32_t *point2, int32_t numpoints, F2DPolygons* poly) { + float trapextx[2]; float x0, x1, m0, m1; int32_t i, j, k, z, i0, i1, i2, i3, npoints, gap, numrst; @@ -4785,17 +4782,13 @@ static void tessectrap(const float *px, const float *py, const int32_t *point2, } if (z != 3) //Simple polygon... early out { - auto data = GLInterface.AllocVertices(npoints); - auto vt = data.second; + auto vt = poly->AllocVertices(npoints); - for (i=0; iSetTexCoord(px[j]*xtex.u + py[j]*ytex.u + otex.u, - px[j]*xtex.v + py[j]*ytex.v + otex.v); - vt->SetVertex(px[j],py[j]); + poly->vertices[vt++] = { px[j], py[j], float(px[j] * xtex.u + py[j] * ytex.u + otex.u), float(px[j] * xtex.v + py[j] * ytex.v + otex.v) }; } - GLInterface.Draw(DT_TRIANGLE_FAN, data.first, npoints); return; } @@ -4836,7 +4829,7 @@ static void tessectrap(const float *px, const float *py, const int32_t *point2, x0 = (py[i1] - rst[j ].y)*rst[j ].xi + rst[j ].x; x1 = (py[i1] - rst[j+1].y)*rst[j+1].xi + rst[j+1].x; - drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1]); + drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1], trapextx, poly); rst[j ].x = x0; rst[j ].y = py[i1]; rst[j+3].x = x1; rst[j+3].y = py[i1]; } @@ -4861,7 +4854,7 @@ static void tessectrap(const float *px, const float *py, const int32_t *point2, { x0 = (py[i1] - rst[j ].y)*rst[j ].xi + rst[j ].x; if ((i == j) && (i1 == i2)) x1 = x0; else x1 = (py[i1] - rst[j+1].y)*rst[j+1].xi + rst[j+1].x; - drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1]); + drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1], trapextx, poly); rst[j ].x = x0; rst[j ].y = py[i1]; rst[j+1].x = x1; rst[j+1].y = py[i1]; } @@ -4871,7 +4864,7 @@ static void tessectrap(const float *px, const float *py, const int32_t *point2, { x0 = (py[i1] - rst[j ].y)*rst[j ].xi + rst[j ].x; x1 = (py[i1] - rst[j+1].y)*rst[j+1].xi + rst[j+1].x; - drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1]); + drawtrap(rst[j].x,rst[j+1].x,rst[j].y,x0,x1,py[i1], trapextx, poly); rst[j ].x = x0; rst[j ].y = py[i1]; rst[j+1].x = x1; rst[j+1].y = py[i1]; @@ -4883,12 +4876,14 @@ static void tessectrap(const float *px, const float *py, const int32_t *point2, } } +static F2DPolygons poly; void polymost_fillpolygon(int32_t npoints) { + poly.vertices.Clear(); + poly.indices.Clear(); polymost_outputGLDebugMessage(3, "polymost_fillpolygon(npoints:%d)", npoints); globvis2 = 0; - GLInterface.SetVisibility(globvis2, fviewingrange); globalx1 = mulscale16(globalx1,xyaspect); globaly2 = mulscale16(globaly2,xyaspect); @@ -4905,25 +4900,12 @@ void polymost_fillpolygon(int32_t npoints) ((float *)rx1)[i] = ((float)rx1[i])*(1.0f/4096.f); ((float *)ry1)[i] = ((float)ry1[i])*(1.0f/4096.f); } - - if (gloy1 != -1) polymostSet2dView(); //disables blending, texturing, and depth testing - GLInterface.EnableAlphaTest(true); - GLInterface.SetTexture(globalpicnum, TileFiles.tiles[globalpicnum], globalpal, DAMETH_NOMASK, -1); + tessectrap((float*)rx1, (float*)ry1, xb1, npoints, &poly); uint8_t const maskprops = (globalorientation>>7)&DAMETH_MASKPROPS; handle_blend(maskprops > DAMETH_MASK, 0, maskprops == DAMETH_TRANS2); - if (maskprops > DAMETH_MASK) - { - GLInterface.EnableBlend(true); - GLInterface.SetColor(1.f, 1.f, 1.f, float_trans(maskprops, 0)); - } - else - { - GLInterface.EnableBlend(false); - GLInterface.SetColor(1.f, 1.f, 1.f); - } - - tessectrap((float *)rx1,(float *)ry1,xb1,npoints); + float alpha = (maskprops > DAMETH_MASK) ? float_trans(maskprops, 0) : 1.f; + twod->AddPoly(TileFiles.tiles[globalpicnum], poly, globalpal, globalshade, alpha); } diff --git a/source/common/2d/v_2ddrawer.cpp b/source/common/2d/v_2ddrawer.cpp index a8233c2b4..e91ff24ec 100644 --- a/source/common/2d/v_2ddrawer.cpp +++ b/source/common/2d/v_2ddrawer.cpp @@ -81,6 +81,15 @@ void F2DDrawer::AddIndices(int firstvert, int count, ...) } } +void F2DDrawer::AddIndices(int firstvert, TArray &v) +{ + int addr = mIndices.Reserve(v.Size()); + for (unsigned i = 0; i < v.Size(); i++) + { + mIndices[addr + i] = firstvert + v[i]; + } +} + //========================================================================== // // SetStyle @@ -302,91 +311,6 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) AddCommand(&dg); } -//========================================================================== -// -// -// -//========================================================================== -void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, int colormap, PalEntry flatcolor, int lightlevel, - uint32_t *indices, size_t indexcount) -{ - // Use an equation similar to player sprites to determine shade - - // Convert a light level into an unbounded colormap index (shade). - // Why the +12? I wish I knew, but experimentation indicates it - // is necessary in order to best reproduce Doom's original lighting. - double fadelevel; - - // The hardware renderer's light modes 0, 1 and 4 use a linear light scale which must be used here as well. Otherwise the automap gets too dark. - fadelevel = 1. - clamp(lightlevel, 0, 255) / 255.f; - - RenderCommand poly; - - poly.mType = DrawTypeTriangles; - poly.mTexture = texture; - poly.mRenderStyle = DefaultRenderStyle(); - poly.mFlags |= DTF_Wrap; - poly.mDesaturate = 0; - - PalEntry color0; - double invfade = 1. - fadelevel; - - color0.r = uint8_t(flatcolor.r * invfade); - color0.g = uint8_t(flatcolor.g * invfade); - color0.b = uint8_t(flatcolor.b * invfade); - color0.a = 255; - - poly.mColor1 = 0; - - bool dorotate = rotation != 0; - - float cosrot = (float)cos(rotation.Radians()); - float sinrot = (float)sin(rotation.Radians()); - - float uscale = float(1.f / (texture->GetWidth() * scalex)); - float vscale = float(1.f / (texture->GetHeight() * scaley)); - float ox = float(originx); - float oy = float(originy); - - poly.mVertCount = npoints; - poly.mVertIndex = (int)mVertices.Reserve(npoints); - for (int i = 0; i < npoints; ++i) - { - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0); - } - poly.mIndexIndex = mIndices.Size(); - - if (indices == nullptr || indexcount == 0) - { - poly.mIndexCount += (npoints - 2) * 3; - for (int i = 2; i < npoints; ++i) - { - AddIndices(poly.mVertIndex, 3, 0, i - 1, i); - } - } - else - { - poly.mIndexCount += (int)indexcount; - int addr = mIndices.Reserve(indexcount); - for (size_t i = 0; i < indexcount; i++) - { - mIndices[addr + i] = poly.mVertIndex + indices[i]; - } - } - - AddCommand(&poly); -} - //========================================================================== // // @@ -722,7 +646,6 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 dg.mRemapIndex = dapalnum | (dashade << 16); dg.mVertCount = 4; dg.mVertIndex = (int)mVertices.Reserve(4); - dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent]; auto ptr = &mVertices[dg.mVertIndex]; float drawpoly_alpha = daalpha * (1.0f / 255.0f); float alpha = float_trans(method, dablend) * (1.f - drawpoly_alpha); // Hmmm... @@ -776,3 +699,60 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 AddCommand(&dg); } + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddPoly(FTexture* img, F2DPolygons& poly, int palette, int shade, float alpha) +{ + RenderCommand dg = {}; + int method = 0; + + dg.mType = DrawTypeRotateSprite; +#if 0 + if (clipx1 > 0 || clipy1 > 0 || clipx2 < xdim - 1 || clipy2 < ydim - 1) + { + dg.mScissor[0] = clipx1; + dg.mScissor[1] = clipy1; + dg.mScissor[2] = clipx2 + 1; + dg.mScissor[3] = clipy2 + 1; + dg.mFlags |= DTF_Scissor; + } +#endif + + PalEntry p = 0xffffffff; + p.a = (uint8_t)(alpha * 255); + dg.mTexture = img; + dg.mRemapIndex = palette | (shade << 16); + dg.mVertCount = poly.vertices.Size(); + dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount); + dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent]; + dg.mIndexIndex = mIndices.Size(); + dg.mFlags |= DTF_Wrap; + auto ptr = &mVertices[dg.mVertIndex]; + + for (auto& sv : poly.vertices) + { + ptr->Set(sv.X, sv.Y, 0.f, sv.Z, sv.W, p); + ptr++; + } + + int start = dg.mVertIndex; + + for (unsigned i = 0; i < poly.indices.Size(); i++) + { + for (int vv = 2; vv < poly.indices[i]; vv++) + { + AddIndices(start, 3, 0, vv - 1, vv); + } + start += poly.indices[i]; + } + + dg.mIndexCount = mIndices.Size() - dg.mIndexIndex; + AddCommand(&dg); +} + + diff --git a/source/common/2d/v_2ddrawer.h b/source/common/2d/v_2ddrawer.h index 95f40a338..a50448757 100644 --- a/source/common/2d/v_2ddrawer.h +++ b/source/common/2d/v_2ddrawer.h @@ -9,6 +9,21 @@ struct DrawParms; +struct F2DPolygons +{ + TArray vertices; + TArray indices; + + unsigned AllocVertices(int num) // Allocates a triangle fan. There's no code that needs a triangle strip. + { + auto vindex = vertices.Reserve(num); + indices.Push(num); + return vindex; + } + +}; + + class F2DDrawer { @@ -86,7 +101,7 @@ public: bool isCompatible(const RenderCommand &other) const { return mTexture == other.mTexture && - mType == other.mType && mType != DrawTypeRotateSprite && + mType == other.mType && mRemapIndex == other.mRemapIndex && mSpecialColormap[0].d == other.mSpecialColormap[0].d && mSpecialColormap[1].d == other.mSpecialColormap[1].d && @@ -106,14 +121,13 @@ public: int AddCommand(const RenderCommand *data); void AddIndices(int firstvert, int count, ...); + void AddIndices(int firstvert, TArray &v); bool SetStyle(FTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad); void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor); public: void AddTexture(FTexture *img, DrawParms &parms); - void AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, int colormap, PalEntry flatcolor, int lightlevel, uint32_t *indices, size_t indexcount); + void AddPoly(FTexture* img, F2DPolygons& poly, int palette, int shade, float alpha); void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin); void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr); diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index f51867de8..7b086b4c2 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -164,7 +164,7 @@ void GLInstance::Draw2D(F2DDrawer *drawer) // todo: Set up hictinting. (broken as the feature is...) SetShade(cmd.mRemapIndex >> 16, numshades); SetFadeDisable(false); - SetTexture(0, tex, cmd.mRemapIndex & 0xffff, 4/*DAMETH_CLAMPED*/, SamplerClampXY); + SetTexture(0, tex, cmd.mRemapIndex & 0xffff, 4/*DAMETH_CLAMPED*/, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY); EnableBlend(!(cmd.mRenderStyle.Flags & STYLEF_Alpha1)); } else