- draw the textures on the automap with the 2D drawer.

This commit is contained in:
Christoph Oelckers 2019-12-31 15:04:28 +01:00
parent 143c8be84d
commit 964e303dd7
7 changed files with 109 additions and 308 deletions

View file

@ -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);

View file

@ -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
}

View file

@ -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<npoints; z++)
for (int z=0; z<npoints; z++)
if ((unsigned)xb1[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<day2; y++)
{
Bassert(dotp2[y]);
*(dotp2[y]++) = x1>>12;
x1 += xinc;
}
}
else
{
x2 += mulscale12((day2<<12)+4095-y2, xinc);
for (y=day2; y<day1; y++)
{
Bassert(dotp1[y]);
*(dotp1[y]++) = x2>>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)&sector[s]; s<numsectors; s++,sec++)
@ -8541,7 +8392,7 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
setgotpic(globalpicnum);
if ((tilesiz[globalpicnum].x <= 0) || (tilesiz[globalpicnum].y <= 0)) continue;
if (videoGetRenderMode() == REND_POLYMOST)
if (videoGetRenderMode() != REND_POLYMOST)
{
tileLoad(globalpicnum);
// Only load tiles when software rendering.
@ -8672,7 +8523,7 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
setgotpic(globalpicnum);
if ((tilesiz[globalpicnum].x <= 0) || (tilesiz[globalpicnum].y <= 0)) continue;
if (videoGetRenderMode() == REND_POLYMOST)
if (videoGetRenderMode() != REND_POLYMOST)
{
tileLoad(globalpicnum);
// Only load tiles when software rendering.
@ -8737,8 +8588,6 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
}
}
videoEndDrawing(); //}}}
if (r_usenewaspect)
renderSetAspect(oviewingrange, oyxaspect);
else

View file

@ -4719,33 +4719,30 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
polymost_identityrotmat();
}
static float trapextx[2];
static void drawtrap(float x0, float x1, float y0, float x2, float x3, float y1)
#include "v_2ddrawer.h"
static void drawtrap(float x0, float x1, float y0, float x2, float x3, float y1, float *trapextx, F2DPolygons *poly)
{
if (y0 == y1) return;
float px[4], py[4];
int32_t n = 3;
int n = 3;
px[0] = x0; py[0] = y0; py[2] = y1;
if (x0 == x1) { px[1] = x3; py[1] = y1; px[2] = x2; }
else if (x2 == x3) { px[1] = x1; py[1] = y0; px[2] = x3; }
else { px[1] = x1; py[1] = y0; px[2] = x3; px[3] = x2; py[3] = y1; n = 4; }
auto data = GLInterface.AllocVertices(n);
auto vt = data.second;
for (bssize_t i=0; i<n; i++, vt++)
auto vt = poly->AllocVertices(n);
for (int i=0; i<n; i++)
{
px[i] = min(max(px[i],trapextx[0]),trapextx[1]);
vt->SetTexCoord(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; i<npoints; i++, vt++)
for (i=0; i<npoints; i++)
{
j = slist[i];
vt->SetTexCoord(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);
}

View file

@ -81,6 +81,15 @@ void F2DDrawer::AddIndices(int firstvert, int count, ...)
}
}
void F2DDrawer::AddIndices(int firstvert, TArray<int> &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);
}

View file

@ -9,6 +9,21 @@
struct DrawParms;
struct F2DPolygons
{
TArray<FVector4> vertices;
TArray<int> 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<int> &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);

View file

@ -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