source: golgotha/src/render/r1_api.cc

Last change on this file 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: 18.0 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 "r1_api.hh"
10#include "tmanage.hh"
11#include "r1_clip.hh"
12#include "image/context.hh"
13#include <string.h>
14
15r1_render_api_class     *r1_render_api_class_instance=0;
16
17r1_shading_type         r1_render_api_class::shade_mode=R1_SHADE_DISABLED;
18r1_alpha_type           r1_render_api_class::alpha_mode=R1_ALPHA_DISABLED;
19r1_write_mask_type      r1_render_api_class::write_mask=0;
20w32                     r1_render_api_class::const_color=0;
21r1_miplevel_t          *r1_render_api_class::last_node=0;
22r1_render_api_class    *r1_render_api_class::first;
23r1_filter_type          r1_render_api_class::filter_mode=R1_NO_FILTERING;
24i4_draw_context_class  *r1_render_api_class::context=0;
25i4_float                r1_render_api_class::r_tint_mul=0;
26i4_float                r1_render_api_class::g_tint_mul=0;
27i4_float                r1_render_api_class::b_tint_mul=0;
28i4_bool                 r1_render_api_class::color_tint_on=i4_F;
29r1_color_tint           r1_render_api_class::color_tint_list[r1_render_api_class::MAX_COLOR_TINTS];
30
31//start with 1, since 0 disables tinting
32sw8                     r1_render_api_class::num_color_tints = 1;                                                                   
33
34r1_color_tint_handle r1_render_api_class::register_color_tint(i4_float r, i4_float g, i4_float b)
35{
36  if (num_color_tints==MAX_COLOR_TINTS) return 0;
37
38  color_tint_list[num_color_tints].r = r;
39  color_tint_list[num_color_tints].g = g;
40  color_tint_list[num_color_tints].b = b;
41
42  num_color_tints++;
43
44  return num_color_tints-1;
45}
46
47
48void r1_render_api_class::put_image(i4_image_class *im,                                         
49                                    int _x, int _y,             // position on screen
50                                    int x1, int y1,           // area of image to copy
51                                    int x2, int y2)
52{
53  i4_rect_list_class *clip=&context->clip; 
54  i4_rect_list_class::area_iter cl;
55
56  for (cl = clip->list.begin(); cl != clip->list.end(); ++cl)
57  {
58    int lx1,ly1,lx2,ly2,x=_x,y=_y;
59
60    if (x1<0) { lx1=0; _x+=-x1; } else lx1=x1;
61    if (y1<0) { ly1=0; _y+=-y1; } else ly1=y1;
62    if (x2>=im->width())  lx2=im->width()-1;   else lx2=x2;
63    if (y2>=im->height()) ly2=im->height()-1;  else ly2=y2;
64 
65    if (!(lx1>lx2 || ly1>ly2))
66    {
67      if (x<cl->x1)
68      { lx1+=(cl->x1-x); x=cl->x1; }
69
70      if (y<cl->y1)
71      { ly1+=(cl->y1-y); y=cl->y1; }
72
73
74      if (x+lx2-lx1+1>cl->x2)
75        lx2=cl->x2-x+lx1;
76
77      if (y+ly2-ly1+1>cl->y2)
78        ly2=cl->y2-y+ly1;
79
80
81      if (!(lx1>lx2 || ly1>ly2))
82        copy_part(im, x,y, lx1,ly1,lx2,ly2);
83    }
84  }
85}
86
87void r1_render_api_class::set_color_tint(r1_color_tint_handle c)
88{
89  if (c==0)
90  {
91    r_tint_mul = 1.f;
92    g_tint_mul = 1.f;
93    b_tint_mul = 1.f;
94
95    color_tint_on = i4_F;
96        return;
97  }
98
99  color_tint_on = i4_T;
100
101  r_tint_mul = color_tint_list[c].r;
102  g_tint_mul = color_tint_list[c].g;
103  b_tint_mul = color_tint_list[c].b;   
104}
105
106
107r1_render_api_class *r1_create_api(i4_display_class *for_display, char *name)
108{
109  for (r1_render_api_class *r=r1_render_api_class::first; r; r=r->next)
110  {
111   
112    if ((!name || strcmp(r->name(), name)==0) && r->init(for_display))
113    {
114      r1_render_api_class_instance = r;
115      return r;
116    }
117  }
118
119  return 0;
120}
121
122void r1_destroy_api(r1_render_api_class *r)
123{
124  r->uninit();
125  if (r1_render_api_class_instance==r) r1_render_api_class_instance = 0;
126}
127
128i4_bool r1_render_api_class::init(i4_display_class *display)
129{
130  // this should clear out the states and set to a default
131  set_constant_color(0xffffffff);
132  set_constant_color(0);
133
134  set_shading_mode(R1_COLORED_SHADING);
135  set_shading_mode(R1_SHADE_DISABLED);
136
137  set_alpha_mode(R1_ALPHA_LINEAR);
138  set_alpha_mode(R1_ALPHA_DISABLED);
139
140  set_write_mode(0xffff);
141  set_write_mode(0);
142
143  set_filter_mode(R1_BILINEAR_FILTERING);
144  set_filter_mode(R1_NO_FILTERING);
145
146  set_z_range(0.001, 1.0);
147  return i4_T;
148}
149
150
151void r1_render_api_class::uninit()
152{
153  if (tmanager)
154  {
155    delete tmanager;
156    tmanager=0;
157  }
158}
159
160
161void r1_render_api_class::render_sprite(r1_vert *verts)
162{
163  render_poly(4,verts);
164}
165
166void r1_render_api_class::clear_area(int x1, int y1, int x2, int y2, w32 color, float z)
167{
168  w32 old_const_color=get_constant_color();
169  set_constant_color(color);
170
171  r1_shading_type old_shade_mode=get_shade_mode();
172  set_shading_mode(R1_CONSTANT_SHADING);
173
174  disable_texture();
175
176  r1_vert v[4];
177
178  float w = r1_ooz(z);
179
180  v[0].px=x1;     v[0].py=y1;      v[0].w=w;   v[0].v.z=z;
181  v[1].px=x1;     v[1].py=y2+1;    v[1].w=w;   v[1].v.z=z;
182  v[2].px=x2+1;   v[2].py=y2+1;    v[2].w=w;   v[2].v.z=z;
183  v[3].px=x2+1;   v[3].py=y1;      v[3].w=w;   v[3].v.z=z;
184 
185  render_poly(4, v);
186
187  set_shading_mode(old_shade_mode);
188  set_constant_color(old_const_color);
189}
190
191
192r1_vert tmp_render_poly_verts[128];
193
194// default method
195void r1_render_api_class::render_poly(int t_verts, r1_vert *verts, int *vertex_index)
196{
197  if (t_verts>128) return;
198
199  for (int i=0; i<t_verts; i++)
200    tmp_render_poly_verts[i] = verts[vertex_index[i]];
201 
202  render_poly(t_verts, tmp_render_poly_verts); 
203}
204
205void r1_render_api_class::render_poly(int t_verts, r1_vert *verts, w16 *vertex_index)
206
207  if (t_verts>128) return;
208
209  for (int i=0; i<t_verts; i++)
210    tmp_render_poly_verts[i] = verts[vertex_index[i]];
211
212  render_poly(t_verts, tmp_render_poly_verts);
213}
214
215i4_float r1_near_clip_z = 0.001;
216i4_float r1_far_clip_z  = 100;
217
218#define R1_NEXT(i,j) ( (((i)+1)==(j))?(0):((i)+1) )
219#define R1_PREV(i,j) ( ((i)==(0))?((j)-1):((i)-1) )
220
221r1_vert *r1_render_api_class::clip_poly(sw32 *initial_num_vertices,r1_vert *t_vertices,
222                                        w16 *indices,r1_vert *clip_buf_1,
223                                        r1_vert *clip_buf_2,
224                                        w8 flags)
225{
226
227  w32 ORCODE  = 0;
228  w32 ANDCODE = 0xffffffff;
229  w32 i,j,c0,c1;
230  w32 bitmask;
231  i4_float ooz,dx,dy,dz,ds,dt,dr,dg,db,da,t; 
232
233  r1_vert *vertices          = clip_buf_1;
234  sw32     num_vertices      = *initial_num_vertices;
235                             
236  r1_vert *clip_vertices     = clip_buf_2;
237  sw32     num_clip_vertices = 0;
238
239  r1_vert clip_point;       
240
241  if (flags & R1_CLIP_NO_CALC_OUTCODE)
242  {
243    for (i=0; i<num_vertices; i++)
244    {   
245      vertices[i] = t_vertices[indices[i]];     
246      ORCODE  |= vertices[i].outcode;
247      ANDCODE &= vertices[i].outcode;
248    }
249  }
250  else
251  {
252    for (i=0; i<num_vertices; i++)
253    {   
254      w8 outcode;
255      vertices[i] = t_vertices[indices[i]];
256      if (flags & R1_CLIP_ORTHO)
257        outcode = r1_calc_ortho_outcode(&vertices[i]);
258      else
259        outcode = r1_calc_outcode(&vertices[i]);
260      ORCODE  |= outcode;
261      ANDCODE &= outcode;   
262    }
263  }
264 
265  if (ANDCODE)
266  {
267    *initial_num_vertices = 0;
268    return 0;
269  }
270 
271  if (!ORCODE)
272  {
273    return vertices;
274  }
275 
276 
277  for (bitmask=32;bitmask;bitmask=bitmask>>1)
278  {
279    if ((bitmask&ORCODE)==0) continue;
280   
281    for (i=0;i<num_vertices;i++)
282    {                   
283     
284      j  = R1_NEXT(i,num_vertices);
285     
286      c0 = bitmask & vertices[i].outcode;
287      c1 = bitmask & vertices[j].outcode;
288     
289      //if c0 is not outside of this plane,
290      //add it
291      if (c0==0) {
292        clip_vertices[num_clip_vertices] = vertices[i];
293        num_clip_vertices++;
294      }
295     
296      //if they are on the same
297      //side, move to the next vert
298      if (c0==c1) continue;
299     
300      //otherwise, generate a clipped
301      //point
302     
303      dx = vertices[j].v.x - vertices[i].v.x;
304      dy = vertices[j].v.y - vertices[i].v.y;
305      dz = vertices[j].v.z - vertices[i].v.z;
306      ds = vertices[j].s - vertices[i].s;
307      dt = vertices[j].t - vertices[i].t;
308      dr = vertices[j].r - vertices[i].r;
309      dg = vertices[j].g - vertices[i].g;
310      db = vertices[j].b - vertices[i].b;
311      da = vertices[j].a - vertices[i].a;
312           
313      switch (bitmask | (flags & R1_CLIP_ORTHO)) {
314        case 1:
315          t = (-vertices[i].v.x + vertices[i].v.z) / ( dx - dz);                 
316          clip_point.v.y = vertices[i].v.y + (t * dy);
317          clip_point.v.z = vertices[i].v.z + (t * dz);
318         
319          clip_point.v.x = clip_point.v.z;
320          break;
321         
322        case 2:
323          t = ( vertices[i].v.x + vertices[i].v.z) / (-dx - dz);                 
324          clip_point.v.y = vertices[i].v.y + (t * dy);
325          clip_point.v.z = vertices[i].v.z + (t * dz);
326         
327          clip_point.v.x = -clip_point.v.z;
328          break;
329       
330        case 4:
331          t = (-vertices[i].v.y + vertices[i].v.z) / ( dy - dz);
332          clip_point.v.x = vertices[i].v.x + (t * dx);                 
333          clip_point.v.z = vertices[i].v.z + (t * dz);
334         
335          clip_point.v.y = clip_point.v.z;
336          break;
337       
338        case 8:
339          t = ( vertices[i].v.y + vertices[i].v.z) / (-dy - dz);
340          clip_point.v.x = vertices[i].v.x + (t * dx);                 
341          clip_point.v.z = vertices[i].v.z + (t * dz);
342         
343          clip_point.v.y = -clip_point.v.z;
344          break;
345         
346        case 16:
347          t = (r1_near_clip_z - vertices[i].v.z) / (dz);                               
348          clip_point.v.x = vertices[i].v.x + (t * dx);
349          clip_point.v.y = vertices[i].v.y + (t * dy);
350         
351          clip_point.v.z = r1_near_clip_z;
352          break;
353
354        case 32:
355          t = -(vertices[i].v.z - r1_far_clip_z) / (dz);                               
356          clip_point.v.x = vertices[i].v.x + (t * dx);
357          clip_point.v.y = vertices[i].v.y + (t * dy);
358         
359          clip_point.v.z = r1_far_clip_z;
360          break;
361         
362        case 1|128:
363          t = (1.0 - vertices[i].v.x) / dx;
364          clip_point.v.y = vertices[i].v.y + (t * dy);
365          clip_point.v.z = vertices[i].v.z + (t * dz);
366          clip_point.v.x = 1.0;
367          break;
368         
369        case 2|128:
370          t = (vertices[i].v.x + 1.0) / -dx;
371          clip_point.v.y = vertices[i].v.y + (t * dy);
372          clip_point.v.z = vertices[i].v.z + (t * dz);
373          clip_point.v.x = -1.0;
374          break;
375         
376        case 4|128:
377          t = (1.0 - vertices[i].v.y) / dy;
378          clip_point.v.x = vertices[i].v.x + (t * dx);                 
379          clip_point.v.z = vertices[i].v.z + (t * dz);
380          clip_point.v.y = 1.0;
381          break;
382         
383        case 8|128:
384          t = (vertices[i].v.y + 1.0) / -dy;
385          clip_point.v.x = vertices[i].v.x + (t * dx);                 
386          clip_point.v.z = vertices[i].v.z + (t * dz);
387          clip_point.v.y = -1.0;
388          break;
389      }
390     
391      clip_point.s = vertices[i].s + (t * ds);
392      clip_point.t = vertices[i].t + (t * dt);
393      clip_point.r = vertices[i].r + (t * dr);
394      clip_point.g = vertices[i].g + (t * dg);
395      clip_point.b = vertices[i].b + (t * db);
396      clip_point.a = vertices[i].a + (t * da);
397           
398      if (flags & R1_CLIP_ORTHO)
399        ORCODE |= r1_calc_ortho_outcode(&clip_point);
400      else     
401        ORCODE |= r1_calc_outcode(&clip_point);
402     
403      clip_vertices[num_clip_vertices] = clip_point;
404      num_clip_vertices++;           
405    }
406   
407    num_vertices      = num_clip_vertices;
408    num_clip_vertices = 0;
409
410    if (vertices==clip_buf_1)
411    {
412      vertices      = clip_buf_2;
413      clip_vertices = clip_buf_1;
414    }
415    else
416    {
417      vertices      = clip_buf_1;
418      clip_vertices = clip_buf_2;
419    }
420  }
421 
422  *initial_num_vertices = num_vertices;
423  return vertices;
424}
425
426r1_vert *r1_render_api_class::clip_poly(sw32 *initial_num_vertices,r1_vert *t_vertices,
427                                        w32 *indices,r1_vert *clip_buf_1,
428                                        r1_vert *clip_buf_2,
429                                        w8 flags)
430{
431
432  w32 ORCODE  = 0;
433  w32 ANDCODE = 0xffffffff;
434  w32 i,j,c0,c1;
435  w32 bitmask;
436  i4_float ooz,dx,dy,dz,ds,dt,dr,dg,db,da,t; 
437
438  r1_vert *vertices          = clip_buf_1;
439  sw32     num_vertices      = *initial_num_vertices;
440                             
441  r1_vert *clip_vertices     = clip_buf_2;
442  sw32     num_clip_vertices = 0;
443
444  r1_vert clip_point;       
445
446  if (flags & R1_CLIP_NO_CALC_OUTCODE)
447  {
448    for (i=0; i<num_vertices; i++)
449    {   
450      vertices[i] = t_vertices[indices[i]];     
451      ORCODE  |= vertices[i].outcode;
452      ANDCODE &= vertices[i].outcode;
453    }
454  }
455  else
456  {
457    for (i=0; i<num_vertices; i++)
458    {   
459      vertices[i] = t_vertices[indices[i]];
460      w8 outcode = r1_calc_outcode(&vertices[i]);   
461      ORCODE  |= outcode;
462      ANDCODE &= outcode;   
463    }
464  }
465 
466  if (ANDCODE)
467  {
468    *initial_num_vertices = 0;
469    return 0;
470  }
471 
472  if (!ORCODE)
473  {
474    return vertices;
475  }
476 
477  for (bitmask=32;bitmask;bitmask=bitmask>>1)
478  {
479    if ((bitmask&ORCODE)==0) continue;
480   
481    for (i=0;i<num_vertices;i++)
482    {                   
483     
484      j  = R1_NEXT(i,num_vertices);
485     
486      c0 = bitmask & vertices[i].outcode;
487      c1 = bitmask & vertices[j].outcode;
488     
489      //if c0 is not outside of this plane,
490      //add it
491      if (c0==0) {
492        clip_vertices[num_clip_vertices] = vertices[i];
493        num_clip_vertices++;
494      }
495     
496      //if they are on the same
497      //side, move to the next vert
498      if (c0==c1) continue;
499     
500      //otherwise, generate a clipped
501      //point
502     
503      dx = vertices[j].v.x - vertices[i].v.x;
504      dy = vertices[j].v.y - vertices[i].v.y;
505      dz = vertices[j].v.z - vertices[i].v.z;
506      ds = vertices[j].s - vertices[i].s;
507      dt = vertices[j].t - vertices[i].t;
508      dr = vertices[j].r - vertices[i].r;
509      dg = vertices[j].g - vertices[i].g;
510      db = vertices[j].b - vertices[i].b;
511      da = vertices[j].a - vertices[i].a;
512           
513      switch (bitmask | (flags&R1_CLIP_ORTHO)) {
514        case 1: 
515          t = (-vertices[i].v.x + vertices[i].v.z) / ( dx - dz);                 
516          clip_point.v.y = vertices[i].v.y + (t * dy);
517          clip_point.v.z = vertices[i].v.z + (t * dz);
518         
519          clip_point.v.x = clip_point.v.z;
520          break;
521         
522        case 2:
523          t = ( vertices[i].v.x + vertices[i].v.z) / (-dx - dz);                 
524          clip_point.v.y = vertices[i].v.y + (t * dy);
525          clip_point.v.z = vertices[i].v.z + (t * dz);
526         
527          clip_point.v.x = -clip_point.v.z;
528          break;
529       
530        case 4: 
531          t = (-vertices[i].v.y + vertices[i].v.z) / ( dy - dz);
532          clip_point.v.x = vertices[i].v.x + (t * dx);                 
533          clip_point.v.z = vertices[i].v.z + (t * dz);
534         
535          clip_point.v.y = clip_point.v.z;
536          break;
537       
538        case 8:
539          t = ( vertices[i].v.y + vertices[i].v.z) / (-dy - dz);
540          clip_point.v.x = vertices[i].v.x + (t * dx);                 
541          clip_point.v.z = vertices[i].v.z + (t * dz);
542         
543          clip_point.v.y = -clip_point.v.z;
544          break;
545         
546        case 16:
547          t = (r1_near_clip_z - vertices[i].v.z) / (dz);                               
548          clip_point.v.x = vertices[i].v.x + (t * dx);
549          clip_point.v.y = vertices[i].v.y + (t * dy);
550         
551          clip_point.v.z = r1_near_clip_z;
552          break;           
553       
554        case 32:
555          t = -(vertices[i].v.z - r1_far_clip_z) / (dz);                               
556          clip_point.v.x = vertices[i].v.x + (t * dx);
557          clip_point.v.y = vertices[i].v.y + (t * dy);
558                 
559          clip_point.v.z = r1_far_clip_z;
560          break;
561
562        case 1|128:
563          t = (1.0 - vertices[i].v.x) / dx;
564          clip_point.v.y = vertices[i].v.y + (t * dy);
565          clip_point.v.z = vertices[i].v.z + (t * dz);
566          clip_point.v.x = 1.0;
567          break;
568         
569        case 2|128:
570          t = (vertices[i].v.x + 1.0) / -dx;
571          clip_point.v.y = vertices[i].v.y + (t * dy);
572          clip_point.v.z = vertices[i].v.z + (t * dz);
573          clip_point.v.x = -1.0;
574          break;
575         
576        case 4|128:
577          t = (1.0 - vertices[i].v.y) / dy;
578          clip_point.v.x = vertices[i].v.x + (t * dx);                 
579          clip_point.v.z = vertices[i].v.z + (t * dz);
580          clip_point.v.y = 1.0;
581          break;
582         
583        case 8|128:
584          t = (vertices[i].v.y + 1.0) / -dy;
585          clip_point.v.x = vertices[i].v.x + (t * dx);                 
586          clip_point.v.z = vertices[i].v.z + (t * dz);
587          clip_point.v.y = -1.0;
588          break;
589      }
590     
591      clip_point.s = vertices[i].s + (t * ds);
592      clip_point.t = vertices[i].t + (t * dt);
593      clip_point.r = vertices[i].r + (t * dr);
594      clip_point.g = vertices[i].g + (t * dg);
595      clip_point.b = vertices[i].b + (t * db);
596      clip_point.a = vertices[i].a + (t * da);
597           
598      if (flags & R1_CLIP_ORTHO)
599        ORCODE |= r1_calc_ortho_outcode(&clip_point);
600      else
601        ORCODE |= r1_calc_outcode(&clip_point);
602     
603      clip_vertices[num_clip_vertices] = clip_point;
604      num_clip_vertices++;           
605    }
606   
607    num_vertices      = num_clip_vertices;
608    num_clip_vertices = 0;
609
610    if (vertices==clip_buf_1)
611    {
612      vertices      = clip_buf_2;
613      clip_vertices = clip_buf_1;
614    }
615    else
616    {
617      vertices      = clip_buf_1;
618      clip_vertices = clip_buf_2;
619    }
620  }
621 
622  *initial_num_vertices = num_vertices;
623  return vertices;
624}
625
626
Note: See TracBrowser for help on using the repository browser.