mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
softgpu: Implement depth testing.
This commit is contained in:
parent
72a71702a5
commit
00b7fbd19e
@ -162,13 +162,16 @@ void ProcessQuad(VertexData* data)
|
||||
verts[1].drawpos.x = data[1].drawpos.x;
|
||||
verts[4].drawpos.x = data[0].drawpos.x;
|
||||
|
||||
// Color values of second vertex are used for the whole rectangle
|
||||
// Color and depth 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;
|
||||
verts[0].drawpos.z = verts[1].drawpos.z;
|
||||
verts[1].drawpos.z = verts[1].drawpos.z;
|
||||
verts[5].drawpos.z = verts[1].drawpos.z;
|
||||
|
||||
Rasterizer::DrawTriangle(verts);
|
||||
Rasterizer::DrawTriangle(verts+3);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "Rasterizer.h"
|
||||
|
||||
extern u8* fb;
|
||||
extern u8* depthbuf;
|
||||
|
||||
namespace Rasterizer {
|
||||
|
||||
@ -100,7 +101,7 @@ void DrawTriangle(VertexData vertexdata[3])
|
||||
minY = std::max(minY, gstate.getScissorY1());
|
||||
maxY = std::min(maxY, gstate.getScissorY2());
|
||||
|
||||
DrawingCoords p(minX, minY);
|
||||
DrawingCoords p(minX, minY, 0);
|
||||
for (p.y = minY; p.y <= maxY; ++p.y)
|
||||
{
|
||||
for (p.x = minX; p.x <= maxX; ++p.x)
|
||||
@ -114,6 +115,57 @@ void DrawTriangle(VertexData vertexdata[3])
|
||||
if (w0 >=0 && w1 >= 0 && w2 >= 0)
|
||||
{
|
||||
float den = 1.0f/vertexdata[0].clippos.w * w0 + 1.0f/vertexdata[1].clippos.w * w1 + 1.0f/vertexdata[2].clippos.w * w2;
|
||||
|
||||
// TODO: Depth range test
|
||||
|
||||
// TODO: Is it safe to ignore gstate.isDepthTestEnabled() when clear mode is enabled?
|
||||
if ((gstate.isDepthTestEnabled() && !gstate.isModeThrough()) || gstate.isModeClear()) {
|
||||
u16 z = (u16)((vertexdata[0].drawpos.z * w0 / vertexdata[0].clippos.w + vertexdata[1].drawpos.z * w1 / vertexdata[1].clippos.w + vertexdata[2].drawpos.z * w2 / vertexdata[2].clippos.w) / den);
|
||||
u16 reference_z = *(u16*)&depthbuf[p.x*2+p.y*(gstate.zbwidth&0x7C0)*2];
|
||||
bool pass = true;
|
||||
|
||||
switch (gstate.getDepthTestFunc()) {
|
||||
case GE_COMP_NEVER:
|
||||
pass = false;
|
||||
break;
|
||||
|
||||
case GE_COMP_ALWAYS:
|
||||
pass = true;
|
||||
break;
|
||||
|
||||
case GE_COMP_EQUAL:
|
||||
pass = (z == reference_z);
|
||||
break;
|
||||
|
||||
case GE_COMP_NOTEQUAL:
|
||||
pass = (z != reference_z);
|
||||
break;
|
||||
|
||||
case GE_COMP_LESS:
|
||||
pass = (z < reference_z);
|
||||
break;
|
||||
|
||||
case GE_COMP_LEQUAL:
|
||||
pass = (z <= reference_z);
|
||||
break;
|
||||
|
||||
case GE_COMP_GREATER:
|
||||
pass = (z > reference_z);
|
||||
break;
|
||||
|
||||
case GE_COMP_GEQUAL:
|
||||
pass = (z >= reference_z);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear mode forces depth test func to be ALWAYS
|
||||
if (!pass && !gstate.isModeClear())
|
||||
continue;
|
||||
|
||||
if (gstate.isDepthWriteEnabled() || (gstate.clearmode&0x40)) // TODO: Correct to enable depth writing in the clearmode case?
|
||||
*(u16*)&depthbuf[p.x*2+p.y*(gstate.zbwidth&0x7C0)*2] = z;
|
||||
}
|
||||
|
||||
float s = (vertexdata[0].texturecoords.s() * w0 / vertexdata[0].clippos.w + vertexdata[1].texturecoords.s() * w1 / vertexdata[1].clippos.w + vertexdata[2].texturecoords.s() * w2 / vertexdata[2].clippos.w) / den;
|
||||
float t = (vertexdata[0].texturecoords.t() * w0 / vertexdata[0].clippos.w + vertexdata[1].texturecoords.t() * w1 / vertexdata[1].clippos.w + vertexdata[2].texturecoords.t() * w2 / vertexdata[2].clippos.w) / den;
|
||||
u32 color = 0;
|
||||
@ -129,7 +181,7 @@ void DrawTriangle(VertexData vertexdata[3])
|
||||
if (gstate.isTextureMapEnabled())
|
||||
color |= /*TextureDecoder::*/SampleNearest(0, s, t);
|
||||
|
||||
*(u32*)&fb[p.x*4+p.y*(gstate.fbwidth&0x3C0)*4] = color;
|
||||
*(u32*)&fb[p.x*4+p.y*(gstate.fbwidth&0x7C0)*4] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ static GLint uni_tex = -1;
|
||||
static GLuint program;
|
||||
|
||||
const int FB_HEIGHT = 272;
|
||||
u8* fb = NULL; // TODO: Default address?
|
||||
u8* fb = NULL;
|
||||
u8* depthbuf = NULL;
|
||||
|
||||
GLuint OpenGL_CompileProgram(const char* vertexShader, const char* fragmentShader)
|
||||
{
|
||||
@ -135,7 +136,8 @@ SoftGPU::SoftGPU()
|
||||
attr_pos = glGetAttribLocation(program, "pos");
|
||||
attr_tex = glGetAttribLocation(program, "TexCoordIn");
|
||||
|
||||
fb = Memory::GetPointer(0x44000000);
|
||||
fb = Memory::GetPointer(0x44000000); // TODO: correct default address?
|
||||
depthbuf = Memory::GetPointer(0x44000000); // TODO: correct default address?
|
||||
}
|
||||
|
||||
SoftGPU::~SoftGPU()
|
||||
@ -531,6 +533,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
case GE_CMD_ZBUFPTR:
|
||||
{
|
||||
u32 ptr = op & 0xFFE000;
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
DEBUG_LOG(G3D,"Zbuf Ptr: %06x", ptr);
|
||||
}
|
||||
break;
|
||||
@ -538,6 +541,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
case GE_CMD_ZBUFWIDTH:
|
||||
{
|
||||
u32 w = data & 0xFFFFFF;
|
||||
depthbuf = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
DEBUG_LOG(G3D,"Zbuf Width: %i", w);
|
||||
}
|
||||
break;
|
||||
|
@ -63,6 +63,7 @@ DrawingCoords TransformUnit::ScreenToDrawing(const ScreenCoords& coords)
|
||||
// TODO: What to do when offset > coord?
|
||||
ret.x = (((u32)coords.x - (gstate.offsetx&0xffff))/16) & 0x3ff;
|
||||
ret.y = (((u32)coords.y - (gstate.offsety&0xffff))/16) & 0x3ff;
|
||||
ret.z = coords.z;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -152,6 +153,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
|
||||
} else {
|
||||
data[i].drawpos.x = pos[0];
|
||||
data[i].drawpos.y = pos[1];
|
||||
data[i].drawpos.z = 0; // TODO: Not sure if that's what we should do here
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,15 @@ struct ScreenCoords
|
||||
u16 z;
|
||||
};
|
||||
|
||||
typedef Vec2<u10> DrawingCoords; // TODO: Keep z component?
|
||||
struct DrawingCoords
|
||||
{
|
||||
DrawingCoords() {}
|
||||
DrawingCoords(u10 x, u10 y, u16 z) : x(x), y(y), z(z) {}
|
||||
|
||||
u10 x;
|
||||
u10 y;
|
||||
u16 z;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
@ -51,8 +59,10 @@ struct VertexData
|
||||
clippos.z = LINTERP(t, a.clippos.z, b.clippos.z);
|
||||
clippos.w = LINTERP(t, a.clippos.w, b.clippos.w);
|
||||
|
||||
// TODO: Should use a LINTERP_INT, too
|
||||
drawpos.x = LINTERP(t, a.drawpos.x, b.drawpos.x);
|
||||
drawpos.y = LINTERP(t, a.drawpos.y, b.drawpos.y);
|
||||
drawpos.z = LINTERP(t, a.drawpos.z, b.drawpos.z);
|
||||
|
||||
texturecoords.x = LINTERP(t, a.texturecoords.x, b.texturecoords.x);
|
||||
texturecoords.y = LINTERP(t, a.texturecoords.y, b.texturecoords.y);
|
||||
|
Loading…
Reference in New Issue
Block a user