source: golgotha/src/test/ray_tracer/r1_softz.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 15 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: 7.4 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 "r1_win.hh"
11#include "image/image.hh"
12#include "palette/pal.hh"
13#include "threads/threads.hh"
14#include "tmanage.hh"
15#include "time/time.hh"
16
17// this lock prevents 2 threads from drawing at the same time
18static i4_critical_section_class softz_lock;
19static int defer_draws=0;
20
21static i4_pixel_format softz_pixel_fmt;
22class r1_softz_window;
23static r1_softz_window *cur_win=0;
24
25class r1_softz_window : public r1_render_window_class
26{
27public:
28  i4_image_class *im;
29  float *zbuffer;
30  i4_draw_context_class ctext;
31  volatile int rendering;
32 
33  r1_softz_window(int w, int h, r1_expand_type type);
34  void clear_z(int x1, int y1, int x2, int y2, float z)
35  {
36    float *s=zbuffer + y1*width()+x1;
37    int t=(x2-x1+1);
38    for (int y=y1; y<=y2; y++)
39    {
40      for (int i=0; i<t; i++)
41        s[i]=z;
42      s+=width();
43    }
44  }
45
46  void draw(i4_draw_context_class &context)
47  {
48    if (!rendering)
49      im->put_image(local_image, 0,0, context);
50    r1_render_window_class::draw(context);
51   
52  }
53
54  virtual void begin_render()
55  {
56    softz_lock.lock();
57    rendering=1;
58    cur_win=this;
59    if (cur_win->width()!=cur_win->im->width() ||
60        cur_win->height()!=cur_win->im->height())
61      i4_error("image wrong size");
62       
63       
64  }
65
66
67  virtual void end_render()
68  {
69    cur_win=0;
70    rendering=0;
71    softz_lock.unlock();
72  }
73
74  char *name() { return "softz_window"; }
75
76  virtual void private_resize(w16 new_width, w16 new_height)
77  {
78    r1_render_window_class::private_resize(new_width, new_height);
79
80    delete im;
81    i4_free(zbuffer);
82    zbuffer=(float *)i4_malloc(new_width* new_height*sizeof(float), ""); 
83    im=i4_create_image(new_width, new_height, i4_pal_man.register_pal(&softz_pixel_fmt));
84  }
85
86  ~r1_softz_window()
87  {
88    while (rendering)
89    {
90      i4_warning("waiting on render to finish");
91      i4_sleep(1);
92    }
93
94
95    delete im;
96    i4_free(zbuffer);
97  }
98};
99
100
101
102class r1_softz_tman : public r1_texture_manager_class
103
104public:
105  r1_softz_tman(const i4_pal *pal) : r1_texture_manager_class(pal) {}
106
107  virtual void init() {}
108  virtual void uninit() {}
109
110  virtual void next_frame() {}
111
112  virtual void reset() {}
113
114  virtual void toggle_texture_loading() {}
115 
116  virtual r1_miplevel_t *get_texture(r1_texture_handle handle,
117                                     w32 frame_counter,
118                                     sw32 desired_width,
119                                     sw32 &w, sw32 &h)
120  {
121    return 0;
122  }
123
124  virtual i4_bool valid_handle(r1_texture_handle handle)
125  {
126    return i4_F;
127  }
128
129public:
130  virtual i4_bool immediate_mip_load(r1_mip_load_info *load_info) { return i4_T; }
131
132  virtual i4_bool async_mip_load(r1_mip_load_info *load_info) { return i4_T; }
133
134  virtual void free_mip(r1_vram_handle_type vram_handle) {}
135};
136
137
138class r1_softz_api : public r1_render_api_class
139{
140
141public:
142  char *name() { return "Software Z Buffer"; }
143
144  virtual void use_texture(r1_texture_handle material_ref,
145                           sw32 desired_width,
146                           w32 frame)
147  {}
148
149  virtual void disable_texture() {}
150  virtual void set_z_range(float near_z, float far_z) {}
151
152  virtual void render_poly(int t_verts, r1_vert *verts)
153  {
154    render_lines(t_verts-1, verts);
155    r1_vert l[2];
156    l[0]=verts[0];
157    l[1]=verts[t_verts-1];
158    render_lines(1, l);
159  }
160
161  r1_softz_api()
162  {
163    softz_pixel_fmt.default_format();
164    softz_pixel_fmt.alpha_mask=0;
165    softz_pixel_fmt.calc_shift();
166  }
167
168  i4_bool init(i4_display_class *display)
169  {
170    tmanager=new r1_softz_tman(display->get_palette());
171    return i4_T;
172  }
173
174 
175  void uninit()
176  {
177    delete tmanager;
178  }
179
180  virtual void render_pixel(r1_vert *pixel)
181  {
182    int iw=cur_win->width();
183    float *zbuffer=cur_win->zbuffer;
184    int off=(int)pixel->px + ((int)pixel->py)*iw;
185
186    if (write_mask & R1_COMPARE_W)
187      if (zbuffer[off]<=pixel->v.z)
188        return ;
189     
190
191    w32 *im_data=(w32 *)cur_win->im->data;
192
193    if (write_mask & R1_WRITE_COLOR)
194    {
195      int r=(int)(pixel->r*255.0),
196          g=(int)(pixel->g*255.0),
197          b=(int)(pixel->b*255.0);
198       
199      w32 c=(r<<16)|(g<<8)|b;
200      im_data[off]=c;
201    }
202
203    if (write_mask & R1_WRITE_W)   
204      zbuffer[off]=pixel->v.z;
205
206  }
207
208  virtual void render_lines(int t_lines, r1_vert *verts)
209  {
210    w32 *im_data=(w32 *)cur_win->im->data;
211    int iw=cur_win->im->width();
212    float *zbuffer=cur_win->zbuffer;
213
214    for (int i=0; i<t_lines; i++)
215    {
216      float x=verts[i].px, y=verts[i].py, z=verts[i].v.z;
217      float xd=(int)fabs(verts[i+1].px-x), yd=(int)fabs(verts[i+1].py-y);
218      int steps = xd>yd ? xd+1 : yd+1;
219      float r=verts[i].r, g=verts[i].g, b=verts[i].b;
220
221      float rs=(verts[i+1].r-r)/(float)steps;
222      float gs=(verts[i+1].g-g)/(float)steps;
223      float bs=(verts[i+1].b-b)/(float)steps;
224      float xs=(verts[i+1].px-x)/(float)steps;
225      float ys=(verts[i+1].py-y)/(float)steps;
226      float zs=(verts[i+1].v.z-z)/(float)steps;
227
228      for (int j=0; j<steps; j++)
229      {
230        int off=(int)x + ((int)y)*iw;
231
232        if ((write_mask & R1_COMPARE_W)==0 || zbuffer[off]>z)
233        {
234
235          if (write_mask & R1_WRITE_COLOR)
236          {
237            int ir=(int)(r*255.0), ig=(int)(g*255.0), ib=(int)(b*255.0);
238            w32 c=(ir<<16)|(ig<<8)|ib;
239            im_data[off]=c;
240
241            r+=rs;
242            g+=gs;
243            b+=bs;
244          }
245       
246          if (write_mask & R1_WRITE_W)
247            zbuffer[off]=z;     
248        }
249
250        x+=xs;
251        y+=ys;
252        z+=zs;         
253   
254      }     
255    }
256  }
257
258  virtual i4_image_class *create_compatible_image(w16 w, w16 h)
259  {
260    return i4_create_image(w,h, i4_pal_man.register_pal(&softz_pixel_fmt));
261  }
262
263  virtual void clear_area(int x1, int y1, int x2, int y2, w32 color, float z)
264  {
265    if (write_mask & R1_WRITE_COLOR)
266      cur_win->im->bar(x1,y1,x2,y2, color, cur_win->ctext);
267   
268    if (write_mask & R1_WRITE_W)
269      cur_win->clear_z(x1,y1,x2,y2, z);
270  }
271
272
273
274  virtual r1_render_window_class *create_render_window(int visable_w, int visable_h,
275                                                       r1_expand_type type)
276  {
277    return new r1_softz_window(visable_w, visable_h, type);
278  }
279
280  virtual void copy_part(i4_image_class *im,                                         
281                         int x, int y,             // position on screen
282                         int x1, int y1,           // area of image to copy
283                         int x2, int y2) {}
284};
285
286static r1_softz_api softz;
287
288
289
290r1_softz_window::r1_softz_window(int w, int h, r1_expand_type type)
291  : r1_render_window_class(w,h, type, &softz),
292    ctext(0,0,w-1,h-1)
293{
294  zbuffer=(float *)i4_malloc(w*h*sizeof(float), "");
295  im=i4_create_image(w,h, i4_pal_man.register_pal(&softz_pixel_fmt));
296  rendering=0;
297}
298
Note: See TracBrowser for help on using the repository browser.