PDA

View Full Version : Volume Rendering a Stack of 2D Slices



mmorgan
07-22-2015, 11:41 AM
Hi All, based off of a previous topic here, I've tried to implement my own version of rendering a volume using 2D textures. Here's my code:

The Volume is a 3D array in memory, and I'm grabbing slices out of one of the cardinal directions.



int NumSlices = VolSize_pix.length;

GLuint * texturesObjects = new GLuint[NumSlices];

for (int SliceCount = 0; SliceCount < NumSlices; SliceCount++)
{
float * RGBAbuf;
RGBAbuf = new float[VolSize_pix.depth * VolSize_pix.width * 4]; // volsize_pix.depth and width are the dims of each 2D slice of the volume
int RGBAcounter = 0;

for (int VX = 0; VX < VolSize_pix.depth; VX++)
{
for (int VZ = 0; VZ < VolSize_pix.width; VZ++)
{
RGBAbuf[4 * RGBAcounter] = Volume[VX][SliceCount][VZ]/VolMax; // Red (divide by VolMax to normalize values)
RGBAbuf[4 * RGBAcounter + 1] = Volume[VX][SliceCount][VZ]/VolMax; // Green
RGBAbuf[4 * RGBAcounter + 2] = Volume[VX][SliceCount][VZ]/VolMax; // Blue
if (Volume[VX][SliceCount][VZ] / VolMax > 0.5)
{
RGBAbuf[4 * RGBAcounter + 3] = 1; // Alpha
}
else
{
RGBAbuf[4 * RGBAcounter + 3] = 0;
}
RGBAcounter++;
}
}

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texturesObjects[SliceCount]);
glBindTexture(GL_TEXTURE_2D, texturesObjects[SliceCount]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VolSize_pix.depth, VolSize_pix.width, 0, GL_RGBA, GL_FLOAT, (GLvoid*)RGBAbuf);
printf("SliceCount: %i\n", SliceCount);
free(RGBAbuf);
}


glfwMakeContextCurrent(window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
for (int i = 0; i < NumSlices; ++i)
{
glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, 2 * i / NumSlices - 1);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, 2 * i / NumSlices - 1);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, 2 * i / NumSlices - 1);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, 2 * i / NumSlices - 1);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}

// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();



But unfortunately, I get the dreaded empty black screen, and can't seem to find my error here... I was hoping to get a fresh pair of eyes.

Thanks in advance, really appreciate any insight!

GClements
07-22-2015, 02:36 PM
The only thing which immediately stands out is




glVertex3f(-1.0, -1.0, 2 * i / NumSlices - 1);


Both operands to the division are integers, so the Z coordinate will be either -1 (if 2*i < NumSlices) or 0. (if 2*i >= NumSlices). If your near and far distances were 0 and 1, it's conceivable that both sets of quads will be outside of the view volume.

Also, using a depth buffer with blending doesn't make much sense (blending effectively requires that you render from back to front, so depth testing isn't needed). Given that your alpha values are either zero or one, you might try using an alpha test instead of blending.

Other than that: have you tried calling glGetError() to check whether any errors occurred?