Start work on implementing bbox, add a comment with some thoughts..

This commit is contained in:
Henrik Rydgard 2013-09-24 13:58:14 +02:00
parent 424b4cbd5f
commit bd8cb4b02d
6 changed files with 83 additions and 18 deletions

View File

@ -733,7 +733,7 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_VERTEXTYPE:
if (diff)
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
break;
case GE_CMD_REGION1:

View File

@ -811,10 +811,22 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
break;
case GE_CMD_BOUNDINGBOX:
if (data != 0)
WARN_LOG_REPORT_ONCE(boundingbox, G3D, "Unsupported bounding box: %06x", data);
// bounding box test. Let's assume the box was visible.
currentList->bboxResult = true;
if ((data % 8 == 0) && data < 64) { // Sanity check
void *control_points = Memory::GetPointer(gstate_c.vertexAddr);
if (gstate.vertType & GE_VTYPE_IDX_MASK) {
ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Indexed bounding box data not supported.");
// Data seems invalid. Let's assume the box test passed.
currentList->bboxResult = true;
break;
}
// Test if the bounding box is within the drawing region.
currentList->bboxResult = transformDraw_.TestBoundingBox(control_points, data, gstate.vertType);
} else {
ERROR_LOG_REPORT_ONCE(boundingbox, G3D, "Bad bounding box data: %06x", data);
// Data seems invalid. Let's assume the box test passed.
currentList->bboxResult = true;
}
break;
case GE_CMD_VERTEXTYPE:

View File

@ -23,14 +23,6 @@
// Here's how to evaluate them fast:
// http://and-what-happened.blogspot.se/2012/07/evaluating-b-splines-aka-basis-splines.html
// PSP compatible format so we can use the end of the pipeline
struct SimpleVertex {
float uv[2];
u8 color[4];
Vec3f nrm;
Vec3f pos;
};
// This normalizes a set of vertices in any format to SimpleVertex format, by processing away morphing AND skinning.
// The rest of the transform pipeline like lighting will go as normal, either hardware or software.
// The implementation is initially a bit inefficient but shouldn't be a big deal.

View File

@ -1247,3 +1247,50 @@ rotateVBO:
host->GPUNotifyDraw();
#endif
}
bool TransformDrawEngine::TestBoundingBox(void* control_points, int vertexCount, u32 vertType) {
// Simplify away bones and morph before proceeding
/*
SimpleVertex *corners = (SimpleVertex *)(decoded + 65536 * 12);
u8 *temp_buffer = decoded + 65536 * 24;
u32 origVertType = vertType;
vertType = NormalizeVertices((u8 *)corners, temp_buffer, (u8 *)control_points, 0, vertexCount, vertType);
for (int cube = 0; cube < vertexCount / 8; cube++) {
// For each cube...
for (int i = 0; i < 8; i++) {
const SimpleVertex &vert = corners[cube * 8 + i];
// To world space...
float worldPos[3];
Vec3ByMatrix43(worldPos, (float *)&vert.pos.x, gstate.worldMatrix);
// To view space...
float viewPos[3];
Vec3ByMatrix43(viewPos, worldPos, gstate.viewMatrix);
// And finally to screen space.
float frustumPos[4];
Vec3ByMatrix44(frustumPos, viewPos, gstate.projMatrix);
// Project to 2D
float x = frustumPos[0] / frustumPos[3];
float y = frustumPos[1] / frustumPos[3];
// Rescale 2d position
// ...
}
}
*/
// Let's think. A better approach might be to take the edges of the drawing region and the projection
// matrix to build a frustum pyramid, and then clip the cube against those planes. If all vertices fail the same test,
// the cube is out. Otherwise it's in.
// TODO....
return true;
}

View File

@ -90,18 +90,24 @@ public:
u16 drawsUntilNextFullHash;
};
// PSP compatible format so we can use the end of the pipeline in beziers etc
struct SimpleVertex {
float uv[2];
u8 color[4];
Vec3f nrm;
Vec3f pos;
};
// Handles transform, lighting and drawing.
class TransformDrawEngine : public GfxResourceHolder {
public:
TransformDrawEngine();
virtual ~TransformDrawEngine();
void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertexType, int forceIndexType, int *bytesRead);
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type);
void SubmitBezier(void* control_points, void* indices, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertex_type);
// legacy
void DrawBezier(int ucount, int vcount);
void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int forceIndexType, int *bytesRead);
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertType);
void SubmitBezier(void* control_points, void* indices, int count_u, int count_v, GEPatchPrimType prim_type, u32 vertType);
bool TestBoundingBox(void* control_points, int vertexCount, u32 vertType);
void DecodeVerts();
void SetShaderManager(ShaderManager *shaderManager) {

View File

@ -584,6 +584,14 @@ inline void Vec3ByMatrix43(float vecOut[3], const float v[3], const float m[12])
vecOut[2] = v[0] * m[2] + v[1] * m[5] + v[2] * m[8] + m[11];
}
inline void Vec3ByMatrix44(float vecOut[4], const float v[3], const float m[16])
{
vecOut[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[9];
vecOut[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[10];
vecOut[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[11];
vecOut[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + m[15];
}
inline void Norm3ByMatrix43(float vecOut[3], const float v[3], const float m[12])
{
vecOut[0] = v[0] * m[0] + v[1] * m[3] + v[2] * m[6];