Previous 199869 Revisions Next

r32826 Sunday 19th October, 2014 at 17:16:11 UTC by Ville Linde
model3: More rendering improvements [Ville Linde]
- Draw transparent triangles in a separate pass
- Implemented viewport priority
[src/mame/drivers]model3.c
[src/mame/includes]model3.h
[src/mame/video]model3.c

trunk/src/mame/includes/model3.h
r32825r32826
5656   cached_texture *texture;
5757   int param;
5858   int transparency;
59   int intensity;
6059   int color;
6160};
6261
r32825r32826
181180   cached_texture *m_texcache[2][1024/32][2048/32];
182181
183182   model3_renderer *m_renderer;
183   m3_triangle* m_tri_buffer;
184   m3_triangle* m_tri_alpha_buffer;
185   int m_tri_buffer_ptr;
186   int m_tri_alpha_buffer_ptr;
187   int m_viewport_tri_index[4];
188   int m_viewport_tri_alpha_index[4];
184189
185190   DECLARE_READ32_MEMBER(rtc72421_r);
186191   DECLARE_WRITE32_MEMBER(rtc72421_w);
r32825r32826
292297   TILE_GET_INFO_MEMBER(tile_info_layer1_8bit);
293298   TILE_GET_INFO_MEMBER(tile_info_layer2_8bit);
294299   TILE_GET_INFO_MEMBER(tile_info_layer3_8bit);
300   void reset_triangle_buffers();
301   m3_triangle* push_triangle(bool alpha);
295302   void draw_layers(bitmap_rgb32 &bitmap, const rectangle &cliprect);
296303   void draw_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect, int layer, int bitdepth, int sx, int sy);
297304   void draw_3d_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect);
trunk/src/mame/video/model3.c
r32825r32826
1111#define TRI_PARAM_TEXTURE_ENABLE        0x8
1212#define TRI_PARAM_ALPHA_TEST            0x10
1313
14#define TRI_BUFFER_SIZE               35000
15#define TRI_ALPHA_BUFFER_SIZE         15000
16
1417struct model3_polydata
1518{
1619   cached_texture *texture;
r32825r32826
2427{
2528public:
2629   model3_renderer(model3_state &state, int width, int height)
27      : poly_manager<float, model3_polydata, 6, 50000>(state.machine())//, m_state(state)
30      : poly_manager<float, model3_polydata, 6, 50000>(state.machine())
2831   {
2932      m_fb = auto_bitmap_rgb32_alloc(state.machine(), width, height);
3033      m_zb = auto_bitmap_ind32_alloc(state.machine(), width, height);
3134   }
3235
3336   void draw(bitmap_rgb32 &bitmap, const rectangle &cliprect);
34   void draw_triangle(const m3_triangle* tri);
35   void clear_buffers();
37   void draw_opaque_triangles(const m3_triangle* tris, int num_tris);
38   void draw_alpha_triangles(const m3_triangle* tris, int num_tris);
39   void clear_fb();
40   void clear_zb();
3641   void draw_scanline_solid(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
3742   void draw_scanline_tex(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
38   void draw_scanline_contour(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
43   void draw_scanline_tex_contour(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
3944   void draw_scanline_tex_trans(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
4045   void draw_scanline_tex_alpha(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
46   void wait_for_polys();
4147
4248private:
43   //model3_state &m_state;
4449   bitmap_rgb32 *m_fb;
4550   bitmap_ind32 *m_zb;
4651};
r32825r32826
153158
154159   m_renderer = auto_alloc(machine(), model3_renderer(*this, width, height));
155160
161   m_tri_buffer = auto_alloc_array_clear(machine(), m3_triangle, TRI_BUFFER_SIZE);
162   m_tri_alpha_buffer = auto_alloc_array_clear(machine(), m3_triangle, TRI_ALPHA_BUFFER_SIZE);
163
156164   machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model3_state::model3_exit), this));
157165
158166   m_m3_char_ram = auto_alloc_array_clear(machine(), UINT64, 0x100000/8);
r32825r32826
10071015   }
10081016   m_texture_fifo_pos = 0;
10091017
1010   m_renderer->clear_buffers();
1018   m_renderer->clear_fb();
10111019
1020   reset_triangle_buffers();
10121021   real3d_traverse_display_list();
1022
1023   /*
1024   m_renderer->draw_opaque_triangles(m_tri_buffer, m_tri_buffer_ptr);
1025   m_renderer->draw_alpha_triangles(m_tri_alpha_buffer, m_tri_alpha_buffer_ptr);
1026
1027   m_renderer->wait_for_polys();
1028   */
1029
1030   for (int i=0; i < 4; i++)
1031   {
1032      int ticount, tiacount;
1033      int ti = m_viewport_tri_index[i];
1034      int tia = m_viewport_tri_alpha_index[i];
1035      if (i < 3)
1036      {         
1037         ticount = m_viewport_tri_index[i+1] - ti;
1038         tiacount = m_viewport_tri_alpha_index[i+1] - tia;
1039      }
1040      else
1041      {
1042         ticount = m_tri_buffer_ptr - ti;
1043         tiacount = m_tri_alpha_buffer_ptr - tia;
1044      }
1045
1046      if (ticount > 0 || tiacount > 0)
1047      {
1048         m_renderer->clear_zb();
1049         m_renderer->draw_opaque_triangles(&m_tri_buffer[ti], ticount);
1050         m_renderer->draw_alpha_triangles(&m_tri_alpha_buffer[tia], tiacount);
1051         m_renderer->wait_for_polys();
1052      }
1053   }
10131054}
10141055
10151056void model3_state::real3d_display_list1_dma(UINT32 src, UINT32 dst, int length, int byteswap)
r32825r32826
12731314   return clip_verts;
12741315}
12751316
1317void model3_state::reset_triangle_buffers()
1318{
1319   m_tri_buffer_ptr = 0;
1320   m_tri_alpha_buffer_ptr = 0;
1321}
1322
1323m3_triangle *model3_state::push_triangle(bool alpha)
1324{
1325   if (!alpha)
1326   {
1327      int i = m_tri_buffer_ptr;
1328
1329      if (m_tri_buffer_ptr >= TRI_BUFFER_SIZE)
1330      {
1331         return NULL;
1332         //fatalerror("push_triangle: tri buffer max exceeded");
1333      }
1334     
1335      m_tri_buffer_ptr++;
1336      return &m_tri_buffer[i];
1337   }
1338   else
1339   {
1340      int i = m_tri_alpha_buffer_ptr;
1341
1342      if (m_tri_alpha_buffer_ptr >= TRI_ALPHA_BUFFER_SIZE)
1343      {
1344         return NULL;
1345         //fatalerror("push_triangle: tri alpha buffer max exceeded");
1346      }
1347
1348      m_tri_alpha_buffer_ptr++;
1349      return &m_tri_alpha_buffer[i];
1350   }
1351}
1352
12761353void model3_state::draw_model(UINT32 addr)
12771354{
12781355   // Polygon RAM is mapped to the low 4MB of VROM
r32825r32826
13111388      VECTOR3 normal;
13121389      VECTOR3 sn;
13131390      VECTOR p[4];
1314      m3_triangle tri;
1315      float dot;
13161391      int polygon_transparency;
13171392
13181393      for (i = 0; i < 7; i++)
r32825r32826
14291504         float intensity;
14301505         if ((header[6] & 0x10000) == 0)
14311506         {
1432            dot = dot_product3(n, m_parallel_light);
1507            float dot = dot_product3(n, m_parallel_light);
14331508            intensity = ((dot * m_parallel_light_intensity) + m_ambient_light_intensity) * 255.0f;
14341509            if (intensity > 255.0f)
14351510            {
r32825r32826
15001575         }
15011576
15021577         for (i=2; i < num_vertices; i++)
1503         {
1504            memcpy(&tri.v[0], &clip_vert[0], sizeof(m3_clip_vertex));
1505            memcpy(&tri.v[1], &clip_vert[i-1], sizeof(m3_clip_vertex));
1506            memcpy(&tri.v[2], &clip_vert[i], sizeof(m3_clip_vertex));
1578         {           
1579            bool alpha = (header[6] & 0x1) || (header[6] & 0x80000000);      // put to alpha buffer if there's any transparency involved
1580            m3_triangle* tri = push_triangle(alpha);
15071581
1508            tri.texture = texture;
1509            tri.transparency = polygon_transparency;
1510            tri.color = color;
1582            // bail out if tri buffer is maxed out (happens during harley boot)
1583            if (!tri)
1584               return;
15111585
1512            tri.param   = 0;
1513            tri.param   |= (header[4] & 0x40) ? TRI_PARAM_TEXTURE_PAGE : 0;
1514            tri.param   |= (header[6] & 0x00000400) ? TRI_PARAM_TEXTURE_ENABLE : 0;
1515            tri.param   |= (header[2] & 0x2) ? TRI_PARAM_TEXTURE_MIRROR_U : 0;
1516            tri.param   |= (header[2] & 0x1) ? TRI_PARAM_TEXTURE_MIRROR_V : 0;
1517            tri.param   |= (header[6] & 0x80000000) ? TRI_PARAM_ALPHA_TEST : 0;
1586            memcpy(&tri->v[0], &clip_vert[0], sizeof(m3_clip_vertex));
1587            memcpy(&tri->v[1], &clip_vert[i-1], sizeof(m3_clip_vertex));
1588            memcpy(&tri->v[2], &clip_vert[i], sizeof(m3_clip_vertex));
15181589
1519            m_renderer->draw_triangle(&tri);
1590            tri->texture = texture;
1591            tri->transparency = polygon_transparency;
1592            tri->color = color;
1593
1594            tri->param   = 0;
1595            tri->param   |= (header[4] & 0x40) ? TRI_PARAM_TEXTURE_PAGE : 0;
1596            tri->param   |= (header[6] & 0x00000400) ? TRI_PARAM_TEXTURE_ENABLE : 0;
1597            tri->param   |= (header[2] & 0x2) ? TRI_PARAM_TEXTURE_MIRROR_U : 0;
1598            tri->param   |= (header[2] & 0x1) ? TRI_PARAM_TEXTURE_MIRROR_V : 0;
1599            tri->param   |= (header[6] & 0x80000000) ? TRI_PARAM_ALPHA_TEST : 0;
15201600         }
15211601      }
15221602   }
r32825r32826
17141794   /* TODO: where does node[23] point to ? LOD table ? */
17151795
17161796   /* set lighting parameters */
1717   m_parallel_light[0] = -*(float *)&node[5];
1797   m_parallel_light[0] = *(float *)&node[5];
17181798   m_parallel_light[1] = *(float *)&node[6];
1719   m_parallel_light[2] = *(float *)&node[4];
1799   m_parallel_light[2] = -*(float *)&node[4];
17201800   m_parallel_light_intensity = *(float *)&node[7];
17211801   m_ambient_light_intensity = (UINT8)(node[36] >> 8) / 256.0f;
17221802
r32825r32826
17351815   m_list_depth = 0;
17361816
17371817   for (int pri = 0; pri < 4; pri++)
1818   {
1819      m_viewport_tri_index[pri] = m_tri_buffer_ptr;
1820      m_viewport_tri_alpha_index[pri] = m_tri_alpha_buffer_ptr;
17381821      draw_viewport(pri, 0x800000);
1822   }
17391823}
17401824
17411825void model3_renderer::draw(bitmap_rgb32 &bitmap, const rectangle &cliprect)
r32825r32826
17571841   }
17581842}
17591843
1760void model3_renderer::clear_buffers()
1844void model3_renderer::clear_fb()
17611845{
17621846   rectangle cliprect;
17631847   cliprect.min_x = 0;
r32825r32826
17661850   cliprect.max_y = 383;
17671851
17681852   m_fb->fill(0x00000000, cliprect);
1853}
17691854
1855void model3_renderer::clear_zb()
1856{
1857   rectangle cliprect;
1858   cliprect.min_x = 0;
1859   cliprect.min_y = 0;
1860   cliprect.max_x = 495;
1861   cliprect.max_y = 383;
1862   
17701863   float zvalue = 10000000000.0f;
17711864   m_zb->fill(*(int*)&zvalue, cliprect);
17721865}
17731866
1774void model3_renderer::draw_triangle(const m3_triangle *tri)
1867void model3_renderer::wait_for_polys()
17751868{
1869   wait();
1870}
1871
1872void model3_renderer::draw_opaque_triangles(const m3_triangle* tris, int num_tris)
1873{
17761874   rectangle cliprect;
17771875   cliprect.min_x = 0;
17781876   cliprect.min_y = 0;
17791877   cliprect.max_x = 495;
17801878   cliprect.max_y = 383;
17811879
1880//   printf("draw opaque: %d\n", num_tris);
1881
17821882   vertex_t v[3];
17831883
1784   if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
1884   for (int t=0; t < num_tris; t++)
17851885   {
1786      for (int i=0; i < 3; i++)
1886      const m3_triangle* tri = &tris[t];
1887
1888      if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
17871889      {
1788         v[i].x = tri->v[i].x;
1789         v[i].y = tri->v[i].y;
1790         v[i].p[0] = tri->v[i].z;
1791         v[i].p[1] = 1.0f / tri->v[i].z;
1792         v[i].p[2] = tri->v[i].u * 256.0f;       // 8 bits of subtexel precision for bilinear filtering
1793         v[i].p[3] = tri->v[i].v * 256.0f;
1794         v[i].p[4] = tri->v[i].i;
1890         for (int i=0; i < 3; i++)
1891         {
1892            v[i].x = tri->v[i].x;
1893            v[i].y = tri->v[i].y;
1894            v[i].p[0] = tri->v[i].z;
1895            v[i].p[1] = 1.0f / tri->v[i].z;
1896            v[i].p[2] = tri->v[i].u * 256.0f;       // 8 bits of subtexel precision for bilinear filtering
1897            v[i].p[3] = tri->v[i].v * 256.0f;
1898            v[i].p[4] = tri->v[i].i;
1899         }
1900   
1901         model3_polydata &extra = object_data_alloc();
1902         extra.texture = tri->texture;
1903         extra.transparency = tri->transparency;
1904         extra.texture_param = tri->param;
1905
1906         render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_tex), this), 5, v[0], v[1], v[2]);
17951907      }
1908      else
1909      {
1910         for (int i=0; i < 3; i++)
1911         {
1912            v[i].x = tri->v[i].x;
1913            v[i].y = tri->v[i].y;
1914            v[i].p[0] = tri->v[i].z;
1915            v[i].p[1] = tri->v[i].i;
1916         }
17961917
1797      model3_polydata &extra = object_data_alloc();
1798      extra.texture = tri->texture;
1799      extra.transparency = tri->transparency;
1800      extra.intensity = tri->intensity;
1801      extra.texture_param = tri->param;
1918         model3_polydata &extra = object_data_alloc();
1919         extra.color = tri->color;
18021920
1803      render_delegate rd;
1804      if (tri->param & TRI_PARAM_ALPHA_TEST)
1805      {
1806         rd = render_delegate(FUNC(model3_renderer::draw_scanline_contour), this);
1921         render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_solid), this), 2, v[0], v[1], v[2]);
18071922      }
1808      else if (extra.texture->alpha == 0xff)
1923   }
1924}
1925
1926void model3_renderer::draw_alpha_triangles(const m3_triangle* tris, int num_tris)
1927{
1928   rectangle cliprect;
1929   cliprect.min_x = 0;
1930   cliprect.min_y = 0;
1931   cliprect.max_x = 495;
1932   cliprect.max_y = 383;
1933
1934//   printf("draw alpha: %d\n", num_tris);
1935
1936   vertex_t v[3];
1937
1938   for (int t=num_tris-1; t >= 0; t--)
1939   {
1940      const m3_triangle* tri = &tris[t];
1941
1942      if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
18091943      {
1810         if (tri->transparency >= 32)
1811            rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex), this);
1944         for (int i=0; i < 3; i++)
1945         {
1946            v[i].x = tri->v[i].x;
1947            v[i].y = tri->v[i].y;
1948            v[i].p[0] = tri->v[i].z;
1949            v[i].p[1] = 1.0f / tri->v[i].z;
1950            v[i].p[2] = tri->v[i].u * 256.0f;       // 8 bits of subtexel precision for bilinear filtering
1951            v[i].p[3] = tri->v[i].v * 256.0f;
1952            v[i].p[4] = tri->v[i].i;
1953         }
1954   
1955         model3_polydata &extra = object_data_alloc();
1956         extra.texture = tri->texture;
1957         extra.transparency = tri->transparency;
1958         extra.texture_param = tri->param;
1959
1960         if (tri->param & TRI_PARAM_ALPHA_TEST)
1961         {
1962            render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_tex_contour), this), 5, v[0], v[1], v[2]);
1963         }
18121964         else
1813            rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex_trans), this);
1965         {
1966            render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_tex_alpha), this), 5, v[0], v[1], v[2]);
1967         }
18141968      }
18151969      else
18161970      {
1817         rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex_alpha), this);
1818      }
1971         for (int i=0; i < 3; i++)
1972         {
1973            v[i].x = tri->v[i].x;
1974            v[i].y = tri->v[i].y;
1975            v[i].p[0] = tri->v[i].z;
1976            v[i].p[1] = tri->v[i].i;
1977         }
18191978
1820      render_triangle(cliprect, rd, 5, v[0], v[1], v[2]);
1821   }
1822   else
1823   {
1824      for (int i=0; i < 3; i++)
1825      {
1826         v[i].x = tri->v[i].x;
1827         v[i].y = tri->v[i].y;
1828         v[i].p[0] = tri->v[i].z;
1829         v[i].p[1] = tri->v[i].i;
1979         model3_polydata &extra = object_data_alloc();
1980         extra.color = tri->color;
1981
1982         // TODO: scanline renderer for solid /w transparency
1983         render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_solid), this), 2, v[0], v[1], v[2]);
18301984      }
1831
1832      model3_polydata &extra = object_data_alloc();
1833
1834      extra.intensity = tri->intensity;
1835      extra.color = tri->color;
1836
1837      render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_solid), this), 2, v[0], v[1], v[2]);
18381985   }
18391986}
18401987
r32825r32826
19642111   }
19652112}
19662113
1967void model3_renderer::draw_scanline_contour(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
2114void model3_renderer::draw_scanline_tex_contour(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
19682115{
19692116   UINT32 *fb = &m_fb->pix32(scanline);
19702117   float *zb = (float*)&m_zb->pix32(scanline);
r32825r32826
20682215         b += ((orig & 0x000000ff) * desttrans) >> 5;
20692216
20702217         fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
2071         zb[x] = z;
20722218      }
20732219
20742220      ooz += dooz;
r32825r32826
21312277            b += ((orig & 0x000000ff) * minalpha) >> 8;
21322278
21332279            fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
2134            zb[x] = z;
21352280         }
21362281      }
21372282
trunk/src/mame/drivers/model3.c
r32825r32826
2626    vs29815 - massive memory trashing and page faults
2727
2828    vs2 - works
29    harley - works, wrong textures in many places, correct textures uploaded when the game ends
29    harley - works
3030    skichamp - boots after skipping the drive board errors, massive slowdowns
3131    srally2/sraly2dx - works
3232    von2/von254g - works
33    fvipers2 - waiting for decrementer (same code as eca)
33    fvipers2 - crashes after player selection
3434    vs298 - works, hangs with an onscreen error code
3535    vs299/vs2v991 - works
3636    oceanhun - same as daytona2
r32825r32826
60056005/* Model 3 Step 2.1 */
60066006GAME( 1998, daytona2,         0, model3_21, daytona2, model3_state, daytona2, ROT0, "Sega", "Daytona USA 2 (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60076007GAME( 1998, dayto2pe,         0, model3_21, daytona2, model3_state, dayto2pe, ROT0, "Sega", "Daytona USA 2 Power Edition", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6008GAME( 1998, dirtdvls,         0, model3_21, model3, model3_state,   dirtdvls, ROT0, "Sega", "Dirt Devils (set 1) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6009GAME( 1998, dirtdvlsa, dirtdvls, model3_21, model3, model3_state,   dirtdvls, ROT0, "Sega", "Dirt Devils (set 2) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6008GAME( 1998, dirtdvls,         0, model3_21, scud, model3_state,     dirtdvls, ROT0, "Sega", "Dirt Devils (set 1) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6009GAME( 1998, dirtdvlsa, dirtdvls, model3_21, scud, model3_state,     dirtdvls, ROT0, "Sega", "Dirt Devils (set 2) (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60106010GAME( 1998, swtrilgy,         0, model3_21, swtrilgy, model3_state, swtrilgy, ROT0, "Sega / LucasArts", "Star Wars Trilogy (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60116011GAME( 1998, swtrilgya, swtrilgy, model3_21, swtrilgy, model3_state, swtrilga, ROT0, "Sega / LucasArts", "Star Wars Trilogy", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60126012GAME( 1998, spikeout,         0, model3_21, model3, model3_state,   spikeout, ROT0, "Sega", "Spikeout (Revision C)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team