I just finished 2D texture slices based volume rendering today. Here are the snapshots of the application. Its damn fast. I will be adding some transfer function editing facility into it tomorrow.
A cool idea though will now work on transfer functions and then view aligned slicing of 3D texture.
Implementation details:
I used glut and OpenGL for this b/c I think its much more fast to develop applications in OpenGL and glut. First I determine the current view direction vector which is simply obtained using the following code
GLfloat matView[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matView);
GLfloat viewDir[3]={ -matView[2], -matView[6], -matView[10]};
Next a 3d texture is loaded from the CT/MRI scans and then using this code, object space quad slices are generated. Here I am only giving the code for the PosZ axis. A slight modification is needed for the other axes.
void DrawSliceZPos()
{
float zPos = 0.5;
float zAmt = -1.0f/zSlices;
glBindTexture(GL_TEXTURE_3D,textureID);
glBegin(GL_QUADS);
//offset the slice so its in the middle
zPos += zAmt/2.0f;
for(int i=zSlices-1;i>=0;i--)
{
float tex = (((float)i)/zSlices);
glTexCoord3f(0,0,tex); glVertex3f(-0.5, -0.5, zPos);
glTexCoord3f(0,1,tex); glVertex3f(-0.5, 0.5, zPos);
glTexCoord3f(1,1,tex); glVertex3f( 0.5, 0.5, zPos);
glTexCoord3f(1,0,tex); glVertex3f( 0.5, -0.5, zPos);
zPos += zAmt;
}
glEnd();
}
The appropriate slices are drawn based on the maximum abs value of the current view direction as
switch(GetMaxDim(viewDir))
{
case 0:
if(viewDir[maxDim] > 0.0f)
DrawSlicePosX();
else
DrawSliceNegX();
break;
...
case n: ... and so on
}
Thats it and finally the result is blended to produce the rendering as shown above.
Can you upload the code example of this. Thx in advance!!!!!! great job
ReplyDeleteCould you please show how do you do a final blending? Thanks...
ReplyDeleteHi,
ReplyDeleteIt follows the conventional over blending eq. i.e.
glEnable(GL_BLENDING);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
The overall rendering code is as follows (assuming volume texture is bound to texture target GL_TEXTURE_3D):
void Render() {
glClear(GL_COLOR_BUFFER_BIT|
GL_DEPTH_BUFFER_BIT);
//setup modelview matrix;
GLfkoat MV[16];
glGetFloatv(GL_MODELVIEW_MATRIX, MV);
GLfloat viewDir[3]={-MV[2],-MV[6], -MV[10]};
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
switch(GetMaxDim(viewDir)){
case 0:
if(viewDir[maxDim] > 0.f)
DrawSlicesPosX();
else
DrawSlicesNegX();
break;
case 1:
if(viewDir[maxDim] > 0.f)
DrawSlicesPosY();
else
DrawSlicesNegY();
break;
case 2:
if(viewDir[maxDim] > 0.f)
DrawSlicesPosZ();
else
DrawSlicesNegZ();
break;
}
glDisable(GL_BLEND);
glutSwapBuffers();
}