www.pudn.com > Ì廿֯Âë.rar > volume.cpp, change:2001-12-12,size:24956b
#include <stdio.h>
#include <math.h>
#include "stdafx.h"
#include "openglsupport.h"
#include "vecmath.h"
#include "volume.h"
#include "progress.h"
#include "color.h"
//--------------------------------------------------------------
grad_t operator * (grad_t g1, float s)
{
grad_t g;
g.x = g1.x * s;
g.y = g1.y * s;
g.z = g1.z * s;
return g;
}
grad_t operator + (grad_t g1, grad_t g2)
{
grad_t g;
g.x = g1.x + g2.x;
g.y = g1.y + g2.y;
g.z = g1.z + g2.z;
return g;
}
bool norm(grad_t &g)
{
float l = (float)sqrt(g.x*g.x + g.y*g.y + g.z*g.z);
if (l > 0)
{
float il = (1.0f/l);
g.x *= il;
g.y *= il;
g.z *= il;
return true;
}
return false;
}
float normlen(grad_t &g)
{
float l = (float)sqrt(g.x*g.x + g.y*g.y + g.z*g.z);
if (l > 0)
{
float il = (1.0f/l);
g.x *= il;
g.y *= il;
g.z *= il;
}
return l;
}
float length(grad_t g)
{
return (float)(sqrt(g.x*g.x + g.y*g.y + g.z*g.z));
}
//--------------------------------------------------------------
void swap4(void *p)
{
char *c = (char *)p;
char h;
h = c[0]; c[0] = c[3]; c[3] = h;
h = c[1]; c[1] = c[2]; c[2] = h;
}
//===== class Volume =============================================
Volume::Volume()
{
m_data = NULL;
m_grad = NULL;
// m_gradlen = NULL;
m_overview_xtex = NULL;
m_overview_ytex = NULL;
m_overview_ztex = NULL;
m_view_matrix = IDENTITY_MATRIX;
m_view_matrix_inv = IDENTITY_MATRIX;
m_overview_gllist = 0;
for (int i=0; i=MAXDENSITY; i++) m_histogram[i] = 0.0f;
}
Volume::~Volume()
{
if (m_data != NULL) delete []m_data;
if (m_grad != NULL) delete []m_grad;
// if (m_gradlen != NULL) delete []m_gradlen;
if (m_overview_xtex != NULL) glDeleteTextures(m_overview_texsize, m_overview_xtex);
if (m_overview_ytex != NULL) glDeleteTextures(m_overview_texsize, m_overview_ytex);
if (m_overview_ztex != NULL) glDeleteTextures(m_overview_texsize, m_overview_ztex);
if (m_overview_xtex != NULL) delete []m_overview_xtex;
if (m_overview_ytex != NULL) delete []m_overview_ytex;
if (m_overview_ztex != NULL) delete []m_overview_ztex;
if (m_overview_gllist != 0) glDeleteLists(m_overview_gllist, 1);
}
void
Volume::CalcGradient()
{
ProgressWin pw;
// ===== gradienten berechnen =====
pw.SetText("Calculating Gradient Data ...");
pw.SetRange(0, m_zz);
grad_t g;
// float len;
int x,y,z;
int ix,iy,iz;
m_grad = new grad_t[m_size];
// m_gradlen = new float[m_size];
iz = 0;
for (z=0; z<m_z; z++)
{
iy = 0;
for (y=0; y<m_y; y++)
{
ix = 0;
for (x=0; x<m_x; x++)
{
g.x = (float)(GetDataI(ix+1,iy, iz ) - GetDataI(ix-1,iy ,iz ));
g.y = (float)(GetDataI(ix, iy+m_x,iz ) - GetDataI(ix, iy-m_x,iz ));
g.z = (float)(GetDataI(ix, iy, iz+m_xy) - GetDataI(ix, iy ,iz-m_xy));
// len = normlen(g);
norm(g);
m_grad[DATAI(ix,iy,iz)] = g;
// m_gradlen[DATAI(ix,iy,iz)] = len;
ix++;
}
iy += m_x;
}
pw.SetPos(z);
iz += m_xy;
}
}
void
Volume::CalcHistogram()
{
ProgressWin pw;
// ===== histogram berechnen
pw.SetText("Calculating Histogram ...");
pw.SetRange(0, m_zz);
int x,y,z;
int i;
for (i=0; i=MAXDENSITY; i++) m_histogram[i] = 0.0f;
for (z=0; z<m_z; z++)
{
for (y=0; y<m_y; y++)
for (x=0; x<m_x; x++)
{
m_histogram[m_data[DATA(x,y,z)]] += 1.0f;
}
pw.SetPos(z);
}
// suche maximum
float max = 0.0f;
for (i=0; i=MAXDENSITY; i++) if (m_histogram[i] > max) max = m_histogram[i];
max *= 0.25f;
// normalisieren
for (i=0; i=MAXDENSITY; i++) m_histogram[i] /= ((float)max);
}
void
Volume::Initialise()
{
m_max = m_x;
if (m_max m_y) m_max = m_y;
if (m_max m_z) m_max = m_z;
}
bool
Volume::LoadDataDAT(const char *filename)
{
FILE *f;
f = fopen(filename, "r+b");
if (f != NULL)
{
ProgressWin pw;
// ===== daten laden =====
unsigned short sx,sy,sz;
fread(&sx, 2, 1, f);
fread(&sy, 2, 1, f);
fread(&sz, 2, 1, f);
pw.SetText("Loading Volume Data ...");
m_x = (int)sx;
m_y = (int)sy;
m_z = (int)sz;
m_xx = m_x-1;
m_yy = m_y-1;
m_zz = m_z-1;
m_xy = m_x * m_y;
m_xyz = m_xy * m_z;
m_size = m_x * m_y * m_z;
m_data = new data_t[m_size];
fread(m_data, 2, m_size, f);
fclose(f);
int x, y, z;
// daten maskieren mit 12bit maske
pw.SetText("Preparing Volume Data ...");
pw.SetRange(0, m_zz);
for (z=0; z<m_z; z++)
{
for (y=0; y<m_y; y++)
for (x=0; x<m_x; x++)
m_data[DATA(x,y,z)] &= 0x0fff;
pw.SetPos(z);
}
//-------------
CalcGradient();
CalcHistogram();
Initialise();
return true;
}
return false;
}
bool
Volume::LoadDataVOL(const char *filename)
{
struct VolHeader
{
long magic;
long headerlength;
long width;
long height;
long images;
long bitspervoxel;
long indexbits;
float scaleX;
float scaleY;
float scaleZ;
float rotX;
float rotY;
float rotZ;
};
FILE *f;
f = fopen(filename, "r+b");
if (f != NULL)
{
ProgressWin pw;
VolHeader vh;
int x, y, z;
// ===== daten laden =====
fread(&(vh.magic), 4, 1, f);
fread(&(vh.headerlength), 4, 1, f);
fread(&(vh.width), 4, 1, f);
fread(&(vh.height), 4, 1, f);
fread(&(vh.images), 4, 1, f);
fread(&(vh.bitspervoxel), 4, 1, f);
fread(&(vh.indexbits), 4, 1, f);
fread(&(vh.scaleX), 4, 1, f);
fread(&(vh.scaleY), 4, 1, f);
fread(&(vh.scaleZ), 4, 1, f);
swap4(&(vh.magic));
swap4(&(vh.headerlength));
swap4(&(vh.width));
swap4(&(vh.height));
swap4(&(vh.images));
swap4(&(vh.bitspervoxel));
swap4(&(vh.indexbits));
swap4(&(vh.scaleX));
swap4(&(vh.scaleY));
swap4(&(vh.scaleZ));
fseek(f, vh.headerlength, SEEK_SET);
int voxbits = vh.bitspervoxel + vh.indexbits;
if (voxbits > 32)
{
fclose(f);
return false;
}
int voxbytes = vh.bitspervoxel >> 3;
m_x = vh.width;
m_y = vh.height;
m_z = vh.images;
m_xx = m_x-1;
m_yy = m_y-1;
m_zz = m_z-1;
m_xy = m_x * m_y;
m_xyz = m_xy * m_z;
m_size = m_x * m_y * m_z;
m_data = new data_t[m_size];
int shift = 32 - vh.bitspervoxel;
int mask = ((1 < (vh.bitspervoxel - vh.indexbits)) - 1) < vh.indexbits;
pw.SetText("Loading Volume Data ...");
pw.SetRange(0, m_zz);
if (voxbytes == 3) voxbytes = 4;
for (z=0; z<m_z; z++)
{
for (y=0; y<m_y; y++)
for (x=0; x<m_x; x++)
{
long l;
fread(&l, voxbytes, 1, f);
m_data[DATA(x,y,z)] = ((((l & mask) < shift) >> 20) & 0x0fff);
}
pw.SetPos(z);
}
fclose(f);
// ===== daten resamplen =====
if (vh.magic == 192837466) // C_VR_MAGIC_NUMBER
{
int t_x = (int)(m_x * vh.scaleX);
int t_y = (int)(m_y * vh.scaleY);
int t_z = (int)(m_z * vh.scaleZ);
int t_size = t_x * t_y * t_z;
data_t *t_data = new data_t[t_size];
memset(t_data, 0, t_size);
float sx = ((float)m_x) / t_x;
float sy = ((float)m_y) / t_y;
float sz = ((float)m_z) / t_z;
pw.SetText("Resampling Volume Data ...");
pw.SetRange(0, t_z-1);
coord3 pos;
pos.z = 0;
for (z=0; z<t_z; z++)
{
pos.y = 0;
for (y=0; y<t_y; y++)
{
pos.x = 0;
for (x=0; x<t_x; x++)
{
data_t d;
GetDataTL(pos, d);
t_data[DATA(x,y,z)] = (d & 0xfff);
pos.x += sx;
}
pos.y += sy;
}
pos.z += sz;
pw.SetPos(z);
}
delete []m_data;
m_x = t_x;
m_y = t_y;
m_z = t_z;
m_xx = m_x-1;
m_yy = m_y-1;
m_zz = m_z-1;
m_xy = m_x * m_y;
m_xyz = m_xy * m_z;
m_size = m_x * m_y * m_z;
m_data = t_data;
}
//-------------
CalcGradient();
CalcHistogram();
Initialise();
return true;
}
return false;
}
bool
Volume::GetData(int x, int y, int z, data_t &data)
{
data = m_data[DATA(x,y,z)];
return true;
}
data_t
Volume::GetData(int x, int y, int z)
{
if ((x<0) || (x>=m_x) || (y<0) || (y>=m_y) || (z<0) || (z>=m_z)) return 0;
return m_data[DATA(x,y,z)];
}
data_t
Volume::GetDataI(int x, int y, int z)
{
if ((x<0) || (x>=m_x) || (y<0) || (y>=m_xy) || (z<0) || (z>=m_xyz)) return 0;
return m_data[DATAI(x,y,z)];
}
bool
Volume::GetData(coord3 &pos, data_t &data)
{
data = m_data[DATA((int)(pos.x),(int)(pos.y),(int)(pos.z))];
return true;
}
bool
Volume::GetDataTL(coord3 &pos, data_t &data)
{
int x0 = (int)(pos.x);
int y0 = (int)(pos.y);
int z0 = (int)(pos.z);
if ((x0 >= m_xx) || (y0 >= m_yy) || (z0 >= m_zz)) return false;
int x1 = x0+1;
int y1 = y0+1;
int z1 = z0+1;
float fx = pos.x - x0;
float fy = pos.y - y0;
float fz = pos.z - z0;
float dm00 = m_data[DATA(x0,y0,z0)]*(1-fx) + m_data[DATA(x1,y0,z0)]*fx;
float dm10 = m_data[DATA(x0,y1,z0)]*(1-fx) + m_data[DATA(x1,y1,z0)]*fx;
float dm01 = m_data[DATA(x0,y0,z1)]*(1-fx) + m_data[DATA(x1,y0,z1)]*fx;
float dm11 = m_data[DATA(x0,y1,z1)]*(1-fx) + m_data[DATA(x1,y1,z1)]*fx;
float dmm0 = dm00*(1-fy) + dm10*fy;
float dmm1 = dm01*(1-fy) + dm11*fy;
float dmmm = dmm0*(1-fz) + dmm1*fz;
data = (data_t)dmmm;
return true;
/*
int fx = ((int)(pos.x*FPMUL)) & FPMASK;
int fy = ((int)(pos.y*FPMUL)) & FPMASK;
int fz = ((int)(pos.z*FPMUL)) & FPMASK;
int dx00 = ((int)m_data[DATA(x0,y0,z0)])*(FPMUL-fx) + ((int)m_data[DATA(x1,y0,z0)])*fx;
int dx10 = ((int)m_data[DATA(x0,y1,z0)])*(FPMUL-fx) + ((int)m_data[DATA(x1,y1,z0)])*fx;
int dx01 = ((int)m_data[DATA(x0,y0,z1)])*(FPMUL-fx) + ((int)m_data[DATA(x1,y0,z1)])*fx;
int dx11 = ((int)m_data[DATA(x0,y1,z1)])*(FPMUL-fx) + ((int)m_data[DATA(x1,y1,z1)])*fx;
int dy0 = (dx00>>FPSH)*(FPMUL-fy) + (dx10>>FPSH)*fy;
int dy1 = (dx01>>FPSH)*(FPMUL-fy) + (dx11>>FPSH)*fy;
int dz = (dy0>>FPSH)*(FPMUL-fz) + (dy1>>FPSH)*fz;
data = (data_t)(dz>>FPSH);
return true;
*/
}
bool
Volume::GetGradient(int x, int y, int z, grad_t &grad)
{
grad = m_grad[DATA(x,y,z)];
return true;
}
bool
Volume::GetGradient(coord3 &pos, grad_t &grad)
{
grad = m_grad[DATA((int)(pos.x),(int)(pos.y),(int)(pos.z))];
return true;
}
bool
Volume::GetGradientTL(coord3 &pos, grad_t &grad)
{
int x0 = (int)(pos.x);
int y0 = (int)(pos.y);
int z0 = (int)(pos.z);
if ((x0 >= m_xx) || (y0 >= m_yy) || (z0 >= m_zz)) return false;
int x1 = x0+1;
int y1 = y0+1;
int z1 = z0+1;
float fx = pos.x - x0;
float fy = pos.y - y0;
float fz = pos.z - z0;
grad_t gm00 = (m_grad[DATA(x0,y0,z0)]*(1-fx) + m_grad[DATA(x1,y0,z0)]*fx);
grad_t gm10 = (m_grad[DATA(x0,y1,z0)]*(1-fx) + m_grad[DATA(x1,y1,z0)]*fx);
grad_t gm01 = (m_grad[DATA(x0,y0,z1)]*(1-fx) + m_grad[DATA(x1,y0,z1)]*fx);
grad_t gm11 = (m_grad[DATA(x0,y1,z1)]*(1-fx) + m_grad[DATA(x1,y1,z1)]*fx);
norm(gm00);
norm(gm10);
norm(gm01);
norm(gm11);
grad_t gmm0 = (gm00*(1-fy) + gm10*fy);
grad_t gmm1 = (gm01*(1-fy) + gm11*fy);
norm(gmm0);
norm(gmm1);
grad_t gmmm = (gmm0*(1-fz) + gmm1*fz);
norm(gmmm);
grad = gmmm;
return true;
}
/*
float
Volume::GetGradientLength(coord3 &pos)
{
return m_gradlen[DATA((int)(pos.x),(int)(pos.y),(int)(pos.z))];
}
float
Volume::GetGradientLengthTL(coord3 &pos)
{
int x0 = (int)(pos.x);
int y0 = (int)(pos.y);
int z0 = (int)(pos.z);
if ((x0 >= m_xx) || (y0 >= m_yy) || (z0 >= m_zz)) return 0.0;
int x1 = x0+1;
int y1 = y0+1;
int z1 = z0+1;
float fx = pos.x - x0;
float fy = pos.y - y0;
float fz = pos.z - z0;
float dm00 = m_gradlen[DATA(x0,y0,z0)]*(1-fx) + m_gradlen[DATA(x1,y0,z0)]*fx;
float dm10 = m_gradlen[DATA(x0,y1,z0)]*(1-fx) + m_gradlen[DATA(x1,y1,z0)]*fx;
float dm01 = m_gradlen[DATA(x0,y0,z1)]*(1-fx) + m_gradlen[DATA(x1,y0,z1)]*fx;
float dm11 = m_gradlen[DATA(x0,y1,z1)]*(1-fx) + m_gradlen[DATA(x1,y1,z1)]*fx;
float dmm0 = dm00*(1-fy) + dm10*fy;
float dmm1 = dm01*(1-fy) + dm11*fy;
float dmmm = dmm0*(1-fz) + dmm1*fz;
return dmmm;
}
*/
//-------------------------------------------------------------------
int
Volume::GetDimX()
{
return m_x;
}
int
Volume::GetDimY()
{
return m_y;
}
int
Volume::GetDimZ()
{
return m_z;
}
int
Volume::GetMaxWidth()
{
return m_max;
}
//-------------------------------------------------------------------
float
Volume::GetHistogramValue(int i)
{
if ((i 0) || (i > MAXDENSITY)) return 0.0f;
return m_histogram[i];
}
float
Volume::GetHistogramRange(int min, int max)
{
int h;
if (max min)
{
h = max;
max = min;
min = h;
}
if ((max 0) || (min > MAXDENSITY)) return 0.0f;
if (max > MAXDENSITY) max = MAXDENSITY;
if (min 0) min = 0;
float val = 0;
for (h=min; h=max; h++) val += m_histogram[h];
return val;
}
//-------------------------------------------------------------------
bool
Volume::GetRayEnds(coord3 &nearpos, coord3 &farpos, coord3 &pos, coord3 &dir, float &dist)
{
// intersect ray with the volume cube from (0,0,0) to (m_x,m_y,m_z);
float nearscale = -1000000;
float farscale = +1000000;
float scale1, scale2;
// intersect with x planes
if (dir.x != 0)
{
scale1 = (0 - pos.x) / dir.x;
scale2 = (m_xx - pos.x) / dir.x;
if (scale1 scale2)
{
if (scale1 > nearscale) nearscale = scale1;
if (scale2 farscale) farscale = scale2;
}
else
{
if (scale2 > nearscale) nearscale = scale2;
if (scale1 farscale) farscale = scale1;
}
}
// intersect with y planes
if (dir.y != 0)
{
scale1 = (0 - pos.y) / dir.y;
scale2 = (m_yy - pos.y) / dir.y;
if (scale1 scale2)
{
if (scale1 > nearscale) nearscale = scale1;
if (scale2 farscale) farscale = scale2;
}
else
{
if (scale2 > nearscale) nearscale = scale2;
if (scale1 farscale) farscale = scale1;
}
}
// intersect with z planes
if (dir.z != 0)
{
scale1 = (0 - pos.z) / dir.z;
scale2 = (m_zz - pos.z) / dir.z;
if (scale1 scale2)
{
if (scale1 > nearscale) nearscale = scale1;
if (scale2 farscale) farscale = scale2;
}
else
{
if (scale2 > nearscale) nearscale = scale2;
if (scale1 farscale) farscale = scale1;
}
}
nearpos.x = pos.x + nearscale * dir.x + 0.5f;
nearpos.y = pos.y + nearscale * dir.y + 0.5f;
nearpos.z = pos.z + nearscale * dir.z + 0.5f;
if (nearpos.x 0) return false;
if (nearpos.x >= m_x) return false;
if (nearpos.y 0) return false;
if (nearpos.y >= m_y) return false;
if (nearpos.z 0) return false;
if (nearpos.z >= m_z) return false;
farpos.x = pos.x + farscale * dir.x + 0.5f;
farpos.y = pos.y + farscale * dir.y + 0.5f;
farpos.z = pos.z + farscale * dir.z + 0.5f;
if (farpos.x 0) return false;
if (farpos.x >= m_x) return false;
if (farpos.y 0) return false;
if (farpos.y >= m_y) return false;
if (farpos.z 0) return false;
if (farpos.z >= m_z) return false;
coord3 tmp;
vec_subtract(&tmp, &farpos, &nearpos);
dist = vec_length(&tmp);
return true;
}
//-------------------------------------------------------------------
void
Volume::CreateOverview(int ts)
{
int texsize = 1 < ts;
rgba *texture = new rgba[texsize*texsize];
data_t *voldata = new data_t[texsize*texsize*texsize];
m_overview_texsize = texsize;
int x,y,z,i,j;
ProgressWin pw;
pw.SetText("Generating Overview Textures: Preparing Textures ...");
pw.SetRange(0,texsize-1);
float sx = ((float)m_x)/((float)texsize);
float sy = ((float)m_y)/((float)texsize);
float sz = ((float)m_z)/((float)texsize);
for (z=0; z<texsize; z++)
{
for (y=0; y<texsize; y++)
for (x=0; x<texsize; x++)
{
coord3 pos;
data_t d;
pos.x = x * sx;
pos.y = y * sy;
pos.z = z * sz;
GetData(pos, d);
voldata[(z*texsize+y)*texsize+x] = d;
}
pw.SetPos(z);
}
glEnable(GL_TEXTURE_2D);
GLint neighbour = GL_NEAREST;
// ----- Z axis -----
pw.SetText("Generating Overview Textures: Z axis ...");
pw.SetRange(0,texsize-1);
m_overview_ztex = new GLuint[texsize];
glGenTextures(texsize, m_overview_ztex);
for (i=0; i<texsize; i++)
{
for (y=0; y<texsize; y++)
for (x=0; x<texsize; x++)
{
data_t d = voldata[(i*texsize+y)*texsize+x];
unsigned char uc = d >> 4;
texture[y*texsize+x].r = 128+uc/2;
texture[y*texsize+x].g = 128+uc/2;
texture[y*texsize+x].b = 128+uc/2;
texture[y*texsize+x].a = uc;
}
glBindTexture(GL_TEXTURE_2D, m_overview_ztex[i]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 4, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
pw.SetPos(i);
}
// ----- Y axis -----
pw.SetText("Generating Overview Textures: Y axis ...");
pw.SetRange(0,texsize-1);
m_overview_ytex = new GLuint[texsize];
glGenTextures(texsize, m_overview_ytex);
for (i=0; i<texsize; i++)
{
for (y=0; y<texsize; y++)
for (x=0; x<texsize; x++)
{
data_t d = voldata[(y*texsize+i)*texsize+x];
unsigned char uc = d >> 4;
texture[y*texsize+x].r = 128+uc/2;
texture[y*texsize+x].g = 128+uc/2;
texture[y*texsize+x].b = 128+uc/2;
texture[y*texsize+x].a = uc;
}
glBindTexture(GL_TEXTURE_2D, m_overview_ytex[i]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 4, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
pw.SetPos(i);
}
// ----- X axis -----
pw.SetText("Generating Overview Textures: X axis ...");
pw.SetRange(0,texsize-1);
m_overview_xtex = new GLuint[texsize];
glGenTextures(texsize, m_overview_xtex);
for (i=0; i<texsize; i++)
{
for (y=0; y<texsize; y++)
for (x=0; x<texsize; x++)
{
data_t d = voldata[(y*texsize+x)*texsize+i];
unsigned char uc = d >> 4;
texture[y*texsize+x].r = 128+uc/2;
texture[y*texsize+x].g = 128+uc/2;
texture[y*texsize+x].b = 128+uc/2;
texture[y*texsize+x].a = uc;
}
glBindTexture(GL_TEXTURE_2D, m_overview_xtex[i]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 4, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, neighbour);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
pw.SetPos(i);
}
// create display list
m_overview_gllist = glGenLists(1);
glNewList(m_overview_gllist, GL_COMPILE);
float mx = (float)m_x;
float my = (float)m_y;
float mz = (float)m_z;
/* float sx = mx/m_overview_texsize;
float sy = my/m_overview_texsize;
float sz = mz/m_overview_texsize; */
GLfloat LightAmbient[]= { 0.6f, 0.6f, 0.6f, 1.0f };
GLfloat LightDiffuse[]= { 0.8f, 0.8f, 0.8f, 1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, LightDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, LightAmbient);
for (i=0; i<m_overview_texsize; i++)
{
glBindTexture(GL_TEXTURE_2D, m_overview_ztex[i]);
glBegin(GL_QUADS);
for (j=0; j<2; j++)
{
glNormal3f(0, 0, 1);
glTexCoord2f(0, 0);
glVertex3f(0, 0, (i+j)*sz);
glTexCoord2f(1, 0);
glVertex3f(mx, 0, (i+j)*sz);
glTexCoord2f(1, 1);
glVertex3f(mx,my, (i+j)*sz);
glTexCoord2f(0, 1);
glVertex3f(0,my, (i+j)*sz);
}
glEnd();
}
for (i=0; i<m_overview_texsize; i++)
{
glBindTexture(GL_TEXTURE_2D, m_overview_ytex[i]);
glBegin(GL_QUADS);
for (j=0; j<2; j++)
{
glNormal3f(0, -1, 0);
glTexCoord2f(0, 0);
glVertex3f(0, (i+j)*sy, 0);
glTexCoord2f(1, 0);
glVertex3f(mx, (i+j)*sy, 0);
glTexCoord2f(1, 1);
glVertex3f(mx, (i+j)*sy, mz);
glTexCoord2f(0, 1);
glVertex3f(0, (i+j)*sy, mz);
}
glEnd();
}
for (i=0; i<m_overview_texsize; i++)
{
glBindTexture(GL_TEXTURE_2D, m_overview_xtex[i]);
glBegin(GL_QUADS);
for (j=0; j<2; j++)
{
glNormal3f(1, 0, 0);
glTexCoord2f(0, 0);
glVertex3f((i+j)*sx, 0, 0);
glTexCoord2f(1, 0);
glVertex3f((i+j)*sx,my, 0);
glTexCoord2f(1, 1);
glVertex3f((i+j)*sx,my, mz);
glTexCoord2f(0, 1);
glVertex3f((i+j)*sx, 0, mz);
}
glEnd();
}
glEndList();
glFlush();
glDisable(GL_TEXTURE_2D);
delete []texture;
delete []voldata;
}
void
Volume::SetOverviewDrawSize(int width, int height)
{
m_overview_draw_width = width;
m_overview_draw_height = height;
}
//-------------------------------------------------------------------
void
Volume::GetViewMatrix(matrix44 &m)
{
m = m_view_matrix;
}
void
Volume::GetViewMatrixInv(matrix44 &m)
{
m = m_view_matrix_inv;
}
void
Volume::ViewRotate(float angle, float x, float y, float z)
{
matrix44 m,tmp;
matrix_rotate(&m, x, y, z, angle);
tmp = m_view_matrix;
matrix_matrixmul(&m_view_matrix, &m, &tmp);
matrix_rotate(&m, x, y, z, -angle);
tmp = m_view_matrix_inv;
matrix_matrixmul(&m_view_matrix_inv, &tmp, &m);
}
//-------------------------------------------------------------------
void
Volume::glOverviewDraw(int threshold)
{
glClearColor(0.0f, 0.0f, 0.4f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GEQUAL, ((float)threshold)/MAXDENSITY);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float w = ((GLfloat)m_overview_draw_width/(GLfloat)m_overview_draw_height) * 0.5f;
glOrtho(-w, +w, -0.5, +0.5, -2, +2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float mx = (float)m_x;
float my = (float)m_y;
float mz = (float)m_z;
glMultMatrixf((const float *)m_view_matrix.matrix);
glScalef(1.0f/m_max, 1.0f/m_max, 1.0f/m_max);
glTranslatef(-mx/2, -my/2, -mz/2);
glCallList(m_overview_gllist);
glFlush();
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
}