diff options
author | yz70s <yz70s@users.noreply.github.com> | 2016-02-01 23:28:56 +0100 |
---|---|---|
committer | yz70s <yz70s@users.noreply.github.com> | 2016-02-01 23:28:56 +0100 |
commit | 5e8d6c57bd99293eeee8328b4b392b97c1756438 (patch) | |
tree | 7e02f97a096154739dd641137f5af6c1a95c9c95 /src/mame | |
parent | 4ba9de3b750206e601de667450b8d254074e6850 (diff) |
chihiro.cpp: add backface culling to 3d accelerator (nw)
Diffstat (limited to 'src/mame')
-rw-r--r-- | src/mame/includes/chihiro.h | 16 | ||||
-rw-r--r-- | src/mame/video/chihiro.cpp | 68 |
2 files changed, 67 insertions, 17 deletions
diff --git a/src/mame/includes/chihiro.h b/src/mame/includes/chihiro.h index 0f68747059a..0a1915157c6 100644 --- a/src/mame/includes/chihiro.h +++ b/src/mame/includes/chihiro.h @@ -346,6 +346,15 @@ public: B8 = 9, G8B8 = 10 }; + enum class NV2A_GL_FRONT_FACE { + CW = 0x0900, + CCW = 0x0901 + }; + enum class NV2A_GL_CULL_FACE { + FRONT = 0x0404, + BACK = 0x0405, + FRONT_AND_BACK = 0x0408 + }; nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 13, 8192>(machine) { @@ -363,6 +372,9 @@ public: indexesleft_count = 0; vertex_pipeline = 4; color_mask = 0xffffffff; + backface_culling_enabled = false; + backface_culling_winding = NV2A_GL_FRONT_FACE::CCW; + backface_culling_culled = NV2A_GL_CULL_FACE::BACK; alpha_test_enabled = false; alpha_reference = 0; alpha_func = NV2A_COMPARISON_OP::ALWAYS; @@ -464,6 +476,7 @@ public: int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit); int read_vertices_0x1818(address_space & space, vertex_nv *destination, UINT32 address, int limit); void convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count); + UINT32 render_triangle_culling(const rectangle &cliprect, render_delegate callback, int paramcount, const vertex_t &_v1, const vertex_t &_v2, const vertex_t &_v3); void clear_render_target(int what, UINT32 value); void clear_depth_buffer(int what, UINT32 value); inline UINT8 *direct_access_ptr(offs_t address); @@ -630,6 +643,9 @@ public: std::mutex lock; } combiner; UINT32 color_mask; + bool backface_culling_enabled; + NV2A_GL_FRONT_FACE backface_culling_winding; + NV2A_GL_CULL_FACE backface_culling_culled; bool alpha_test_enabled; NV2A_COMPARISON_OP alpha_func; int alpha_reference; diff --git a/src/mame/video/chihiro.cpp b/src/mame/video/chihiro.cpp index e6c8e578bb6..845110e59b4 100644 --- a/src/mame/video/chihiro.cpp +++ b/src/mame/video/chihiro.cpp @@ -2549,6 +2549,25 @@ void nv2a_renderer::clear_depth_buffer(int what, UINT32 value) } } +UINT32 nv2a_renderer::render_triangle_culling(const rectangle &cliprect, render_delegate callback, int paramcount, const vertex_t &_v1, const vertex_t &_v2, const vertex_t &_v3) +{ + float areax2; + + if (backface_culling_enabled == false) + return render_triangle(cliprect, callback, paramcount, _v1, _v2, _v3); + if (backface_culling_culled == NV2A_GL_CULL_FACE::FRONT_AND_BACK) + return 0; + areax2 = _v1.x*(_v2.y - _v3.y) + _v2.x*(_v3.y - _v1.y) + _v3.x*(_v1.y - _v2.y); + if (backface_culling_winding == NV2A_GL_FRONT_FACE::CCW) + areax2 = -areax2; + // if areax2 >= 0 then front faced else back faced + if ((backface_culling_culled == NV2A_GL_CULL_FACE::FRONT) && (areax2 >= 0)) + return 0; + if ((backface_culling_culled == NV2A_GL_CULL_FACE::BACK) && (areax2 < 0)) + return 0; + return render_triangle(cliprect, callback, paramcount, _v1, _v2, _v3); +} + int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen) { UINT32 maddress; @@ -2592,7 +2611,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN for (n = 0; n <= count; n += 4) { read_vertices_0x1810(space, vertex_software + vertex_first, n + offset, 4); convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 4); - render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv + //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]); vertex_first = (vertex_first + 4) & 1023; vertex_count = vertex_count + 4; wait(); @@ -2602,7 +2623,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN for (n = 0; n <= count; n += 3) { read_vertices_0x1810(space, vertex_software + vertex_first, n + offset, 3); convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 3); - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv vertex_first = (vertex_first + 3) & 1023; vertex_count = vertex_count + 3; wait(); @@ -2624,7 +2645,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN for (n = 0; n <= count; n++) { read_vertices_0x1810(space, vertex_software + vertex_first, offset + n, 1); convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1); - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -2645,9 +2666,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN read_vertices_0x1810(space, vertex_software + vertex_first, offset + n, 1); convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1); if ((vertex_count & 1) == 0) - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); else - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -2691,7 +2712,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN address = address + c * 4; countlen = countlen - c; convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 4); - render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv + //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy + vertex_first); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]); vertex_first = (vertex_first + 4) & 1023; vertex_count = vertex_count + 4; wait(); @@ -2733,7 +2756,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1); address = address + c * 4; countlen = countlen - c; - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -2753,7 +2776,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN address = address + c * 4; countlen = countlen - c; convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 3); - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv vertex_first = (vertex_first + 3) & 1023; vertex_count = vertex_count + 3; wait(); @@ -2789,9 +2812,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN countlen = countlen - c; convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1); if ((vertex_count & 1) == 0) - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); else - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -2849,7 +2872,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN break; } address = address + c * 4; - render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy); // 4 rgba, 4 texture units 2 uv + //render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 1], vertex_xy[vertex_first + 2]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[vertex_first + 2], vertex_xy[vertex_first + 3]); vertex_first = (vertex_first + 4) & 1023; vertex_count = vertex_count + 4; wait(); @@ -2877,8 +2902,8 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN return 0; } address = address + c * 4; - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[n & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 2) & 3]); - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(n + 2) & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 3) & 3]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[n & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 2) & 3]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(n + 2) & 3], vertex_xy[(n + 1) & 3], vertex_xy[(n + 3) & 3]); wait(); } } @@ -2914,7 +2939,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } address = address + c * 4; convert_vertices_poly(vertex_software + vertex_first, vertex_xy + vertex_first, 1); - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[1024], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -2933,7 +2958,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN break; } address = address + c * 4; - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[vertex_first], vertex_xy[(vertex_first + 1) & 1023], vertex_xy[(vertex_first + 2) & 1023]); // 4 rgba, 4 texture units 2 uv vertex_first = (vertex_first + 3) & 1023; vertex_count = vertex_count + 3; wait(); @@ -2968,9 +2993,9 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } address = address + c * 4; if ((vertex_count & 1) == 0) - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[(vertex_first - 1) & 1023], vertex_xy[vertex_first]); else - render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); + render_triangle_culling(limits_rendertarget, renderspans, 4 + 4 * 2, vertex_xy[(vertex_first - 2) & 1023], vertex_xy[vertex_first], vertex_xy[(vertex_first - 1) & 1023]); vertex_first = (vertex_first + 1) & 1023; vertex_count = vertex_count + 1; wait(); @@ -3028,6 +3053,15 @@ int nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UIN } if ((maddress == 0x1d6c) || (maddress == 0x1d70) || (maddress == 0x1a4)) countlen--; + if (maddress == 0x0308) { + backface_culling_enabled = data != 0 ? true : false; + } + if (maddress == 0x03a0) { + backface_culling_winding = (NV2A_GL_FRONT_FACE)data; + } + if (maddress == 0x039c) { + backface_culling_culled = (NV2A_GL_CULL_FACE)data; + } if (maddress == 0x019c) { geforce_read_dma_object(data, dma_offset[0], dma_size[0]); } |