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);
}
}