source: golgotha/src/golg/map_fast.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 15.6 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "image/image.hh"
10#include "palette/pal.hh"
11#include "map.hh"
12#include "math/transform.hh"
13#include "map_cell.hh"
14#include "poly/polydraw.hh"
15#include "resources.hh"
16#include "map_cell.hh"
17#include "poly/poly.hh"
18#include "tile.hh"
19#include "g1_object.hh"
20#include "statistics.hh"
21#include "time/profile.hh"
22#include "r1_api.hh"
23#include "g1_render.hh"
24#include "r1_clip.hh"
25#include "height_info.hh"
26#include "lisp/li_class.hh"
27#include "tmanage.hh"
28#include "map_cell.hh"
29#include "map_vert.hh"
30#include "draw_context.hh"
31#include "camera.hh"
32
33#if 0
34static i4_profile_class pf_map_fast_draw_tri("map_fast::draw tri"),
35  pf_map_fast_draw_terrain("map_fast::draw terrain"),
36  pf_map_fast_draw_objects("map_fast::dra objects"),
37  pf_map_fast_obj_list("map_fast::gen obj list"),
38  pf_map_fast_clear("map_fast::clear structures"),
39  pf_map_fast_clip_code("map_fast::clip codes"),
40  pf_map_fast_pack_uv("map_fast::pack uv's"),
41  pf_map_fast_transform("map_fast::transform"),
42  pf_project("map_fast::project"),
43  pf_pack_light("map_fast::pack light"),
44  pf_backface_test("map_fast::backface test"),
45  pf_map_fast_clip_tri("map_fast::clip tri"),
46  pf_map_fast_use_texture("map_fast::use texture"),
47  pf_map_fast_render("map_fast::render poly");
48
49
50static i4_bool do_fog;
51static r1_texture_ref g1_default_texture("tron_grid");
52
53i4_profile_class pf_draw_objects("draw objects");
54
55const w32          g1_max_objs_in_view = 256;
56w32                g1_num_objs_in_view = 0;
57w32 g1_objs_in_view[g1_max_objs_in_view];
58
59i4_array<i4_transform_class> g1_obj_transforms_in_view(0, g1_max_objs_in_view);
60class transform_killer_class : public i4_init_class
61{
62  //fix this trey!  can't have global i4_array's without something to clean it up.
63  void uninit() { g1_obj_transforms_in_view.uninit(); }
64} transform_killer;
65
66struct g1_draw_tri_struct
67{
68  g1_map_vertex_class *v1;
69  int vx1, vy1;
70
71  g1_map_vertex_class *v2;
72  int vx2, vy2;
73
74  g1_map_vertex_class *v3;
75  int vx3, vy3;
76
77  r1_texture_handle texture;
78  i4_float texture_scale;
79};
80
81
82r1_vert terrain_verts[4];
83         
84static r1_vert temp_buf_1[8],temp_buf_2[8];
85static w16 indices[4] = {0,1,2,3};
86
87inline void g1_draw_tri(g1_draw_tri_struct &ts, i4_transform_class &t, w16 cell_flags)
88{
89  g1_stat_counter.increment(g1_statistics_counter_class::TOTAL_POLYS);
90  g1_stat_counter.increment(g1_statistics_counter_class::TERRAIN);
91
92 
93  int and_code=ts.v1->clip_code & ts.v2->clip_code & ts.v3->clip_code;
94
95  if (and_code==0)     // at least one of the verts isn't clipped out
96  {
97    i4_3d_vector dot1,dot2, norm;
98    dot1 = i4_3d_vector(ts.v2->v.x - ts.v1->v.x, ts.v2->v.y - ts.v1->v.y, ts.v2->v.z - ts.v1->v.z);
99    dot2 = i4_3d_vector(ts.v3->v.x - ts.v1->v.x, ts.v3->v.y - ts.v1->v.y, ts.v3->v.z - ts.v1->v.z);
100    norm.cross(dot1,dot2);
101
102    i4_float facing=ts.v1->v.dot(norm);
103
104
105    if (facing < 0.0001)
106    {
107      int ins=0;
108
109      pf_pack_light.start();
110
111      if (do_fog)
112      {
113        if (!ts.v1->get_flag(g1_map_vertex_class::FOGGED))
114          ts.v1->get_rgb(terrain_verts[0].r, terrain_verts[0].g, terrain_verts[0].b, ts.vx1, ts.vy1);
115        else
116          terrain_verts[0].r=terrain_verts[0].g=terrain_verts[0].b=0;
117         
118        if (!ts.v2->get_flag(g1_map_vertex_class::FOGGED))
119          ts.v2->get_rgb(terrain_verts[1].r, terrain_verts[1].g, terrain_verts[1].b, ts.vx1, ts.vy1);
120        else
121          terrain_verts[1].r=terrain_verts[1].g=terrain_verts[1].b=0;
122
123        if (!ts.v3->get_flag(g1_map_vertex_class::FOGGED))
124          ts.v3->get_rgb(terrain_verts[2].r, terrain_verts[2].g, terrain_verts[2].b, ts.vx1, ts.vy1);
125        else
126          terrain_verts[2].r=terrain_verts[2].g=terrain_verts[2].b=0;
127      }
128      else
129      {
130        ts.v1->get_rgb(terrain_verts[0].r, terrain_verts[0].g, terrain_verts[0].b, ts.vx1, ts.vy1);
131        ts.v2->get_rgb(terrain_verts[1].r, terrain_verts[1].g, terrain_verts[1].b, ts.vx1, ts.vy1);
132        ts.v3->get_rgb(terrain_verts[2].r, terrain_verts[2].g, terrain_verts[2].b, ts.vx1, ts.vy1);
133      }
134     
135      pf_pack_light.stop();
136
137      pf_project.start();
138
139      float closest_ooz=0.0001;     
140     
141      if (!ts.v1->clip_code)
142      {
143        ts.v1->project(g1_render.center_x, g1_render.center_y);
144        terrain_verts[0].px  = ts.v1->px;
145        terrain_verts[0].py  = ts.v1->py;
146        terrain_verts[0].v.z = ts.v1->v.z;
147        terrain_verts[0].w   = ts.v1->w;
148        ins++;
149      }
150      if (ts.v1->w> closest_ooz) closest_ooz = ts.v1->w;
151     
152      if (!ts.v2->clip_code)
153      {
154        ts.v2->project(g1_render.center_x, g1_render.center_y);
155        terrain_verts[1].px  = ts.v2->px;
156        terrain_verts[1].py  = ts.v2->py;
157        terrain_verts[1].v.z = ts.v2->v.z;
158        terrain_verts[1].w   = ts.v2->w;       
159       
160        ins++;
161      }
162      if (ts.v2->w > closest_ooz) closest_ooz = ts.v2->w;
163     
164      if (!ts.v3->clip_code)
165      {
166        ts.v3->project(g1_render.center_x, g1_render.center_y);
167        terrain_verts[2].px  = ts.v3->px;
168        terrain_verts[2].py  = ts.v3->py;
169        terrain_verts[2].v.z = ts.v3->v.z;
170        terrain_verts[2].w   = ts.v3->w;       
171
172        ins++;
173      }
174      if (ts.v3->w > closest_ooz) closest_ooz = ts.v3->w;
175      if (closest_ooz>100) closest_ooz = 100;
176      pf_project.stop();
177     
178
179
180      sw32 num_poly_verts = 3;
181      r1_render_api_class *tmap=g1_render.r_api;
182
183      if (g1_render.draw_mode==g1_render_class::WIREFRAME)
184      {       
185        tmap->set_constant_color(0x7f7f7f);
186        tmap->disable_texture();
187        tmap->set_shading_mode(R1_SHADE_DISABLED);
188
189        terrain_verts[0].v.x = ts.v1->v.x;
190        terrain_verts[0].v.y = ts.v1->v.y;
191        terrain_verts[0].v.z = ts.v1->v.z;
192
193        terrain_verts[1].v.x = ts.v2->v.x;
194        terrain_verts[1].v.y = ts.v2->v.y;
195        terrain_verts[1].v.z = ts.v2->v.z;
196
197        terrain_verts[2].v.x = ts.v3->v.x;
198        terrain_verts[2].v.y = ts.v3->v.y;
199        terrain_verts[2].v.z = ts.v3->v.z;
200
201        r1_vert v[4];
202        v[0]=terrain_verts[0];
203        v[1]=terrain_verts[1];
204        v[2]=terrain_verts[2];
205        v[3]=terrain_verts[0];
206
207        r1_clip_render_lines(3, v, g1_render.center_x, g1_render.center_y, tmap);
208        tmap->set_shading_mode(R1_WHITE_SHADING);
209
210      }
211      else
212      {
213        if (ins == 3)
214        {
215          sw32 texture_size=i4_f_to_i(ts.texture_scale * g1_render.center_x * closest_ooz * 0.5);
216
217          if (g1_render.draw_mode!=g1_render_class::SOLID)
218            // completely in view       
219            tmap->use_texture(ts.texture, texture_size, 0);
220
221
222          pf_map_fast_render.start();
223          tmap->render_poly(num_poly_verts,terrain_verts);
224          pf_map_fast_render.stop();
225        }
226        else
227        {
228          pf_map_fast_clip_tri.start();
229
230          terrain_verts[0].v.x = ts.v1->v.x;
231          terrain_verts[0].v.y = ts.v1->v.y;
232          terrain_verts[0].v.z = ts.v1->v.z;
233         
234          terrain_verts[1].v.x = ts.v2->v.x;
235          terrain_verts[1].v.y = ts.v2->v.y;
236          terrain_verts[1].v.z = ts.v2->v.z;
237
238          terrain_verts[2].v.x = ts.v3->v.x;
239          terrain_verts[2].v.y = ts.v3->v.y;
240          terrain_verts[2].v.z = ts.v3->v.z;
241
242          r1_vert *clipped_poly = (tmap)->clip_poly(&num_poly_verts,
243                                                    terrain_verts,
244                                                    indices,
245                                                    temp_buf_1,
246                                                    temp_buf_2,
247                                                    0);
248          pf_map_fast_clip_tri.stop();
249
250          if (clipped_poly && num_poly_verts>=3)
251          {
252            pf_project.start();
253            for (sw32 j=0;j<num_poly_verts;j++)
254            {       
255              float ooz = r1_ooz(clipped_poly[j].v.z);
256           
257              clipped_poly[j].px = clipped_poly[j].v.x *
258                ooz * g1_render.center_x + g1_render.center_x;
259
260              clipped_poly[j].py = clipped_poly[j].v.y *
261                ooz * g1_render.center_y + g1_render.center_y;
262
263              clipped_poly[j].w  = ooz;
264
265            }
266            pf_project.stop();
267         
268            sw32 texture_size=i4_f_to_i(ts.texture_scale * g1_render.center_x * closest_ooz * 0.5);
269
270            if (g1_render.draw_mode!=g1_render_class::SOLID)
271              tmap->use_texture(ts.texture,  texture_size, 0);
272
273
274            pf_map_fast_render.start();
275            tmap->render_poly(num_poly_verts,clipped_poly);
276            pf_map_fast_render.stop();
277          }
278        }
279      }
280    }
281  }
282}
283
284
285void g1_map_class::fast_draw_cells(g1_draw_context_class  *context)
286{
287  i4_transform_class t=*context->transform;
288 
289  g1_map_vertex_class *v=verts;
290
291  sw32 i,cnt,cx,cy,mw_p1, w_xoff, w_yoff;
292  mw_p1=width()+1;
293 
294  g1_map_vertex_class *vt[4];
295
296
297  if (!g1_current_view_state())
298    do_fog=i4_F;
299  else
300    do_fog=g1_current_view_state()->get_view_mode()==G1_STRATEGY_MODE ? i4_T : i4_F;
301
302  r1_render_api_class *r_api = g1_render.r_api;
303 
304 
305  //runs through the cells, determines which objects will be drawn, generates their
306  //shadows if necessary
307  g1_num_objs_in_view = 0;
308  g1_obj_transforms_in_view.clear();
309
310 
311  g1_visible_cell *cell;
312
313  //step through the cells, front to back 
314  cell=cell_list+t_visible_cells-1;
315
316  g1_map_cell_class *m=cells;
317
318
319
320  pf_map_fast_obj_list.start();
321  for (i=t_visible_cells-1; i>=0; i--, cell--)
322  {
323    cx=cell->x;
324    cy=cell->y;
325    sw16 cell_number=cy*width()+cx;
326    g1_map_cell_class *map_cell=m+cell_number;
327
328    for (g1_object_chain_class *o=map_cell->get_obj_list(); o; o=o->next)
329    {
330      g1_object_class *obj=o->object;
331
332      if ((!do_fog ||
333          ((map_cell->flags & g1_map_cell_class::FOGGED)==0)) &&
334           !obj->get_flag(g1_object_class::SCRATCH_BIT))
335      {
336        g1_object_class *obj=o->object;
337
338        g1_stat_counter.increment(g1_statistics_counter_class::OBJECTS);           
339        if (g1_num_objs_in_view<g1_max_objs_in_view)
340        {             
341         
342          g1_objs_in_view[g1_num_objs_in_view] = o->object->global_id;
343          o->object->world_transform = g1_obj_transforms_in_view.add();
344         
345          g1_num_objs_in_view++;
346         
347          //have the object update his transform
348          o->object->calc_world_transform(g1_render.frame_ratio);
349         
350          o->object->set_flag(g1_object_class::SCRATCH_BIT, 1);
351        }   
352      }
353    }         
354  }
355  pf_map_fast_obj_list.stop();
356
357
358  if (g1_render.draw_mode==g1_render_class::SOLID)
359    g1_render.r_api->use_texture(g1_default_texture.get(), 1, 0);
360 
361  pf_map_fast_draw_terrain.start();
362  cell=cell_list;
363  for (i=0; i<t_visible_cells; i++, cell++)
364  {
365
366    cx=cell->x;
367    cy=cell->y;
368
369    if (cx<0 || cy<0 || cx>=width() || cy>=height())
370      i4_error("cell out of bounds");
371    else
372    {
373      g1_map_cell_class *map_cell=m+cx+cy*width();
374
375
376      r1_texture_handle han = g1_tile_man.get_texture(map_cell->type);
377   
378      if (han && han!=g1_tile_man.get_pink())
379      {
380
381        pf_map_fast_transform.start();
382
383        g1_draw_tri_struct ts;
384        vt[0]=v + cx + cy * mw_p1;         
385        vt[1]=vt[0]+1;
386        vt[2]=vt[1]+mw_p1;
387        vt[3]=vt[2]-1;
388
389        vt[0]->transform(t, cx, cy,     g1_render.scale_x,g1_render.scale_y);
390        vt[1]->transform(t, cx+1, cy,   g1_render.scale_x,g1_render.scale_y);
391        vt[2]->transform(t, cx+1, cy+1, g1_render.scale_x,g1_render.scale_y);
392        vt[3]->transform(t, cx, cy+1,   g1_render.scale_x,g1_render.scale_y);
393        pf_map_fast_transform.stop();
394
395
396
397        pf_map_fast_clip_code.start();
398        vt[0]->calc_clip_code();
399        vt[1]->calc_clip_code();
400        vt[2]->calc_clip_code();
401        vt[3]->calc_clip_code();     
402        pf_map_fast_clip_code.stop();
403
404
405        g1_stat_counter.set_current_counter(g1_statistics_counter_class::TERRAIN_POLYS);
406
407        pf_map_fast_pack_uv.start();
408        int uv_on=map_cell->get_rotation();
409        int uv_dir=map_cell->mirrored() ? 3 : 1;
410
411        float u[4]={0,1,1,0},v[4]={1,1,0,0};
412
413        terrain_verts[0].s = u[uv_on];
414        terrain_verts[0].t = v[uv_on];
415        uv_on=(uv_on+uv_dir)&3;
416
417        terrain_verts[1].s = u[uv_on];
418        terrain_verts[1].t = v[uv_on];
419        uv_on=(uv_on+uv_dir)&3;
420
421        terrain_verts[2].s = u[uv_on];
422        terrain_verts[2].t = v[uv_on];
423        pf_map_fast_pack_uv.stop();
424
425
426
427        pf_map_fast_draw_tri.start();
428
429
430        ts.v1 = vt[0];
431        ts.v2 = vt[1];
432        ts.v3 = vt[2];
433        ts.texture = han;
434        ts.texture_scale = 1;
435        ts.vx1 = cx;
436        ts.vy1 = cy;
437        ts.vx2 = cx+1;
438        ts.vy2 = cy;
439        ts.vx3 = cx+1;
440        ts.vy3 = cy+1;
441
442
443        g1_draw_tri(ts, t, map_cell->flags);
444        pf_map_fast_draw_tri.stop();
445
446
447
448        pf_map_fast_pack_uv.start();
449        uv_on=map_cell->get_rotation();
450        terrain_verts[0].s = u[uv_on];
451        terrain_verts[0].t = v[uv_on];
452
453        uv_on=(uv_on+uv_dir*2)&3;
454        terrain_verts[1].s = u[uv_on];
455        terrain_verts[1].t = v[uv_on];
456
457        uv_on=(uv_on+uv_dir)&3;
458        terrain_verts[2].s = u[uv_on];
459        terrain_verts[2].t = v[uv_on];
460        pf_map_fast_pack_uv.stop();
461
462
463        ts.v1 = vt[0];
464        ts.v2 = vt[2];
465        ts.v3 = vt[3];
466        ts.vx1 = cx;
467        ts.vy1 = cy;
468        ts.vx2 = cx+1;
469        ts.vy2 = cy+1;
470        ts.vx3 = cx;
471        ts.vy3 = cy+1;
472
473
474        pf_map_fast_draw_tri.start();
475
476
477
478        g1_draw_tri(ts, t, map_cell->flags);
479        pf_map_fast_draw_tri.stop();
480
481
482        if (post_cell_draw)
483          post_cell_draw(cx,cy, post_cell_draw_context);
484      }       
485
486
487    }
488  }
489  pf_map_fast_draw_terrain.stop();
490
491
492
493  cell=cell_list;
494
495  li_class *old_this=li_this;
496  pf_map_fast_draw_objects.start();
497  //draw the objects BACK TO FRONT
498  for (i=g1_num_objs_in_view-1;i>=0;i--)
499  {
500    g1_object_class *o=g1_global_id.checked_get(g1_objs_in_view[i]);
501    if (o)
502    {
503      li_this=o->vars;
504
505      if (o->world_transform!=0)
506      {
507        o->draw(context);
508        o->set_flag(g1_object_class::SCRATCH_BIT, 0);
509      }
510      else i4_warning("null transform");
511    }
512  }
513
514  if (context->draw_editor_stuff)
515  {
516    for (i=g1_num_objs_in_view-1;i>=0;i--)
517    {
518      g1_object_class *o=g1_global_id.checked_get(g1_objs_in_view[i]);
519      if (o)
520      {
521        li_this=o->vars;
522        o->editor_draw(context);
523      }
524    }
525  } 
526 
527  li_this=old_this;
528   
529  pf_map_fast_draw_objects.stop();
530
531  pf_map_fast_clear.start();
532  cell=cell_list;
533  for (i=0; i<t_visible_cells; i++, cell++)
534  {   
535    cx=cell->x;
536    cy=cell->y;
537
538    g1_map_cell_class *map_cell=m+cx+cy*width();
539
540    vt[0]=v + cx + cy * mw_p1;
541    vt[1]=vt[0]+1;
542    vt[2]=vt[1]+mw_p1;
543    vt[3]=vt[2]-1;
544
545
546    vt[0]->clear_calculations();
547    vt[1]->clear_calculations();
548    vt[2]->clear_calculations();
549    vt[3]->clear_calculations();       
550
551  }
552
553  pf_map_fast_clear.stop();
554}
555
556
557
558#endif
Note: See TracBrowser for help on using the repository browser.