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

View file

@ -1260,8 +1260,8 @@ void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
class DrawTrianglesCommand : public DrawerCommand
{
public:
DrawTrianglesCommand(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *clipdata)
: objectToWorld(objectToWorld), vertices(vertices), count(count), clipleft(clipleft), clipright(clipright), clipdata(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)
: 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];
}
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
@ -1337,7 +1337,7 @@ private:
int minx = MAX((MIN(MIN(X1, X2), X3) + 0xF) >> 4, clipleft);
int maxx = MIN((MAX(MAX(X1, X2), X3) + 0xF) >> 4, clipright);
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)
return;
@ -1407,9 +1407,9 @@ private:
// Check if block needs clipping
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
@ -1451,11 +1451,15 @@ private:
{
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 green = (uint32_t)clamp(varying[1] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t blue = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//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++)
varying[i] += varyingStep[i];
@ -1488,15 +1492,19 @@ private:
{
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)
{
uint32_t red = (uint32_t)clamp(varying[0] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t green = (uint32_t)clamp(varying[1] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t blue = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//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++)
@ -1523,13 +1531,15 @@ private:
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;
if (clipdistance1 < 0.0f)
if (d1 < 0.0f)
t1 = MAX(-clipdistance1 / (clipdistance2 - clipdistance1), t1);
if (clipdistance2 < 0.0f)
if (d2 < 0.0f)
t2 = MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2);
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++)
{
@ -1592,8 +1602,8 @@ private:
auto &v = vert[j];
v = *(vinput++);
// Apply object to world transform:
const float *matrix = objectToWorld.get();
// Apply transform to get world coordinates:
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 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;
@ -1611,9 +1621,9 @@ private:
double tr_z = v.z - ViewPos.Z;
double tx = tr_x * ViewSin - tr_y * ViewCos;
double tz = tr_x * ViewTanCos + tr_y * ViewTanSin;
v.x = (float)tx;
v.y = (float)tr_z;
v.z = (float)(-tz * (farp + nearp) / (nearp - farp) + (2.0f * farp * nearp) / (nearp - farp));
v.x = (float)tx * 0.5f;
v.y = (float)tr_z * 0.5f;
v.z = (float)((-tz * (farp + nearp) / (nearp - farp) + (2.0f * farp * nearp) / (nearp - farp)));
v.w = (float)tz;
}
@ -1636,8 +1646,8 @@ private:
v.z *= v.w;
// Apply viewport scale to get screen coordinates:
v.x = (float)(CenterX + v.x * CenterX);
v.y = (float)(CenterY - v.y * InvZtoScale);
v.x = (float)(CenterX + v.x * 2.0f * CenterX);
v.y = (float)(CenterY - v.y * 2.0f * InvZtoScale);
}
// Draw screen triangles
@ -1659,15 +1669,18 @@ private:
}
}
VSMatrix objectToWorld;
VSMatrix transform;
const TriVertex *vertices;
int count;
int clipleft;
int clipright;
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)
return;
@ -1687,7 +1700,7 @@ void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, i
for (int i = 0; i < cliplength; 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] =
{
{ -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 },
// Top
{ -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.1f, 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, 0.6f, 1.0f, 0.0f, 0.1f, 1.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.1f, 1.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, 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, 1.0f, 1.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.9f, 1.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 },
{ -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 },
// Front
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.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 },
{ 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 },
// Back
{ -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, 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, 2.0f, 1.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.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, 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, 2.0f, 1.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.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, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f },
// Left
{ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.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, 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 },
{ -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, 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 }
};
static bool first_time = true;
if (first_time)
{
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;
}
VSMatrix transform(0);
transform.translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
transform.scale(1000.0f, 1000.0f, 1000.0f);
//static float angle = 0.0f;
//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);
R_DrawTriangles(transform, cube, 6 * 6, x1, x2 - 1, uwal, dwal, frontskytex);
}
static void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat)