Trace.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:18k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * (RGB hardware)                                         *
  3.  * Simple 3D ray tracing engine.                          *
  4.  *                                                        *
  5.  * Defines:                                               *
  6.  *  TR_sphere_init           Actualy, does nothing;       *
  7.  *  TR_sphere_intersect      Closest of two;              *
  8.  *  TR_sphere_normal         From a point;                *
  9.  *  TR_polygon_init          Compute the plane equation;  *
  10.  *  TR_polygon_intersect     t of the intersection;       *
  11.  *  TR_polygon_normal        Always constant;             *
  12.  *  TR_init_world            Init all objects;            *
  13.  *  TR_trace_world           Building an image.           *
  14.  *                                                        *
  15.  * Internals:                                             *
  16.  *  TRI_make_ray_point       Construct from two points;   *
  17.  *  TRI_make_ray_vector      From a point and a vector;   *
  18.  *  TRI_on_ray               Point from ray coef;         *
  19.  *  TRI_illuminate           Local illumination;          *
  20.  *  TRI_shadow_ray           If a lightsource is shadowed;*
  21.  *  TRI_direct_ray           Computes one pixel's colour. *
  22.  *                                                        *
  23.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  24. **********************************************************/
  25. #include "Graphics.h"           /* G_pixel */
  26. #include "Colour.h"               /* colour related */
  27. #include "Vector.h"               /* linear algebra related */
  28. #include "Trace.h"                 /* self definition */
  29. #include <math.h>                           /* sqrt */
  30. #include <stdlib.h>                         /* malloc */
  31. int TR_rendering_type;                      /* rendering options */
  32. float TR_viewer[V_LNG_VECTOR];              /* position of the viewer */
  33. float TR_screen[V_LNG_VECTOR];              /* origine of the screen */
  34. float TR_screen_u[V_LNG_VECTOR];            /* screen orientation vectors */
  35. float TR_screen_v[V_LNG_VECTOR];
  36. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  37.  * Constructing a ray from two points.                   *
  38.  *                                                       *
  39.  * RETURNS: Constructed ray.                             *
  40.  * --------                                              *
  41. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  42. struct TR_ray *TRI_make_ray_point(struct TR_ray *r,float *from,
  43.                                                    float *to
  44.                                  )
  45. {
  46.  //设置光线矢量的起始点
  47.  V_set(r->tr_start,from);
  48.  //计算光线的矢量方向
  49.  V_difference(r->tr_codirected,to,from);
  50.  return(r);
  51. }
  52. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  53.  * Constructing a ray from a point and a vector.         *
  54.  *                                                       *
  55.  * RETURNS: Constructed ray.                             *
  56.  * --------                                              *
  57. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  58. struct TR_ray *TRI_make_ray_vector(struct TR_ray *r,float *from,
  59.                                                     float *vector
  60.                                   )
  61. {
  62.  V_set(r->tr_start,from);
  63.  V_set(r->tr_codirected,vector);
  64.  return(r);
  65. }
  66. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  67.  * Returns point at distance t from the origine.         *
  68.  *                                                       *
  69.  * RETURNS: Constructed vertex.                          *
  70.  * --------                                              *
  71. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  72. float *TRI_on_ray(float *point,struct TR_ray *r,float t)
  73. {
  74.  point[0]=r->tr_start[0]+r->tr_codirected[0]*t;
  75.  point[1]=r->tr_start[1]+r->tr_codirected[1]*t;
  76.  point[2]=r->tr_start[2]+r->tr_codirected[2]*t;
  77.  return(point);
  78. }
  79. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  80.  * Computing illumination of a intersected surface point.*
  81.  *                                                       *
  82.  * RETURNS: An RGB triple.                               *
  83.  * --------                                              *
  84. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  85. float *TRI_illuminate(float *light,struct TR_point_light *l,
  86.                                    struct TR_matter *material,
  87.                                    float *normal,
  88.                                    float *where,
  89.                                    float *viewer
  90.                     )
  91. {
  92.  int i;
  93.  float lightvector[V_LNG_VECTOR],viewvector[V_LNG_VECTOR],reflect[V_LNG_VECTOR];
  94.  float diffuseratio,specularratio,specularfun;
  95.  V_unit_vector(lightvector,where,l->tr_centre);
  96.  V_unit_vector(viewvector,where,viewer);
  97.  if((diffuseratio=V_scalar_product(normal,lightvector))>0)
  98.  {
  99.   if(TR_rendering_type&(TR_DIFFUSE|TR_SPECULAR))
  100.   {
  101.    light[0]+=l->tr_intensity[0]*material->tr_diffuse[0]*diffuseratio;
  102.    light[1]+=l->tr_intensity[1]*material->tr_diffuse[1]*diffuseratio;
  103.    light[2]+=l->tr_intensity[2]*material->tr_diffuse[2]*diffuseratio;
  104.   }
  105.                                             /* diffuse term */
  106.   if(TR_rendering_type&TR_SPECULAR)
  107.   {
  108.    reflect[0]=2*diffuseratio*normal[0]-lightvector[0];
  109.    reflect[1]=2*diffuseratio*normal[1]-lightvector[1];
  110.    reflect[2]=2*diffuseratio*normal[2]-lightvector[2];
  111.    if((specularratio=V_scalar_product(reflect,viewvector))>0)
  112.    {
  113.     for(specularfun=1,i=0;i<material->tr_exponent;i++) specularfun*=specularratio;
  114.     light[0]+=l->tr_intensity[0]*material->tr_specular*specularfun;
  115.     light[1]+=l->tr_intensity[1]*material->tr_specular*specularfun;
  116.     light[2]+=l->tr_intensity[2]*material->tr_specular*specularfun;
  117.    }                                        /* specular term */
  118.   }
  119.  }
  120.  return(light);
  121. }
  122. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  123.  * Casting a ray towards a lightsource to find out if    *
  124.  * it is hidden by other objects or not.                 *
  125.  *                                                       *
  126.  * RETURNS: 1 light source visible; 0 otherwise.         *
  127.  * --------                                              *
  128. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  129. int TRI_shadow_ray(struct TR_world *w,
  130.                    struct TR_point_light *l,
  131.                    float *point,
  132.                    int cur_obj
  133.                   )
  134. {
  135.  float t=0.0;
  136.  int i;
  137.  struct TR_ray r;
  138.  TRI_make_ray_point(&r,point,l->tr_centre);
  139.  for(i=0;i<w->tr_no_objects;i++)            /* finding intersection */
  140.  {
  141.   if(i!=cur_obj)
  142.   {
  143.    switch(w->tr_objects[i]->tr_type)
  144.    {
  145.     case TR_SPHERE:  t=TR_sphere_intersect(&r,(struct TR_sphere*)w->tr_objects[i]);
  146.                      break;
  147.     case TR_POLYGON: t=TR_polygon_intersect(&r,(struct TR_polygon*)w->tr_objects[i]);
  148.                      break;
  149.    }
  150.    if((t>0)&&(t<=1)) return(1);             /* first intersection is enough */
  151.   }
  152.  }
  153.  return(0);
  154. }
  155. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  156.  * Casting a ray into the world, recursing to compute    *
  157.  * environmental reflections.                            *
  158.  *                                                       *
  159.  * RETURNS: Illumination for the pixel.                  *
  160.  * --------                                              *
  161. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  162. float *TRI_direct_ray(float *light,struct TR_world *w,
  163.                                    struct TR_ray *r,
  164.                                    int cur_obj,
  165.                                    int depth
  166.                      )
  167. {
  168.  int i,min=0,no_inter=0;
  169.  float objt[TR_MAX_SPHERES],t=0.0;
  170.  int obj[TR_MAX_SPHERES];
  171.  struct TR_ray rr;
  172.  float where[V_LNG_VECTOR];                 /* current intersection */
  173.  float normal[V_LNG_VECTOR];                /* of the current intersection */
  174.  float viewer[V_LNG_VECTOR],reflect[V_LNG_VECTOR],rlight[V_LNG_VECTOR];
  175.  if(depth!=0)
  176.  {
  177.   for(i=0;i<w->tr_no_objects;i++)           /* finding intersection */
  178.   {
  179.    if(i!=cur_obj)                           /* with itself, no sense */
  180.    {
  181.     switch(w->tr_objects[i]->tr_type)
  182.     {
  183.      case TR_SPHERE:  t=TR_sphere_intersect(r,(struct TR_sphere*)w->tr_objects[i]);
  184.   //同球求交
  185.                       break;
  186.      case TR_POLYGON: t=TR_polygon_intersect(r,(struct TR_polygon*)w->tr_objects[i]);
  187. //同多边形求交
  188.                       break;
  189.     }
  190.     if(t>0)                                 /* not behind the ray */
  191.     {
  192.      objt[no_inter]=t; obj[no_inter++]=i;   /* a valid intersection */
  193.     }
  194.    }
  195.   }
  196.   if(no_inter!=0)                           /* if some objects intersected */
  197.   {
  198.    for(i=1;i<no_inter;i++)
  199.     if(objt[min]>objt[i]) min=i;            /* finding closest intersection */
  200.    light[0]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[0]*w->tr_ambient[0];
  201.    light[1]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[1]*w->tr_ambient[1];
  202.    light[2]+=w->tr_objects[obj[min]]->tr_material.tr_ambient[2]*w->tr_ambient[2];
  203.    TRI_on_ray(where,r,objt[min]);           /* intersection's coordinate */
  204.    switch(w->tr_objects[obj[min]]->tr_type)
  205.    {
  206. //
  207. case TR_SPHERE:  TR_sphere_normal(normal,where,(struct TR_sphere*)w->tr_objects[obj[min]]);
  208.                      break;
  209.     case TR_POLYGON: TR_polygon_normal(normal,where,(struct TR_polygon*)w->tr_objects[obj[min]]);
  210.                      break;
  211.    }
  212.    for(i=0;i<w->tr_no_point_lights;i++)     /* illumination from each light */
  213.    {
  214.     if((!TRI_shadow_ray(w,w->tr_point_lights[i],where,obj[min]))||
  215.        (!(TR_rendering_type&TR_SHADOW))
  216.       )
  217.      TRI_illuminate(light,w->tr_point_lights[i],
  218.                     &w->tr_objects[obj[min]]->tr_material,
  219.                     normal,where,TR_viewer
  220.                    );
  221.    }
  222.    if(TR_rendering_type&TR_REFLECT)
  223.    {
  224.     V_unit_vector(viewer,where,TR_viewer);
  225.     V_multiply(reflect,normal,V_scalar_product(normal,viewer)*2);
  226.     V_difference(reflect,reflect,viewer);
  227.     TRI_make_ray_vector(&rr,where,reflect); /* prepare recursive ray */
  228.     TRI_direct_ray(V_zero(rlight),w,&rr,obj[min],depth-1);
  229.     light[0]+=rlight[0]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
  230.     light[1]+=rlight[1]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
  231.     light[2]+=rlight[2]*w->tr_objects[obj[min]]->tr_material.tr_reflect;
  232.    }
  233.   }
  234.  }
  235.  return(light);
  236. }
  237. /**********************************************************
  238.  * Setting the rendering type.                            *
  239. **********************************************************/
  240. void TR_init_rendering(int type)
  241. {
  242.  TR_rendering_type=type;
  243. }
  244. /**********************************************************
  245.  * Setting the camera parameter, where TR_viewer stores   *
  246.  * position of the viewer's eye, TR_screen origine of the *
  247.  * projection plane, TR_screen_u and TR_screen_v          *
  248.  * orientation of the projection plane in the world       *
  249.  * space.                                                 *
  250. **********************************************************/
  251. //摄像机参数的设置,
  252. //TR_viever存储遮视窗eye的位置