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>xfw/2)/(fw/2),


162  (bev>yfh/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  }

