www.pudn.com > Ì廿֯Âë.rar > raycaster.cpp, change:2001-12-06,size:3504b


#include "progress.h" 
#include "raycaster.h" 
  
RayCaster::RayCaster() 
{ 
   m_image = NULL; 
} 
  
RayCaster::~RayCaster() 
{ 
   if (m_image != NULL) free(m_image); 
} 
 
void 
RayCaster::RayCastImage(Ray *ray, Volume *vol) 
{ 
   ProgressWin pw; 
   pw.SetText("Rendering Image ..."); 
   pw.SetRange(0, m_image_height-1); 
 
   float max = (float)(vol->GetMaxWidth());  
    
   float ix = max/((float)m_image_height); 
   float iy = max/((float)m_image_width); 
   float inc = (ix  iy) ? ix : iy; 
 
   coord3 pt00, pt10, pt01, ptmm; 
 
   float maxh = max/2; 
//   float maxv = max/2; 
   float dist = - maxh * 4; 
 
   vec_set(&pt00, -maxh, -maxh, dist); 
   vec_set(&pt10, +maxh, -maxh, dist); 
   vec_set(&pt01, -maxh, +maxh, dist);   
   vec_set(&ptmm, 0, 0, dist); 
 
   coord3 dir; 
   coord3 rpt00, rpt10, rpt01; 
   matrix44 view_matrix_inv; 
   vol->GetViewMatrixInv(view_matrix_inv); 
   vec_matrixmul(&rpt00, &view_matrix_inv, &pt00); 
   vec_matrixmul(&rpt10, &view_matrix_inv, &pt10); 
   vec_matrixmul(&rpt01, &view_matrix_inv, &pt01); 
   vec_matrixmul(&dir  , &view_matrix_inv, &ptmm); 
 
   coord3 xdir; 
   coord3 ydir; 
   vec_subtract(&xdir, &rpt10, &rpt00); 
   vec_subtract(&ydir, &rpt01, &rpt00); 
 
   vec_scale(&xdir, &xdir, 1/((float)m_image_width)); 
   vec_scale(&ydir, &ydir, 1/((float)m_image_height)); 
 
   coord3 xpos; 
   coord3 ypos; 
   rgba color; 
 
   rpt00.x += ((float)(vol->GetDimX()))/2; 
   rpt00.y += ((float)(vol->GetDimY()))/2; 
   rpt00.z += ((float)(vol->GetDimZ()))/2; 
 
   ypos = rpt00; 
   for (int y=0; y<m_image_height; y++) 
   { 
      xpos = ypos; 
      for (int x=0; x<m_image_width; x++) 
      { 
         ray->Cast(xpos, dir, color); 
         m_image[y * m_image_width + x] = color; 
         vec_add(&xpos, &xpos, &xdir); 
      } 
      vec_add(&ypos, &ypos, &ydir); 
      pw.SetPos(y); 
   }  
} 
 
void  
RayCaster::SetImageSize(int width, int height) 
{ 
   m_image_width = width; 
   m_image_height = height; 
   m_image_size = m_image_width * m_image_height * sizeof(rgba); 
   m_image = (rgba *)realloc(m_image, m_image_size); 
   SetImageDrawSize(m_image_draw_width, m_image_draw_height); 
} 
 
void  
RayCaster::SetImageDrawSize(int width, int height) 
{ 
   m_image_draw_width = width; 
   m_image_draw_height = height; 
   float pr1 = ((float)width)/((float)height); 
   float pr2 = ((float)m_image_width)/((float)m_image_height); 
   if (pr1  pr2) 
   { 
      m_image_zoom = ((float)width)/((float)m_image_width); 
   } 
   else 
   { 
      m_image_zoom = ((float)height)/((float)m_image_height); 
   } 
   m_shift_x = (int)(m_image_draw_width - m_image_zoom * m_image_width) / 2; 
   m_shift_y = (int)(m_image_draw_height - m_image_zoom * m_image_height) / 2; 
} 
 
int  
RayCaster::GetImageWidth() 
{ 
   return m_image_width; 
} 
 
int  
RayCaster::GetImageHeight() 
{ 
   return m_image_height; 
} 
 
void  
RayCaster::glDrawImage() 
{ 
   if (m_image != NULL) 
   {     
   	glMatrixMode(GL_PROJECTION); 
   	glLoadIdentity();				 
      glOrtho(0, m_image_draw_width, 0, m_image_draw_height, -1, 1); 
   	glMatrixMode(GL_MODELVIEW);		 
	   glLoadIdentity();							 
 
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer 
      glRasterPos3i(m_shift_x, m_shift_y,0); 
      glPixelZoom(m_image_zoom, m_image_zoom); 
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
      glDrawPixels(m_image_width, m_image_height, GL_RGBA, GL_UNSIGNED_BYTE, m_image); 
   } 
}