source: golgotha/src/render/software/rasterize_perspective.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: 13.1 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 "software/r1_software.hh"
10#include "software/r1_software_globals.hh"
11#include "software/span_buffer.hh"
12#include "software/inline_fpu.hh"
13#include "software/mappers.hh"
14
15//all calls to qftoi() here assume it will truncate, so be sure that start_trunc() gets
16//called before these functions execute
17
18//straight rasterization routines 1st
19//span rasterization at the bottom of the file
20
21void tri_draw_perspective_lit(tri_edge &top_to_middle,tri_edge &top_to_bottom, tri_edge &mid_to_bottom,
22                               sw32 start_y, i4_bool edge_comp)
23{
24  sw32 cur_y = start_y;
25 
26  w16 *screen_line;
27 
28  screen_line = r1_software_render_buffer_ptr + cur_y*r1_software_render_buffer_wpl;
29 
30  tri_edge *left;
31  tri_edge *right;
32  tri_edge *last_left=0;
33 
34  perspective_span cps; //(cur_perspective_span)
35 
36  //rasterize top to middle / top to bottom
37  float cur_l;
38  float oozystep,sozystep,tozystep,lystep;
39
40  if (top_to_middle.dy)
41  {   
42    if (edge_comp)
43    {     
44      left  = &top_to_bottom;
45      right = &top_to_middle;     
46    }
47    else
48    {     
49      left  = &top_to_middle;
50      right = &top_to_bottom;
51    }
52
53    last_left = left;
54   
55    sw32 lx,rx;
56
57    lx = (left->px  + 0xFFFF) >> 16;
58    rx = (right->px + 0xFFFF) >> 16;
59       
60    cps.ooz = cur_grads.oozat00 + ((float)cur_y*cur_grads.doozdy) + ((float)lx * cur_grads.doozdx);
61    cps.soz = cur_grads.sozat00 + ((float)cur_y*cur_grads.dsozdy) + ((float)lx * cur_grads.dsozdx);
62    cps.toz = cur_grads.tozat00 + ((float)cur_y*cur_grads.dtozdy) + ((float)lx * cur_grads.dtozdx);
63    cur_l   = cur_grads.lat00   + ((float)cur_y*cur_grads.dldy)   + ((float)lx * cur_grads.dldx);
64
65    oozystep = cur_grads.doozdy + cur_grads.doozdx * left->dxdy;
66    sozystep = cur_grads.dsozdy + cur_grads.dsozdx * left->dxdy;
67    tozystep = cur_grads.dtozdy + cur_grads.dtozdx * left->dxdy;
68    lystep   = cur_grads.dldy   + cur_grads.dldx   * left->dxdy;
69       
70    while (top_to_middle.dy)
71    {     
72      lx = (left->px  + 0xFFFF) >> 16;
73      rx = (right->px + 0xFFFF) >> 16;
74   
75      sw32 width = rx - lx;
76      if (width>0)
77      {
78        cps.l = qftoi(cur_l);
79        cur_scanline_texture_func(screen_line,(lx<<1),&cps,width);       
80      }
81     
82      //advance y down
83      cur_y++;
84
85      cps.ooz += oozystep;
86      cps.soz += sozystep;
87      cps.toz += tozystep;
88      cur_l   += lystep;
89
90      top_to_middle.px  += top_to_middle.dxdy_fixed;
91      top_to_bottom.px  += top_to_bottom.dxdy_fixed;
92     
93      top_to_middle.dy--;
94      top_to_bottom.dy--;
95           
96      screen_line += r1_software_render_buffer_wpl;     
97    }   
98  }
99 
100  if (mid_to_bottom.dy)
101  {
102    if (edge_comp)
103    {
104      left  = &top_to_bottom;
105      right = &mid_to_bottom;
106    }
107    else
108    {
109      left  = &mid_to_bottom;
110      right = &top_to_bottom;
111    }
112
113    sw32 lx,rx;
114
115    lx = (left->px  + 0xFFFF) >> 16;
116    rx = (right->px + 0xFFFF) >> 16;
117
118    if (left != last_left)
119    {
120      //switched edges, recalc these values
121      cps.ooz = cur_grads.oozat00 + ((float)cur_y*cur_grads.doozdy) + ((float)lx * cur_grads.doozdx);
122      cps.soz = cur_grads.sozat00 + ((float)cur_y*cur_grads.dsozdy) + ((float)lx * cur_grads.dsozdx);
123      cps.toz = cur_grads.tozat00 + ((float)cur_y*cur_grads.dtozdy) + ((float)lx * cur_grads.dtozdx);
124      cur_l   = cur_grads.lat00   + ((float)cur_y*cur_grads.dldy)   + ((float)lx * cur_grads.dldx);
125
126      oozystep = cur_grads.doozdy + cur_grads.doozdx * left->dxdy;
127      sozystep = cur_grads.dsozdy + cur_grads.dsozdx * left->dxdy;
128      tozystep = cur_grads.dtozdy + cur_grads.dtozdx * left->dxdy;
129      lystep   = cur_grads.dldy   + cur_grads.dldx   * left->dxdy;
130    }   
131   
132    while (mid_to_bottom.dy)
133    {     
134      lx = (left->px  + 0xFFFF) >> 16;
135      rx = (right->px + 0xFFFF) >> 16;
136   
137      sw32 width = rx - lx;
138      if (width>0)
139      {
140        cps.l = qftoi(cur_l);
141        cur_scanline_texture_func(screen_line,(lx<<1),&cps,width);       
142      }
143     
144      //advance y down
145      cur_y++;
146
147      cps.ooz += oozystep;
148      cps.soz += sozystep;
149      cps.toz += tozystep;
150      cur_l   += lystep;
151
152      top_to_bottom.px  += top_to_bottom.dxdy_fixed;
153      mid_to_bottom.px  += mid_to_bottom.dxdy_fixed;
154     
155      top_to_bottom.dy--;
156      mid_to_bottom.dy--;
157                 
158      screen_line += r1_software_render_buffer_wpl;
159    }
160  }
161}
162
163void tri_draw_perspective_unlit(tri_edge &top_to_middle,tri_edge &top_to_bottom, tri_edge &mid_to_bottom,
164                                 sw32 start_y, i4_bool edge_comp)
165{
166  sw32 cur_y = start_y;
167 
168  w16 *screen_line;
169 
170  screen_line = r1_software_render_buffer_ptr + cur_y*r1_software_render_buffer_wpl;
171 
172  tri_edge *left;
173  tri_edge *right;
174  tri_edge *last_left=0;
175 
176  perspective_span cps; //(cur_perspective_span)
177 
178  //rasterize top to middle / top to bottom 
179  float oozystep,sozystep,tozystep,lystep;
180
181  if (top_to_middle.dy)
182  {   
183    if (edge_comp)
184    {     
185      left  = &top_to_bottom;
186      right = &top_to_middle;     
187    }
188    else
189    {     
190      left  = &top_to_middle;
191      right = &top_to_bottom;
192    }
193
194    last_left = left;
195   
196    sw32 lx,rx;
197
198    lx = (left->px  + 0xFFFF) >> 16;
199    rx = (right->px + 0xFFFF) >> 16;
200       
201    cps.ooz = cur_grads.oozat00 + ((float)cur_y*cur_grads.doozdy) + ((float)lx * cur_grads.doozdx);
202    cps.soz = cur_grads.sozat00 + ((float)cur_y*cur_grads.dsozdy) + ((float)lx * cur_grads.dsozdx);
203    cps.toz = cur_grads.tozat00 + ((float)cur_y*cur_grads.dtozdy) + ((float)lx * cur_grads.dtozdx);   
204
205    oozystep = cur_grads.doozdy + cur_grads.doozdx * left->dxdy;
206    sozystep = cur_grads.dsozdy + cur_grads.dsozdx * left->dxdy;
207    tozystep = cur_grads.dtozdy + cur_grads.dtozdx * left->dxdy;
208       
209    while (top_to_middle.dy)
210    {     
211      lx = (left->px  + 0xFFFF) >> 16;
212      rx = (right->px + 0xFFFF) >> 16;
213   
214      sw32 width = rx - lx;
215      if (width>0)
216      {       
217        cur_scanline_texture_func(screen_line,(lx<<1),&cps,width);       
218      }
219     
220      //advance y down
221      cur_y++;
222
223      cps.ooz += oozystep;
224      cps.soz += sozystep;
225      cps.toz += tozystep;     
226
227      top_to_middle.px  += top_to_middle.dxdy_fixed;
228      top_to_bottom.px  += top_to_bottom.dxdy_fixed;
229     
230      top_to_middle.dy--;
231      top_to_bottom.dy--;
232           
233      screen_line += r1_software_render_buffer_wpl;
234    }   
235  }
236 
237  if (mid_to_bottom.dy)
238  {
239    if (edge_comp)
240    {
241      left  = &top_to_bottom;
242      right = &mid_to_bottom;
243    }
244    else
245    {
246      left  = &mid_to_bottom;
247      right = &top_to_bottom;
248    }
249
250    sw32 lx,rx;
251
252    lx = (left->px  + 0xFFFF) >> 16;
253    rx = (right->px + 0xFFFF) >> 16;
254
255    if (left != last_left)
256    {
257      //switched edges, recalc these values
258      cps.ooz = cur_grads.oozat00 + ((float)cur_y*cur_grads.doozdy) + ((float)lx * cur_grads.doozdx);
259      cps.soz = cur_grads.sozat00 + ((float)cur_y*cur_grads.dsozdy) + ((float)lx * cur_grads.dsozdx);
260      cps.toz = cur_grads.tozat00 + ((float)cur_y*cur_grads.dtozdy) + ((float)lx * cur_grads.dtozdx);     
261
262      oozystep = cur_grads.doozdy + cur_grads.doozdx * left->dxdy;
263      sozystep = cur_grads.dsozdy + cur_grads.dsozdx * left->dxdy;
264      tozystep = cur_grads.dtozdy + cur_grads.dtozdx * left->dxdy;
265    }   
266   
267    while (mid_to_bottom.dy)
268    {     
269      lx = (left->px  + 0xFFFF) >> 16;
270      rx = (right->px + 0xFFFF) >> 16;
271   
272      sw32 width = rx - lx;
273      if (width>0)
274      {       
275        cur_scanline_texture_func(screen_line,(lx<<1),&cps,width);       
276      }
277     
278      //advance y down
279      cur_y++;
280
281      cps.ooz += oozystep;
282      cps.soz += sozystep;
283      cps.toz += tozystep;     
284
285      top_to_bottom.px  += top_to_bottom.dxdy_fixed;
286      mid_to_bottom.px  += mid_to_bottom.dxdy_fixed;
287     
288      top_to_bottom.dy--;
289      mid_to_bottom.dy--;
290                 
291      screen_line += r1_software_render_buffer_wpl;
292    }
293  }
294}
295
296void span_draw_perspective_lit(span_tri_info *tri)
297{     
298  r1_software_class_instance.set_color_tint(tri->color_tint);
299
300  //setup some of the global variables
301  r1_software_texture_ptr    = tri->texture;
302  r1_software_twidth_log2    = tri->twidth_log2;
303  r1_software_texture_width  = tri->texture_width;
304  r1_software_texture_height = tri->texture_height;
305  cur_grads                  = tri->grads;
306   
307  s_mask = ((r1_software_texture_width -1)<<16) | 0xFFFF;
308  t_mask = ((r1_software_texture_height-1)<<16) | 0xFFFF;
309 
310  //dont forget the light
311  dldx_fixed = qftoi(tri->grads.dldx);
312
313  span_entry *s = &global_span_list[tri->span_list_head];
314
315  perspective_span left; 
316  while (s!=global_span_list)
317  {   
318    left.ooz = s->s.ooz;
319
320#ifndef USE_ASM
321    float fx = s->x;
322    float fy = s->y;
323   
324    left.toz = cur_grads.tozat00 + (fx * cur_grads.dtozdx) + (fy * cur_grads.dtozdy);
325    left.soz = cur_grads.sozat00 + (fx * cur_grads.dsozdx) + (fy * cur_grads.dsozdy);
326    left.l   = qftoi(cur_grads.lat00 + (fx * cur_grads.dldx) + (fy * cur_grads.dldy));
327#else
328    _asm
329    {
330      mov edi,dword ptr [s]
331     
332      fild dword ptr [edi]span_entry.s.x
333      fild dword ptr [edi]span_entry.s.y
334
335      fld dword ptr [cur_grads]tri_gradients.dtdx
336      fld dword ptr [cur_grads]tri_gradients.dtdy
337
338      //dtdy  dtdx  y   x
339      fmul st(0),st(2)
340      fxch st(1)
341
342      //dtdx  dtdy*y  y  x
343
344      fmul st(0),st(3)
345      fxch st(1)
346
347      //dtdy*y  dtdx*x  y  x
348
349      fld dword ptr [cur_grads]tri_gradients.dsdx
350      fld dword ptr [cur_grads]tri_gradients.dsdy
351
352      //dsdy  dsdx  dtdy*y  dtdx*x  y  x
353
354      fmul st(0),st(4)
355      fxch st(1)
356
357      //dsdx  dsdy*y  dtdy*y  dtdx*x  y  x
358
359      fmul st(0),st(5)
360      fxch st(1)
361
362      //dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
363      fld dword ptr [cur_grads]tri_gradients.dldx
364      fld dword ptr [cur_grads]tri_gradients.dldy
365
366      //dldy  dldx  dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
367
368      fmul st(0),st(6)
369      fxch st(1)
370
371      //dldx  dldy*y  dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
372
373      fmul st(0),st(7)
374      fxch st(4)
375     
376      //dtdy*y  dldx*x  dsdy*y  dsdx*x  dldy*y  dtdx*x  y  x
377     
378      fadd dword ptr [cur_grads]tri_gradients.tat00
379      fxch st(2)
380
381      //dsdy*y  dldx*x  dtdy*y+tat00  dsdx*x  dldy*y  dtdx*x  y  x
382
383      fadd dword ptr [cur_grads]tri_gradients.sat00
384      fxch st(4)
385
386      //dldy*y  dldx*x  dtdy*y+tat00  dsdx*x  dsdy*y+sat00  dtdx*x  y  x
387
388      fadd dword ptr [cur_grads]tri_gradients.lat00
389      fxch st(2)
390
391      //dtdy*y+tat00  dldx*x  dldy*y+lat00  dsdx*x  dsdy*y+sat00  dtdx*x  y  x
392      faddp st(5),st(0)
393
394      //dldx*x  dldy*y+lat00  dsdx*x  dsdy*y+sat00  dtdx*x+dtdy*y+tat00  y  x
395      fxch st(3)
396
397      //dsdy*y+sat00  dldy*y+lat00  dsdx*x  dldx*x  dtdx*x+dtdy*y+tat00  y  x
398      faddp st(2),st(0)
399
400      //dldy*y+lat00  dsdx*x+dsdy*y+sat00  dldx*x  dtdx*x+dtdy*y+tat00  y  x
401      faddp st(2),st(0)
402
403      //dsdx*x+dsdy*y+sat00  dldx*x+dldy*y+lat00  dtdx*x+dtdy*y+tat00  y  x
404      fxch st(3)
405     
406      //y  dldx*x+dldy*y+lat00  dtdx*x+dtdy*y+tat00  dsdx*x+dsdy*y+sat00  x
407      fstp st(0)
408      fxch st(3)
409     
410      //x  dtdx*x+dtdy*y+tat00  dsdx*x+dsdy*y+sat00  dldx*x+dldy*y+lat00
411      fstp st(0)
412
413      fstp dword ptr [left]perspective_span.toz
414      fstp dword ptr [left]perspective_span.soz
415      fistp dword ptr [left]perspective_span.l
416    }
417#endif
418
419    cur_scanline_texture_func(s->s.scanline_ptr,(s->s.x<<1),&left,s->s.width);   
420    s = &global_span_list[s->s.next_tri_span];
421  }
422}
423
424void span_draw_perspective_unlit(span_tri_info *tri)
425{     
426  //setup some of the global variables
427  r1_software_texture_ptr    = tri->texture;
428  r1_software_twidth_log2    = tri->twidth_log2;
429  r1_software_texture_width  = tri->texture_width;
430  r1_software_texture_height = tri->texture_height;
431  cur_grads                  = tri->grads;
432
433  span_entry *s = &global_span_list[tri->span_list_head];
434
435  s_mask = ((r1_software_texture_width -1)<<16) | 0xFFFF;
436  t_mask = ((r1_software_texture_height-1)<<16) | 0xFFFF;
437
438  perspective_span left; 
439  while (s!=global_span_list)
440  {   
441    float fx = s->s.x;
442    float fy = s->s.y;
443   
444    left.ooz = s->s.ooz;
445    left.toz = tri->grads.tozat00 + (fx * tri->grads.dtozdx) + (fy * tri->grads.dtozdy);
446    left.soz = tri->grads.sozat00 + (fx * tri->grads.dsozdx) + (fy * tri->grads.dsozdy);
447                                     
448    cur_scanline_texture_func(s->s.scanline_ptr,(s->s.x<<1),&left,s->s.width);   
449    s = &global_span_list[s->s.next_tri_span];
450  }
451}
Note: See TracBrowser for help on using the repository browser.