chihiro.cpp: enable clipping of vertices where w is negative (nw)

This commit is contained in:
yz70s 2016-12-13 19:45:45 +01:00
parent 8214ac7404
commit 9a09fab1fc
2 changed files with 68 additions and 39 deletions

View File

@ -358,7 +358,7 @@ public:
struct nv2avertex_t : public vertex_t struct nv2avertex_t : public vertex_t
{ {
float w; double w;
}; };
nv2a_renderer(running_machine &machine) : poly_manager<double, nvidia_object_data, 13, 8192>(machine) nv2a_renderer(running_machine &machine) : poly_manager<double, nvidia_object_data, 13, 8192>(machine)

View File

@ -2653,65 +2653,93 @@ uint32_t nv2a_renderer::render_triangle_culling(const rectangle &cliprect, rende
uint32_t nv2a_renderer::render_triangle_clipping(const rectangle &cliprect, render_delegate callback, int paramcount, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3) uint32_t nv2a_renderer::render_triangle_clipping(const rectangle &cliprect, render_delegate callback, int paramcount, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3)
{ {
#if 0 #if 1
nv2avertex_t *vi[3]; nv2avertex_t *vi[3];
nv2avertex_t vo[16]; nv2avertex_t vo[16];
int idx_prev, idx_curr; int idx_prev, idx_curr;
int neg_prev, neg_curr; int neg_prev, neg_curr;
float tfactor; double tfactor;
int idx; int idx;
const double wthreshold = 0.00000001;
#endif #endif
if ((_v1.w > 0) && (_v2.w > 0) && (_v3.w > 0)) if ((_v1.w > 0) && (_v2.w > 0) && (_v3.w > 0))
return render_triangle_culling(cliprect, callback, paramcount, _v1, _v2, _v3); return render_triangle_culling(cliprect, callback, paramcount, _v1, _v2, _v3);
#if 0 #if 1
// assign the elements of the array
vi[0] = &_v1; vi[0] = &_v1;
vi[1] = &_v2; vi[1] = &_v2;
vi[2] = &_v3; vi[2] = &_v3;
for (int n=0;n < 3;n++) // go back to the state before perpective divide
if (vertex_pipeline == 4)
{
for (int n = 0; n < 3; n++)
{
vi[n]->x = (vi[n]->x / (double)supersample_factor_x)*vi[n]->w;
vi[n]->y = (vi[n]->y / (double)supersample_factor_y)*vi[n]->w;
vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] * vi[n]->w;
}
} else
{
for (int n = 0; n < 3; n++)
{ {
// remove translate // remove translate
vi[n]->x = vi[n]->x - translatex; vi[n]->x = vi[n]->x - matrix.translate[0];
vi[n]->y = vi[n]->y - translatey; vi[n]->y = vi[n]->y - matrix.translate[1];
vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] - translatez; vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] - matrix.translate[2];
// remove scale // remove scale
vi[n]->x = vi[n]->x / scalex; vi[n]->x = vi[n]->x / matrix.translate[0];
vi[n]->y = vi[n]->y / scaley; vi[n]->y = vi[n]->y / matrix.translate[1];
vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] / scalez; vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] / matrix.translate[2];
// remove perspective divide // remove perspective divide
vi[n]->x = vi[n]->x * vi[n]->w; vi[n]->x = vi[n]->x * vi[n]->w;
vi[n]->y = vi[n]->y * vi[n]->w; vi[n]->y = vi[n]->y * vi[n]->w;
vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] * vi[n]->w; vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] = vi[n]->p[(int)VERTEX_PARAMETER::PARAM_Z] * vi[n]->w;
} }
}
// do the clipping
idx_prev = 2; idx_prev = 2;
idx_curr = 0; idx_curr = 0;
idx = 0; idx = 0;
neg_prev = vi[idx_prev]->w < 0.00000001 ? 1 : 0; neg_prev = vi[idx_prev]->w < wthreshold ? 1 : 0;
while (idx_curr < 3) while (idx_curr < 3)
{ {
neg_curr = vi[idx_curr]->w < 0.00000001 ? 1 : 0; neg_curr = vi[idx_curr]->w < wthreshold ? 1 : 0;
if (neg_curr ^ neg_prev) if (neg_curr ^ neg_prev)
{ {
float p = (float)0.00000001; tfactor = (wthreshold - vi[idx_prev]->w) / (vi[idx_curr]->w - vi[idx_prev]->w);
// compute values for the new intermediate point
tfactor = (p - vi[idx_prev]->w) / (vi[idx_curr]->w - vi[idx_prev]->w);
vo[idx].x = ((vi[idx_curr]->x - vi[idx_prev]->x) * tfactor) + vi[idx_prev]->x; vo[idx].x = ((vi[idx_curr]->x - vi[idx_prev]->x) * tfactor) + vi[idx_prev]->x;
vo[idx].y = ((vi[idx_curr]->y - vi[idx_prev]->y) * tfactor) + vi[idx_prev]->y; vo[idx].y = ((vi[idx_curr]->y - vi[idx_prev]->y) * tfactor) + vi[idx_prev]->y;
vo[idx].w = ((vi[idx_curr]->w - vi[idx_prev]->w) * tfactor) + vi[idx_prev]->w; vo[idx].w = ((vi[idx_curr]->w - vi[idx_prev]->w) * tfactor) + vi[idx_prev]->w;
for (int n=0;n < 13;n++) for (int n = 0; n < 13; n++)
vo[idx].p[n] = ((vi[idx_curr]->p[n] - vi[idx_prev]->p[n]) * tfactor) + vi[idx_prev]->p[n]; vo[idx].p[n] = ((vi[idx_curr]->p[n] - vi[idx_prev]->p[n]) * tfactor) + vi[idx_prev]->p[n];
idx++; idx++;
} }
if (neg_curr == 0) if (neg_curr == 0)
{ {
memcpy(&vo[idx], vi[idx_curr],sizeof(nv2avertex_t)); vo[idx].x = vi[idx_curr]->x;
vo[idx].y = vi[idx_curr]->y;
vo[idx].w = vi[idx_curr]->w;
for (int n = 0; n < 13; n++)
vo[idx].p[n] = vi[idx_curr]->p[n];
idx++; idx++;
} }
neg_prev = neg_curr; neg_prev = neg_curr;
idx_prev = idx_curr; idx_prev = idx_curr;
idx_curr++; idx_curr++;
} }
// screen coordinates for the new points
if (vertex_pipeline == 4)
{
for (int n = 0; n < idx; n++)
{
vo[n].x = vo[n].x*(double)supersample_factor_x / vo[n].w;
vo[n].y = vo[n].y*(double)supersample_factor_y / vo[n].w;
vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] / vo[n].w;
}
} else
{
for (int n = 0; n < idx; n++) for (int n = 0; n < idx; n++)
{ {
// apply perspective divide // apply perspective divide
@ -2719,15 +2747,16 @@ uint32_t nv2a_renderer::render_triangle_clipping(const rectangle &cliprect, rend
vo[n].y = vo[n].y / vo[n].w; vo[n].y = vo[n].y / vo[n].w;
vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] / vo[n].w; vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] / vo[n].w;
// apply scale // apply scale
vo[n].x = vo[n].x * scalex; vo[n].x = vo[n].x * matrix.scale[0];
vo[n].y = vo[n].y * scaley; vo[n].y = vo[n].y * matrix.scale[1];
vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] * scalez; vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] * matrix.scale[2];
// apply translate // apply translate
vo[n].x = vo[n].x + translatex; vo[n].x = vo[n].x + matrix.translate[0];
vo[n].y = vo[n].y + translatey; vo[n].y = vo[n].y + matrix.translate[1];
vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] + translatez; vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] = vo[n].p[(int)VERTEX_PARAMETER::PARAM_Z] + matrix.translate[2];
} }
for (int n = 0; n < (idx-2); n++) }
for (int n = 0; n < (idx - 2); n++)
{ {
if ((n & 1) == 0) if ((n & 1) == 0)
render_triangle_culling(cliprect, callback, paramcount, vo[n], vo[n + 1], vo[n + 2]); render_triangle_culling(cliprect, callback, paramcount, vo[n], vo[n + 1], vo[n + 2]);