diff --git a/src/mame/drivers/namcos23.c b/src/mame/drivers/namcos23.c index 2f6e351d971..ed64c44983a 100644 --- a/src/mame/drivers/namcos23.c +++ b/src/mame/drivers/namcos23.c @@ -1928,10 +1928,9 @@ void namcos23_state::render_project(poly_vertex &pv) // 640/(3.125/3.75) = 768 // 480/(2.34375/3.75) = 768 - float w = pv.p[0] ? 1/pv.p[0] : 0; - pv.x = 320 + 768*w*pv.x; - pv.y = 240 - 768*w*pv.y; - pv.p[0] = w; + pv.x = 320 + 768 * pv.x; + pv.y = 240 - 768 * pv.y; + pv.p[0] = 1.0f / pv.p[0]; } static UINT32 render_texture_lookup_nocache_point(running_machine &machine, const pen_t *pens, float x, float y) @@ -2034,22 +2033,72 @@ void namcos23_state::render_one_model(const namcos23_render_entry *re) namcos23_poly_entry *p = render.polys + render.poly_count; + // Should be unnecessary now that frustum clipping happens, but this still culls polys behind the camera p->vertex_count = render.polymgr->zclip_if_less(ne, pv, p->pv, 4, 0.001f); - + + // Project if you don't clip on the near plane if(p->vertex_count >= 3) { - for(int i=0; ivertex_count; i++) { - render_project(p->pv[i]); - float w = p->pv[i].p[0]; - p->pv[i].p[1] *= w; - p->pv[i].p[2] *= w; - p->pv[i].p[3] *= w; - } - p->zkey = 0.5f*(minz+maxz); - p->front = !(h & 0x00000001); - p->rd.machine = &machine(); - p->rd.texture_lookup = render_texture_lookup_nocache_point; - p->rd.pens = m_palette->pens() + (color << 8); - render.poly_count++; + // Project the eye points + frustum_clip_vertex clipVerts[10]; + for(int i=0; ivertex_count; i++) { + // A basic perspective transform + const float Z = p->pv[i].p[0]; + const float projX = p->pv[i].x / Z; + const float projY = p->pv[i].y / Z; + + const float near = 0.001f; + const float far = 1000.0f; + const float m22 = -(far / (far-near)); + const float m23 = -((far * near) / (far - near)); + const float projZ = -(Z * m22) + m23; + const float projW = Z; + + // Construct a frustum clipping vert from the NDCoords + clipVerts[i].x = projX; + clipVerts[i].y = projY; + clipVerts[i].z = projZ; + clipVerts[i].w = projW; + clipVerts[i].p[0] = p->pv[i].p[1]; + clipVerts[i].p[1] = p->pv[i].p[2]; + clipVerts[i].p[2] = p->pv[i].p[3]; + } + + // Clip against all edges of the view frustum + int num_vertices = frustum_clip_all(clipVerts, p->vertex_count, clipVerts); + + if (num_vertices != 0) + { + // Push the results back into the main vertices + for (int i=0; i < num_vertices; i++) + { + p->pv[i].x = clipVerts[i].x; + p->pv[i].y = clipVerts[i].y; + p->pv[i].p[0] = clipVerts[i].w; + p->pv[i].p[1] = clipVerts[i].p[0]; + p->pv[i].p[2] = clipVerts[i].p[1]; + p->pv[i].p[3] = clipVerts[i].p[2]; + } + p->vertex_count = num_vertices; + + // This is our poor-man's projection matrix + for(int i=0; ivertex_count; i++) + { + render_project(p->pv[i]); + + float w = p->pv[i].p[0]; + p->pv[i].p[1] *= w; + p->pv[i].p[2] *= w; + p->pv[i].p[3] *= w; + } + + // Compute an odd sorta'-Z thing that can situate the polygon wherever you want in Z-depth + p->zkey = 0.5f*(minz+maxz); + p->front = !(h & 0x00000001); + p->rd.machine = &machine(); + p->rd.texture_lookup = render_texture_lookup_nocache_point; + p->rd.pens = m_palette->pens() + (color << 8); + render.poly_count++; + } } if(type & 0x000010000) @@ -2087,12 +2136,15 @@ void namcos23_renderer::render_flush(bitmap_rgb32& bitmap) namcos23_render_data& extra = render.polymgr->object_data_alloc(); extra = p->rd; + // We should probably split the polygons into triangles ourselves to insure everything is being rendered properly if (p->vertex_count == 3) render_triangle(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv[0], p->pv[1], p->pv[2]); else if (p->vertex_count == 4) render_polygon<4>(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv); else if (p->vertex_count == 5) render_polygon<5>(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv); + else if (p->vertex_count == 6) + render_polygon<6>(scissor, render_delegate(FUNC(namcos23_renderer::render_scanline), this), 4, p->pv); } render.poly_count = 0;