- Implement model rendering in softpoly

This commit is contained in:
Magnus Norddahl 2017-11-24 00:39:10 +01:00
commit 00d7dd0c64
13 changed files with 444 additions and 4 deletions

View file

@ -130,6 +130,16 @@ void PolyDrawArgs::DrawArray(PolyRenderThread *thread, const TriVertex *vertices
{
mVertices = vertices;
mVertexCount = vcount;
mElements = nullptr;
mDrawMode = mode;
thread->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
}
void PolyDrawArgs::DrawElements(PolyRenderThread *thread, const TriVertex *vertices, const unsigned int *elements, int count, PolyDrawMode mode)
{
mVertices = vertices;
mElements = elements;
mVertexCount = count;
mDrawMode = mode;
thread->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
}

View file

@ -83,12 +83,14 @@ public:
void SetLights(PolyLight *lights, int numLights) { mLights = lights; mNumLights = numLights; }
void SetDynLightColor(uint32_t color) { mDynLightColor = color; }
void DrawArray(PolyRenderThread *thread, const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
void DrawElements(PolyRenderThread *thread, const TriVertex *vertices, const unsigned int *elements, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
const TriMatrix *ObjectToClip() const { return mObjectToClip; }
const PolyClipPlane &ClipPlane(int index) const { return mClipPlane[index]; }
const TriVertex *Vertices() const { return mVertices; }
int VertexCount() const { return mVertexCount; }
const unsigned int *Elements() const { return mElements; }
PolyDrawMode DrawMode() const { return mDrawMode; }
bool FaceCullCCW() const { return mFaceCullCCW; }
@ -139,6 +141,7 @@ private:
const TriMatrix *mObjectToClip = nullptr;
const TriVertex *mVertices = nullptr;
int mVertexCount = 0;
const unsigned int *mElements = nullptr;
PolyDrawMode mDrawMode = PolyDrawMode::Triangles;
bool mFaceCullCCW = false;
bool mDepthTest = false;

View file

@ -84,6 +84,64 @@ bool PolyTriangleDrawer::is_mirror()
return mirror;
}
void PolyTriangleDrawer::draw_elements(const PolyDrawArgs &drawargs, WorkerThreadData *thread)
{
if (drawargs.VertexCount() < 3)
return;
TriDrawTriangleArgs args;
args.dest = dest;
args.pitch = dest_pitch;
args.clipright = dest_width;
args.clipbottom = dest_height;
args.uniforms = &drawargs;
args.destBgra = dest_bgra;
args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
args.stencilValues = PolyStencilBuffer::Instance()->Values();
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
args.zbuffer = PolyZBuffer::Instance()->Values();
bool ccw = drawargs.FaceCullCCW();
const TriVertex *vinput = drawargs.Vertices();
const unsigned int *elements = drawargs.Elements();
int vcount = drawargs.VertexCount();
ShadedTriVertex vert[3];
if (drawargs.DrawMode() == PolyDrawMode::Triangles)
{
for (int i = 0; i < vcount / 3; i++)
{
for (int j = 0; j < 3; j++)
vert[j] = shade_vertex(drawargs, vinput[*(elements++)]);
draw_shaded_triangle(vert, ccw, &args, thread);
}
}
else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan)
{
vert[0] = shade_vertex(drawargs, vinput[*(elements++)]);
vert[1] = shade_vertex(drawargs, vinput[*(elements++)]);
for (int i = 2; i < vcount; i++)
{
vert[2] = shade_vertex(drawargs, vinput[*(elements++)]);
draw_shaded_triangle(vert, ccw, &args, thread);
vert[1] = vert[2];
}
}
else // TriangleDrawMode::TriangleStrip
{
vert[0] = shade_vertex(drawargs, vinput[*(elements++)]);
vert[1] = shade_vertex(drawargs, vinput[*(elements++)]);
for (int i = 2; i < vcount; i++)
{
vert[2] = shade_vertex(drawargs, vinput[*(elements++)]);
draw_shaded_triangle(vert, ccw, &args, thread);
vert[0] = vert[1];
vert[1] = vert[2];
ccw = !ccw;
}
}
}
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread)
{
if (drawargs.VertexCount() < 3)
@ -472,7 +530,10 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
thread_data.core = thread->core;
thread_data.num_cores = thread->num_cores;
PolyTriangleDrawer::draw_arrays(args, &thread_data);
if (!args.Elements())
PolyTriangleDrawer::draw_arrays(args, &thread_data);
else
PolyTriangleDrawer::draw_elements(args, &thread_data);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -40,6 +40,7 @@ public:
private:
static ShadedTriVertex shade_vertex(const PolyDrawArgs &drawargs, const TriVertex &v);
static void draw_elements(const PolyDrawArgs &args, WorkerThreadData *thread);
static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread);
static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread);
static bool is_degenerate(const ShadedTriVertex *vertices);