diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 6d6661b43f..91cab3a69d 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "../GPUState.h" + #include "Clipper.h" #include "Rasterizer.h" @@ -97,17 +99,33 @@ static inline int CalcClipMask(const ClipCoords& v) void ProcessQuad(VertexData* data) { - // TODO: Clipping + if (!gstate.isModeThrough()) { + // TODO: Clipping + } - VertexData verts[6] = { data[0], data[0], data[1], data[1], data[0], data[0] }; + VertexData verts[6] = { data[0], data[0], data[1], data[1], data[1], data[0] }; verts[1].drawpos.x = data[1].drawpos.x; verts[4].drawpos.x = data[0].drawpos.x; - Rasterizer::DrawTriangle(data); - Rasterizer::DrawTriangle(data+3); + + // Color values of second vertex are used for the whole rectangle + verts[0].color0 = verts[1].color0; + verts[1].color0 = verts[1].color0; + verts[5].color0 = verts[1].color0; + verts[0].color1 = verts[1].color1; + verts[1].color1 = verts[1].color1; + verts[5].color1 = verts[1].color1; + + Rasterizer::DrawTriangle(verts); + Rasterizer::DrawTriangle(verts+3); } void ProcessTriangle(VertexData* data) { + if (gstate.isModeThrough()) { + Rasterizer::DrawTriangle(data); + return; + } + enum { NUM_CLIPPED_VERTICES = 33, NUM_INDICES = NUM_CLIPPED_VERTICES + 3 }; VertexData* Vertices[NUM_CLIPPED_VERTICES]; diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 5fb841c14f..90988f6566 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -122,10 +122,15 @@ void DrawTriangle(VertexData vertexdata[3]) // TODO: Should only render when it's on the left of the right edge if (w0 >=0 && w1 >= 0 && w2 >= 0) { + // TODO: I fail at barycentric coordinates, I think... this doesn't seem to do what I think it's doing float s = vertexdata[0].texturecoords.s() * w0 / w + vertexdata[1].texturecoords.s() * w1 / w + vertexdata[2].texturecoords.s() * w2 / w; float t = vertexdata[0].texturecoords.t() * w0 / w + vertexdata[1].texturecoords.t() * w1 / w + vertexdata[2].texturecoords.t() * w2 / w; + u32 vcol0 = (int)((vertexdata[0].color0.x * w0 / w + vertexdata[1].color0.x * w1 / w + vertexdata[2].color0.x * w2 / w) * 255)*256*256*256 + + (int)((vertexdata[0].color0.y * w0 / w + vertexdata[1].color0.y * w1 / w + vertexdata[2].color0.y * w2 / w) * 255)*256*256 + + (int)((vertexdata[0].color0.z * w0 / w + vertexdata[1].color0.z * w1 / w + vertexdata[2].color0.z * w2 / w) * 255)*256 + + (int)((vertexdata[0].color0.w * w0 / w + vertexdata[1].color0.w * w1 / w + vertexdata[2].color0.w * w2 / w) * 255); u32 color = /*TextureDecoder::*/SampleNearest(0, s, t); - *(u32*)&fb[p.x*4+p.y*FB_WIDTH*4] = color | 0xff7f0000; + *(u32*)&fb[p.x*4+p.y*FB_WIDTH*4] = color | vcol0; } } } diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 003066d209..90b145bb54 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -265,12 +265,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) // TODO: Index support... ERROR_LOG(G3D, "Using indices... fail"); } - if (gstate.isModeThrough()) - { - // TODO: through mode support... - ERROR_LOG(G3D, "Using through mode... fail"); - break; - } TransformUnit::SubmitPrimitive(verts, type, count, gstate.vertType); } diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 5bd5559ce4..e745c0652b 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -97,16 +97,32 @@ void TransformUnit::SubmitPrimitive(void* vertices, u32 prim_type, int vertex_co vreader.Goto(vtx+i); vreader.ReadPos(pos); - if (gstate.textureMapEnable && vreader.hasUV()) - { + if (!gstate.isModeClear() && gstate.textureMapEnable && vreader.hasUV()) { float uv[2]; vreader.ReadUV(uv); data[i].texturecoords = Vec2(uv[0], uv[1]); } - ModelCoords mcoords(pos[0], pos[1], pos[2]); - data[i].clippos = ClipCoords(ClipCoords(TransformUnit::ViewToClip(TransformUnit::WorldToView(TransformUnit::ModelToWorld(mcoords))))); - data[i].drawpos = DrawingCoords(TransformUnit::ScreenToDrawing(TransformUnit::ClipToScreen(data[i].clippos))); + if (vreader.hasColor0()) { + float col[4]; + vreader.ReadColor0(col); + data[i].color0 = Vec4(col[0], col[1], col[2], col[3]); + } + + if (vreader.hasColor1()) { + float col[3]; + vreader.ReadColor0(col); + data[i].color1 = Vec3(col[0], col[1], col[2]); + } + + if (!gstate.isModeThrough()) { + ModelCoords mcoords(pos[0], pos[1], pos[2]); + data[i].clippos = ClipCoords(ClipCoords(TransformUnit::ViewToClip(TransformUnit::WorldToView(TransformUnit::ModelToWorld(mcoords))))); + data[i].drawpos = DrawingCoords(TransformUnit::ScreenToDrawing(TransformUnit::ClipToScreen(data[i].clippos))); + } else { + data[i].drawpos.x = pos[0]; + data[i].drawpos.y = pos[1]; + } } // TODO: Should do lighting here! diff --git a/GPU/Software/TransformUnit.h b/GPU/Software/TransformUnit.h index 4ae8ce6cd6..65c623558b 100644 --- a/GPU/Software/TransformUnit.h +++ b/GPU/Software/TransformUnit.h @@ -53,11 +53,22 @@ struct VertexData texturecoords.x = LINTERP(t, a.texturecoords.x, b.texturecoords.x); texturecoords.y = LINTERP(t, a.texturecoords.y, b.texturecoords.y); + + color0.x = LINTERP(t, a.color0.x, b.color0.x); + color0.y = LINTERP(t, a.color0.y, b.color0.y); + color0.z = LINTERP(t, a.color0.z, b.color0.z); + color0.w = LINTERP(t, a.color0.w, b.color0.w); + + color1.x = LINTERP(t, a.color1.x, b.color1.x); + color1.y = LINTERP(t, a.color1.y, b.color1.y); + color1.z = LINTERP(t, a.color1.z, b.color1.z); } ClipCoords clippos; DrawingCoords drawpos; // TODO: Shouldn't store this ? Vec2 texturecoords; + Vec4 color0; + Vec3 color1; }; class TransformUnit