PDA

View Full Version : Mapping 3D float intensity values on a cube



kalamaki
06-18-2013, 01:27 AM
Hi,

I have a 3D matrix of floating point intensity values that I want to map on a cube in order to render them on my screen, and apply rotations, translations, using MIP projection. From what I have seen in tutorials, I got the following code (in Python):


def LoadGLTextures(fname):
# Load Texture
image1 = loadImage(fname)
# Create Textures
texture = glGenTextures(1)

# Linear interpolation
glBindTexture(GL_TEXTURE_3D, texture)
#glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE )
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE )
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE )
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR )
glTexParameterf( GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR )
glTexImage3D(GL_TEXTURE_3D,0,GL_LUMINANCE,image1.s izeX,image1.sizeY,image1.sizeZ,0, GL_LUMINANCE,GL_FLOAT,image1.data)

return texture

def DrawGLScene(self):
#With resize, we already are in MODELVIEW mode

#Clear the buffers we will write into
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

#Reinitialize all the transformations (previous are cancelled)
glLoadIdentity()

#Defines which one of the textures we are going to use
glBindTexture(GL_TEXTURE_3D, self.textures)

#My object is defined by the coordinates [-1,1;-1,1;-1,1]
#Zero is the center, and I am in orhographic projection, so no in depth
#translation needed
glTranslatef(0.0,0.0,0.0)

#Rotate the volume
glRotatef(self.yzrotation,1.0,0.0,0.0)
glRotatef(self.xzrotation,0.0,1.0,0.0)
glRotatef(self.xyrotation,0.0,0.0,1.0)



#My "cube" is defined by 6 independent faces, that I assemble like a
#cube.

glBegin(GL_QUADS)

glNormal3f(0.0,0.0,1.0)
glTexCoord3f(0.99,0.99,0.99)
glVertex3f(0.99,0.99,0.99)
glTexCoord3f(-0.99,0.99,0.99)
glVertex3f(-0.99,0.99,0.99)
glTexCoord3f(-0.99,-0.99,0.99)
glVertex3f(-0.99,-0.99,0.99)
glTexCoord3f(0.99,-0.99,0.99)
glVertex3f(0.99,-0.99,0.99)

glNormal3f(0.0,0.0,-1.0)
glTexCoord3f(0.99,0.99,-0.99)
glVertex3f(0.99,0.99,-0.99)
glTexCoord3f(-0.99,0.99,-0.99)
glVertex3f(-0.99,0.99,-0.99)
glTexCoord3f(-0.99,-0.99,-0.99)
glVertex3f(-0.99,-0.99,-0.99)
glTexCoord3f(0.99,-0.99,-0.99)
glVertex3f(0.99,-0.99,-0.99)

glNormal3f(0.0,1.0,0.0)
glTexCoord3f(0.99,0.99,0.99)
glVertex3f(0.99,0.99,0.99)
glTexCoord3f(-0.99,0.99,0.99)
glVertex3f(-0.99,0.99,0.99)
glTexCoord3f(-0.99,0.99,-0.99)
glVertex3f(-0.99,0.99,-0.99)
glTexCoord3f(0.99,0.99,-0.99)
glVertex3f(0.99,0.99,-0.99)

glNormal3f(0.0,-1.0,0.0)
glTexCoord3f(0.99,-0.99,0.99)
glVertex3f(0.99,-0.99,0.99)
glTexCoord3f(-0.99,-0.99,0.99)
glVertex3f(-0.99,-0.99,0.99)
glTexCoord3f(-0.99,-0.99,-0.99)
glVertex3f(-0.99,-0.99,-0.99)
glTexCoord3f(0.99,-0.99,-0.99)
glVertex3f(0.99,-0.99,-0.99)

glNormal3f(1.0,0.0,0.0)
glTexCoord3f(0.99,0.99,0.99)
glVertex3f(0.99,0.99,0.99)
glTexCoord3f(0.99,-0.99,0.99)
glVertex3f(0.99,-0.99,0.99)
glTexCoord3f(0.99,-0.99,-0.99)
glVertex3f(0.99,-0.99,-0.99)
glTexCoord3f(0.99,0.99,-0.99)
glVertex3f(0.99,0.99,-0.99)

glNormal3f(-1.0,0.0,0.0)
glTexCoord3f(-0.99,0.99,0.99)
glVertex3f(-0.99,0.99,0.99)
glTexCoord3f(-0.99,-0.99,0.99)
glVertex3f(-0.99,-0.99,0.99)
glTexCoord3f(-0.99,-0.99,-0.99)
glVertex3f(-0.99,-0.99,-0.99)
glTexCoord3f(-0.99,0.99,-0.99)
glVertex3f(-0.99,0.99,-0.99)

glEnd()

My problem is that the texture is represented 4 times when rendered : https://www.dropbox.com/s/odwgcpsej9kmy88/capture.png, and I don't understand why.

Could you help me with this?


Thanks! :-)

tonyo_au
06-18-2013, 03:01 AM
I would have thought each of you uvw values would range from 0-1 and you would not use wrapping

Also have a look at this http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/.

kalamaki
06-18-2013, 03:39 AM
Thanks for your answer, that was indeed part of the problem.

Another problem came from the fact that I was using textures of the size 256x256x64. By making the texture 256x256x256 (padding with zeros), the volume was only rendered once.

Are those "cubic" textures mandatory? It seems like I have to use four times more memory...

Thanks!

tonyo_au
06-18-2013, 07:06 AM
I don't know - I would not think so but someone else might be able to answer

GClements
06-18-2013, 07:59 AM
Another problem came from the fact that I was using textures of the size 256x256x64. By making the texture 256x256x256 (padding with zeros), the volume was only rendered once.
That suggests that you're reading the data incorrectly.

If you're using the data to texture a cube, using any form of 3D texture is overkill, as only the edges at the boundaries will be used. You'd be better off extracting the faces into 6 2D textures: 2 256x256 textures and 4 256x64 textures = 192k texels, as opposed to 256x256x64 = 4096k texels.

If you're actually trying to render voxel data (it looks like an MRI scan or similar), you shouldn't be rendering a cube, but e.g. rendering 64 parallel squares using additive blending.