Add texturing to triangle drawer

This commit is contained in:
Magnus Norddahl 2016-10-30 08:18:55 +01:00
parent 6ea0baac3a
commit a7d06ddd77
3 changed files with 89 additions and 95 deletions

View file

@ -403,7 +403,7 @@ struct TriVertex
}; };
class VSMatrix; class VSMatrix;
void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom); void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture);
extern bool r_swtruecolor; extern bool r_swtruecolor;

View file

@ -1260,8 +1260,8 @@ void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
class DrawTrianglesCommand : public DrawerCommand class DrawTrianglesCommand : public DrawerCommand
{ {
public: public:
DrawTrianglesCommand(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *clipdata) DrawTrianglesCommand(const VSMatrix &transform, const TriVertex *vertices, int count, int clipleft, int clipright, const short *clipdata, const uint32_t *texturePixels, int textureWidth, int textureHeight)
: objectToWorld(objectToWorld), vertices(vertices), count(count), clipleft(clipleft), clipright(clipright), clipdata(clipdata) : transform(transform), vertices(vertices), count(count), clipleft(clipleft), clipright(clipright), clipdata(clipdata), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight)
{ {
} }
@ -1274,7 +1274,7 @@ public:
thread->triangle_clip_bottom[clipleft + i] = clipdata[cliplength + i]; thread->triangle_clip_bottom[clipleft + i] = clipdata[cliplength + i];
} }
draw_triangles(objectToWorld, vertices, count, clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom, thread); draw_triangles(transform, vertices, count, clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom, thread);
} }
FString DebugInfo() override FString DebugInfo() override
@ -1337,7 +1337,7 @@ private:
int minx = MAX((MIN(MIN(X1, X2), X3) + 0xF) >> 4, clipleft); int minx = MAX((MIN(MIN(X1, X2), X3) + 0xF) >> 4, clipleft);
int maxx = MIN((MAX(MAX(X1, X2), X3) + 0xF) >> 4, clipright); int maxx = MIN((MAX(MAX(X1, X2), X3) + 0xF) >> 4, clipright);
int miny = MAX((MIN(MIN(Y1, Y2), Y3) + 0xF) >> 4, clipymin); int miny = MAX((MIN(MIN(Y1, Y2), Y3) + 0xF) >> 4, clipymin);
int maxy = MIN((MAX(MAX(Y1, Y2), Y3) + 0xF) >> 4, clipymax); int maxy = MIN((MAX(MAX(Y1, Y2), Y3) + 0xF) >> 4, clipymax - 1);
if (minx >= maxx || miny >= maxy) if (minx >= maxx || miny >= maxy)
return; return;
@ -1407,9 +1407,9 @@ private:
// Check if block needs clipping // Check if block needs clipping
int clipcount = 0; int clipcount = 0;
for (int ix = 0; ix < q; ix++) for (int ix = x; ix < x + q; ix++)
{ {
clipcount += (cliptop[x + ix] > y) || (clipbottom[x + ix] < y + q - 1); clipcount += (clipleft > ix) || (clipright < ix) || (cliptop[ix] > y) || (clipbottom[ix] <= y + q - 1);
} }
// Calculate varying variables for affine block // Calculate varying variables for affine block
@ -1451,11 +1451,15 @@ private:
{ {
for (int ix = x; ix < x + q; ix++) for (int ix = x; ix < x + q; ix++)
{ {
uint32_t red = (uint32_t)clamp(varying[0] * 255.0f + 0.5f, 0.0f, 255.0f); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t green = (uint32_t)clamp(varying[1] * 255.0f + 0.5f, 0.0f, 255.0f); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t blue = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f); //uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
buffer[ix] = 0xff000000 | (red << 16) | (green << 8) | blue; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
uint32_t uvoffset = upos * textureHeight + vpos;
buffer[ix] = texturePixels[uvoffset];
for (int i = 0; i < TriVertex::NumVarying; i++) for (int i = 0; i < TriVertex::NumVarying; i++)
varying[i] += varyingStep[i]; varying[i] += varyingStep[i];
@ -1488,15 +1492,19 @@ private:
{ {
for (int ix = x; ix < x + q; ix++) for (int ix = x; ix < x + q; ix++)
{ {
bool visible = (cliptop[ix] <= y + iy) && (clipbottom[ix] >= y + iy); bool visible = ix >= clipleft && ix <= clipright && (cliptop[ix] <= y + iy) && (clipbottom[ix] > y + iy);
if (CX1 > 0 && CX2 > 0 && CX3 > 0 && visible) if (CX1 > 0 && CX2 > 0 && CX3 > 0 && visible)
{ {
uint32_t red = (uint32_t)clamp(varying[0] * 255.0f + 0.5f, 0.0f, 255.0f); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t green = (uint32_t)clamp(varying[1] * 255.0f + 0.5f, 0.0f, 255.0f); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t blue = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f); //uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
buffer[ix] = 0xff000000 | (red << 16) | (green << 8) | blue; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
uint32_t uvoffset = upos * textureHeight + vpos;
buffer[ix] = texturePixels[uvoffset];
} }
for (int i = 0; i < TriVertex::NumVarying; i++) for (int i = 0; i < TriVertex::NumVarying; i++)
@ -1523,13 +1531,15 @@ private:
bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2) bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2)
{ {
if (clipdistance1 < 0.0f && clipdistance2 < 0.0f) float d1 = clipdistance1 * (1.0f - t1) + clipdistance2 * t1;
float d2 = clipdistance1 * (1.0f - t2) + clipdistance2 * t2;
if (d1 < 0.0f && d2 < 0.0f)
return true; return true;
if (clipdistance1 < 0.0f) if (d1 < 0.0f)
t1 = MAX(-clipdistance1 / (clipdistance2 - clipdistance1), t1); t1 = MAX(-clipdistance1 / (clipdistance2 - clipdistance1), t1);
if (clipdistance2 < 0.0f) if (d2 < 0.0f)
t2 = MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2); t2 = MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2);
return false; return false;
@ -1580,7 +1590,7 @@ private:
} }
} }
void draw_triangles(const VSMatrix &objectToWorld, const TriVertex *vinput, int vcount, int clipleft, int clipright, const short *cliptop, const short *clipbottom, DrawerThread *thread) void draw_triangles(const VSMatrix &transform, const TriVertex *vinput, int vcount, int clipleft, int clipright, const short *cliptop, const short *clipbottom, DrawerThread *thread)
{ {
for (int i = 0; i < vcount / 3; i++) for (int i = 0; i < vcount / 3; i++)
{ {
@ -1592,8 +1602,8 @@ private:
auto &v = vert[j]; auto &v = vert[j];
v = *(vinput++); v = *(vinput++);
// Apply object to world transform: // Apply transform to get world coordinates:
const float *matrix = objectToWorld.get(); const float *matrix = transform.get();
float vx = matrix[0 * 4 + 0] * v.x + matrix[1 * 4 + 0] * v.y + matrix[2 * 4 + 0] * v.z + matrix[3 * 4 + 0] * v.w; float vx = matrix[0 * 4 + 0] * v.x + matrix[1 * 4 + 0] * v.y + matrix[2 * 4 + 0] * v.z + matrix[3 * 4 + 0] * v.w;
float vy = matrix[0 * 4 + 1] * v.x + matrix[1 * 4 + 1] * v.y + matrix[2 * 4 + 1] * v.z + matrix[3 * 4 + 1] * v.w; float vy = matrix[0 * 4 + 1] * v.x + matrix[1 * 4 + 1] * v.y + matrix[2 * 4 + 1] * v.z + matrix[3 * 4 + 1] * v.w;
float vz = matrix[0 * 4 + 2] * v.x + matrix[1 * 4 + 2] * v.y + matrix[2 * 4 + 2] * v.z + matrix[3 * 4 + 2] * v.w; float vz = matrix[0 * 4 + 2] * v.x + matrix[1 * 4 + 2] * v.y + matrix[2 * 4 + 2] * v.z + matrix[3 * 4 + 2] * v.w;
@ -1611,9 +1621,9 @@ private:
double tr_z = v.z - ViewPos.Z; double tr_z = v.z - ViewPos.Z;
double tx = tr_x * ViewSin - tr_y * ViewCos; double tx = tr_x * ViewSin - tr_y * ViewCos;
double tz = tr_x * ViewTanCos + tr_y * ViewTanSin; double tz = tr_x * ViewTanCos + tr_y * ViewTanSin;
v.x = (float)tx; v.x = (float)tx * 0.5f;
v.y = (float)tr_z; v.y = (float)tr_z * 0.5f;
v.z = (float)(-tz * (farp + nearp) / (nearp - farp) + (2.0f * farp * nearp) / (nearp - farp)); v.z = (float)((-tz * (farp + nearp) / (nearp - farp) + (2.0f * farp * nearp) / (nearp - farp)));
v.w = (float)tz; v.w = (float)tz;
} }
@ -1636,8 +1646,8 @@ private:
v.z *= v.w; v.z *= v.w;
// Apply viewport scale to get screen coordinates: // Apply viewport scale to get screen coordinates:
v.x = (float)(CenterX + v.x * CenterX); v.x = (float)(CenterX + v.x * 2.0f * CenterX);
v.y = (float)(CenterY - v.y * InvZtoScale); v.y = (float)(CenterY - v.y * 2.0f * InvZtoScale);
} }
// Draw screen triangles // Draw screen triangles
@ -1659,15 +1669,18 @@ private:
} }
} }
VSMatrix objectToWorld; VSMatrix transform;
const TriVertex *vertices; const TriVertex *vertices;
int count; int count;
int clipleft; int clipleft;
int clipright; int clipright;
const short *clipdata; const short *clipdata;
const uint32_t *texturePixels;
int textureWidth;
int textureHeight;
}; };
void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom) void R_DrawTriangles(const VSMatrix &transform, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture)
{ {
if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH) if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH)
return; return;
@ -1687,7 +1700,7 @@ void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, i
for (int i = 0; i < cliplength; i++) for (int i = 0; i < cliplength; i++)
clipdata[cliplength + i] = clipbottom[clipleft + i]; clipdata[cliplength + i] = clipbottom[clipleft + i];
DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(objectToWorld, vertices, count, clipleft, clipright, clipdata); DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(transform, vertices, count, clipleft, clipright, clipdata, texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight());
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -998,85 +998,66 @@ static void R_DrawCubeSky(visplane_t *pl)
static TriVertex cube[6 * 6] = static TriVertex cube[6 * 6] =
{ {
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // Top
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f, 1.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.1f, 1.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
// Bottom
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.9f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // Front
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // Back
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
// Right
{ 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // Left
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }
}; };
static bool first_time = true; VSMatrix transform(0);
if (first_time) transform.translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
{ transform.scale(1000.0f, 1000.0f, 1000.0f);
for (int i = 0; i < 6; i++)
{
cube[i * 6 + 0].varying[0] = 1.0f;
cube[i * 6 + 1].varying[1] = 1.0f;
cube[i * 6 + 2].varying[2] = 1.0f;
cube[i * 6 + 3].varying[2] = 1.0f;
cube[i * 6 + 4].varying[0] = 1.0f;
cube[i * 6 + 4].varying[1] = 1.0f;
cube[i * 6 + 4].varying[2] = 1.0f;
cube[i * 6 + 5].varying[0] = 1.0f;
}
first_time = false;
}
//static float angle = 0.0f; R_DrawTriangles(transform, cube, 6 * 6, x1, x2 - 1, uwal, dwal, frontskytex);
//angle = fmod(angle + 0.5f, 360.0f);
VSMatrix objectToWorld(0);
objectToWorld.translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
//objectToWorld.rotate(angle, 0.57735f, 0.57735f, 0.57735f);
objectToWorld.scale(100.0f, 100.0f, 100.0f);
R_DrawTriangles(objectToWorld, cube, 6 * 6, x1, x2 - 1, uwal, dwal);
} }
static void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat) static void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat)