Thursday, June 5, 2008

Object aligned slice based volume rendering


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.



Object aligned slicing

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.

3 comments:

Pablo Guzman said...

Can you upload the code example of this. Thx in advance!!!!!! great job

Alexey Manuylenko said...

Could you please show how do you do a final blending? Thanks...

Muhammad Mobeen Movania said...

Hi,
It 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();
}

Popular Posts

Copyright (C) 2011 - Movania Muhammad Mobeen. Awesome Inc. theme. Powered by Blogger.