Move triangle drawer into a command and change the sky code to use it if r_cubesky is enabled

This commit is contained in:
Magnus Norddahl 2016-10-19 17:44:50 +02:00
parent ea72152c31
commit d5865a46a0
5 changed files with 505 additions and 418 deletions

View file

@ -387,6 +387,19 @@ void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom);
void R_DrawDoubleSkyCol1(uint32_t solid_top, uint32_t solid_bottom);
void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom);
struct TriVertex
{
TriVertex() { }
TriVertex(float x, float y, float z, float w, float u, float v, float light) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; varying[2] = light; }
enum { NumVarying = 3 };
float x, y, z, w;
float varying[NumVarying];
};
class VSMatrix;
void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom);
extern bool r_swtruecolor;
EXTERN_CVAR(Bool, r_multithreaded);

View file

@ -1257,32 +1257,48 @@ void ApplySpecialColormapRGBACommand::Execute(DrawerThread *thread)
/////////////////////////////////////////////////////////////////////////////
struct TriVertex
class DrawTrianglesCommand : public DrawerCommand
{
TriVertex() { }
TriVertex(float x, float y, float z, float w, float u, float v, float light) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; varying[2] = light; }
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)
{
}
enum { NumVarying = 3 };
float x, y, z, w;
float varying[NumVarying];
};
void Execute(DrawerThread *thread) override
{
int cliplength = clipright - clipleft + 1;
for (int i = 0; i < cliplength; i++)
{
thread->triangle_clip_top[clipleft + i] = clipdata[i];
thread->triangle_clip_bottom[clipleft + i] = clipdata[cliplength + i];
}
float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
{
draw_triangles(objectToWorld, vertices, count, clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom, thread);
}
FString DebugInfo() override
{
return "DrawTrianglesCommand";
}
private:
float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
{
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2);
return top / bottom;
}
}
float grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
{
float grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
{
float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2);
float bottom = -((x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2));
return top / bottom;
}
}
void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v2, const TriVertex &v3, int clipleft, int clipright, const short *cliptop, const short *clipbottom)
{
void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v2, const TriVertex &v3, int clipleft, int clipright, const short *cliptop, const short *clipbottom, DrawerThread *thread)
{
// 28.4 fixed-point coordinates
const int Y1 = (int)round(16.0f * v1.y);
const int Y2 = (int)round(16.0f * v2.y);
@ -1431,6 +1447,8 @@ void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v
varyingStep[i] = (varyingTR[i] + varyingBR[i] * iy - varying[i]) * (1.0f / q);
}
if (!thread->skipped_by_thread(y + iy))
{
for (int ix = x; ix < x + q; ix++)
{
uint32_t red = (uint32_t)clamp(varying[0] * 255.0f + 0.5f, 0.0f, 255.0f);
@ -1442,6 +1460,7 @@ void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v
for (int i = 0; i < TriVertex::NumVarying; i++)
varying[i] += varyingStep[i];
}
}
buffer += pitch;
}
@ -1465,6 +1484,8 @@ void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v
varyingStep[i] = (varyingTR[i] + varyingBR[i] * iy - varying[i]) * (1.0f / q);
}
if (!thread->skipped_by_thread(y + iy))
{
for (int ix = x; ix < x + q; ix++)
{
bool visible = (cliptop[ix] <= y + iy) && (clipbottom[ix] >= y + iy);
@ -1485,6 +1506,7 @@ void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v
CX2 -= FDY23;
CX3 -= FDY31;
}
}
CY1 += FDX12;
CY2 += FDX23;
@ -1497,10 +1519,10 @@ void triangle(uint32_t *dest, int pitch, const TriVertex &v1, const TriVertex &v
dest += q * pitch;
}
}
}
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)
return true;
@ -1511,10 +1533,10 @@ bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t
t2 = MIN(1.0f + clipdistance2 / (clipdistance1 - clipdistance2), t2);
return false;
}
}
void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert)
{
void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert)
{
// Clip and cull so that the following is true for all vertices:
// -v.w <= v.x <= v.w
// -v.w <= v.y <= v.w
@ -1556,97 +1578,11 @@ void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert,
for (int i = 0; i < TriVertex::NumVarying; i++)
v.varying[i] = v1.varying[i] * (1.0f - t2) + v2.varying[i] * t2;
}
}
void R_DrawTriangle()
{
int clipleft = 0;
int clipright = viewwidth - 1;
short cliptop[MAXWIDTH];
short clipbottom[MAXWIDTH];
for (int i = clipleft; i < clipright; i++)
{
cliptop[i] = (i - clipleft) / 4;
clipbottom[i] = viewheight - 1 - (i - clipleft) / 4;
}
TriVertex cube[6 * 6] =
void draw_triangles(const VSMatrix &objectToWorld, const TriVertex *vinput, int vcount, int clipleft, int clipright, const short *cliptop, const short *clipbottom, DrawerThread *thread)
{
{-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, -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, 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 }
};
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;
}
static float angle = 0.0f;
angle = fmod(angle + 0.5f, 360.0f);
VSMatrix objectToWorld(0);
objectToWorld.translate((float)ViewPos.X, (float)ViewPos.Y + 50.0f, (float)ViewPos.Z);
objectToWorld.rotate(angle, 0.57735f, 0.57735f, 0.57735f);
objectToWorld.scale(10.0f, 10.0f, 10.0f);
TriVertex *vinput = cube;
for (int i = 0; i < 6 * 6 / 3; i++)
for (int i = 0; i < vcount / 3; i++)
{
TriVertex vert[3];
@ -1704,11 +1640,54 @@ void R_DrawTriangle()
v.y = (float)(CenterY - v.y * InvZtoScale);
}
// Draw screen triangles
bool ccw = false;
if (ccw)
{
for (int i = numclipvert; i > 1; i--)
{
triangle((uint32_t*)dc_destorg, dc_pitch, clippedvert[numclipvert - 1], clippedvert[i - 1], clippedvert[i - 2], clipleft, clipright, cliptop, clipbottom);
triangle((uint32_t*)dc_destorg, dc_pitch, clippedvert[numclipvert - 1], clippedvert[i - 1], clippedvert[i - 2], clipleft, clipright, cliptop, clipbottom, thread);
}
}
else
{
for (int i = 2; i < numclipvert; i++)
{
triangle((uint32_t*)dc_destorg, dc_pitch, clippedvert[0], clippedvert[i - 1], clippedvert[i], clipleft, clipright, cliptop, clipbottom, thread);
}
}
}
}
VSMatrix objectToWorld;
const TriVertex *vertices;
int count;
int clipleft;
int clipright;
const short *clipdata;
};
void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, int count, int clipleft, int clipright, const short *cliptop, const short *clipbottom)
{
if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH)
return;
int cliplength = clipright - clipleft + 1;
short *clipdata = (short*)DrawerCommandQueue::AllocMemory(cliplength * 2 * sizeof(short));
if (!clipdata)
{
DrawerCommandQueue::WaitForWorkers();
clipdata = (short*)DrawerCommandQueue::AllocMemory(cliplength * 2 * sizeof(short));
if (!clipdata)
return;
}
for (int i = 0; i < cliplength; i++)
clipdata[i] = cliptop[clipleft + i];
for (int i = 0; i < cliplength; i++)
clipdata[cliplength + i] = clipbottom[clipleft + i];
DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(objectToWorld, vertices, count, clipleft, clipright, clipdata);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -59,12 +59,14 @@
#include "v_palette.h"
#include "r_data/colormaps.h"
#include "r_draw_rgba.h"
#include "gl/data/gl_matrix.h"
#ifdef _MSC_VER
#pragma warning(disable:4244)
#endif
CVAR(Bool, r_capsky, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, r_cubesky, false, 0)
//EXTERN_CVAR (Int, tx)
//EXTERN_CVAR (Int, ty)
@ -1154,9 +1156,104 @@ static void R_DrawCapSky(visplane_t *pl)
}
}
static void R_DrawCubeSky(visplane_t *pl)
{
int x1 = pl->left;
int x2 = pl->right;
short *uwal = (short *)pl->top;
short *dwal = (short *)pl->bottom;
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 },
{ 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, 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, -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;
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;
}
//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);
}
static void R_DrawSky (visplane_t *pl)
{
if (r_swtruecolor && r_capsky)
if (r_swtruecolor && r_cubesky)
{
R_DrawCubeSky(pl);
return;
}
else if (r_swtruecolor && r_capsky)
{
R_DrawCapSky(pl);
return;

View file

@ -47,13 +47,10 @@
EXTERN_CVAR(Bool, r_shadercolormaps)
CVAR(Bool, r_drawtriangle, false, 0)
void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio);
void R_SetupColormap(player_t *);
void R_SetupFreelook();
void R_InitRenderer();
void R_DrawTriangle();
FSoftwareRenderer::FSoftwareRenderer()
{
@ -195,8 +192,6 @@ void FSoftwareRenderer::RenderView(player_t *player)
}
R_EndDrawerCommands();
if (r_swtruecolor && r_drawtriangle)
R_DrawTriangle();
}
//==========================================================================

View file

@ -36,6 +36,9 @@ public:
uint32_t dc_temp_rgbabuff_rgba[MAXHEIGHT * 4];
uint32_t *dc_temp_rgba;
short triangle_clip_top[MAXWIDTH];
short triangle_clip_bottom[MAXWIDTH];
// Checks if a line is rendered by this thread
bool line_skipped_by_thread(int line)
{