source: golgotha/src/test/ray_tracer/old_code @ 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: 4.9 KB
Line 
1  i4_image_class *im;
2  float *z_buffer;
3  i4_transform_class t;
4  int iw,ih;
5  i4_3d_vector light;
6  int mouse_x, mouse_y;
7  float theta;
8 
9  float get_z(int x, int y) { return z_buffer[x+y*iw]; }
10  void set_z(int x, int y, float z)
11  {
12    z_buffer[ x + y*iw ]=z;
13  }
14
15  void clear_z()
16  {
17    for (int i=0; i<iw*ih; i++)
18      z_buffer[i]=100000;
19  }
20
21  void render()
22  {
23    srand(0);
24    i4_draw_context_class context(0,0, im->width()-1, im->height()-1);
25   
26    i4_3d_vector circles[3]={i4_3d_vector(0,0,0), i4_3d_vector(0.5,1,0), i4_3d_vector(-2,-2,4)};
27
28    im->clear(0x4f0000, context);
29    clear_z();
30
31    float sx=width()/2, sy=height()/2;
32    float cx=sx,cy=sy;
33   
34
35    for (int j=0; j<3; j++)   
36    {
37      for (int i=0; i<50000; i++)
38      {   
39        float x=frand(),
40              y=frand();
41        float z=frand();
42
43        i4_3d_vector p(x,y,z);
44        p.normalize();
45
46
47        float c1=-p.dot(light);
48        i4_3d_vector reflect=i4_3d_vector(light.x + 2*p.x*c1,
49                                          light.y + 2*p.y*c1,
50                                          light.z + 2*p.z*c1);
51                                         
52
53
54        float light_v=-light.dot(p)*0.7;
55
56        i4_3d_vector pixel_pos(circles[j].x+p.x,circles[j].y+p.y, circles[j].z+p.z);
57        i4_3d_vector t_p;
58        t.transform(pixel_pos, t_p);
59
60       
61        i4_3d_vector view_dir=t_p;
62        view_dir.normalize();
63        float view_dot_r=-view_dir.dot(reflect);
64        if (view_dot_r>=0)
65        {
66          light_v += pow(view_dot_r, 0.4)*0.2;
67        }
68   
69
70        if (light_v<0)
71          light_v=0;
72        if (light_v>1)
73          light_v=1;
74
75       
76        float ooz=1.0/t_p.z;
77
78        float px=t_p.x * ooz * sx;
79        float py=t_p.y * ooz * sy;
80
81        int ix=(int)(px+cx), iy=(int)(py+cy);
82        if (ix>=0 && iy>=0 && ix<w && iy<h)
83        {
84          if (t_p.z<get_z(ix,iy))
85          {
86            im->put_pixel(ix, iy, (int)(light_v*255.0));
87            set_z(ix,iy, t_p.z);
88          }
89        }
90
91      }
92    }
93
94  }
95
96  void calc_transform()
97  {
98    t.identity();
99    t.mult_translate(0,0,8);
100    t.mult_rotate_x(theta);
101    t.mult_rotate_y(theta);
102  }
103
104
105  char *name() { return "trace_view"; }
106  trace_view(int w, int h) : i4_window_class(w,h)
107  {
108    theta=0;
109
110    i4_pixel_format fmt;
111    fmt.default_format();
112    fmt.alpha_mask=0;
113    fmt.calc_shift();
114
115    iw=w; ih=h;
116    z_buffer=(float *)i4_malloc(w*h*sizeof(float), "");
117    im=i4_create_image(w,h, i4_pal_man.register_pal(&fmt));
118
119    calc_transform();
120    light=i4_3d_vector(0,0,1);
121
122    render();
123 
124  }
125
126
127  i4_bool project_point(i4_3d_vector v, i4_3d_vector &t_v)
128  {
129    t.transform(v, t_v);
130    if (t_v.z>0)
131    {
132      float ooz=1.0/t_v.z;
133      t_v.x=t_v.x * ooz * width()/2.0 + width()/2.0;
134      t_v.y=t_v.y * ooz * height()/2.0 + height()/2.0;
135      return i4_T;
136    }
137    return i4_F;
138
139  }
140
141  void draw_3d_line(i4_3d_vector p1, i4_3d_vector p2,
142                    w32 color,
143                    i4_draw_context_class &context)
144  {
145    i4_3d_vector t_p1, t_p2;
146
147    if (project_point(p1, t_p1) &&
148        project_point(p2, t_p2))
149      local_image->line((int)t_p1.x, (int)t_p1.y,
150                        (int)t_p2.x, (int)t_p2.y, color, context);
151
152  }
153
154
155  void receive_event(i4_event *ev)
156  {
157    if (ev->type()==i4_event::MOUSE_BUTTON_DOWN)
158    {
159      CAST_PTR(bev, i4_mouse_button_event_class, ev);
160      float fw=width(), fh=height();
161      light=i4_3d_vector((bev->x-fw/2)/(fw/2),
162                         (bev->y-fh/2)/(fh/2),
163                         1);
164      light.normalize();
165                         
166      render();
167      request_redraw();
168     
169      mouse_x=bev->x;
170      mouse_y=bev->y;
171    }
172    else if (ev->type()==i4_event::KEY_PRESS)
173    {
174      theta+=0.2;
175      calc_transform();
176      render();
177      request_redraw();
178    }
179
180    i4_window_class::receive_event(ev);
181  }
182
183  void draw(i4_draw_context_class &context)
184  {
185    im->put_image(local_image, 0,0, context);
186
187    i4_float mx=(mouse_x - width()/2);
188    i4_float my=(mouse_y - height()/2); 
189
190    i4_3d_vector c_pos, c_dir;
191    t.inverse_transform(i4_3d_vector(0,0,0),c_pos);
192    t.inverse_transform(i4_3d_vector(mx,my, width()),c_dir); 
193
194    c_dir -= c_pos;
195
196
197    draw_3d_line(i4_3d_vector(-1,0,0),
198                 i4_3d_vector(1,0,0),
199                 0x00ff00, context);
200    draw_3d_line(i4_3d_vector(0,-1,0),
201                 i4_3d_vector(0,1,0),
202                 0x00ff00, context);
203    draw_3d_line(i4_3d_vector(0,0,-1),
204                 i4_3d_vector(0,0,1),
205                 0x00ff00, context);
206                 
207
208   
209    draw_3d_line(i4_3d_vector(c_pos.x + mx,
210                              c_pos.y + my,
211                              c_pos.z),
212                 i4_3d_vector(0,0,0),
213                 0xffffff, context);
214                 
215
216
217
218
219  }
Note: See TracBrowser for help on using the repository browser.