PDA

View Full Version : opengl won't map textures



OffbeatPatriot
03-25-2009, 12:38 AM
I'm trying to make a program to view 3d volumes. Basically you start with a bunch of data from an ultra sound or mri and then you load it into a 3d texture. Then you have a cursor made of three components between 0 and 1, and when you draw the display you take three slices of the 3d texture, all perpendicular planes that intersect at the cursor which you can move around by clicking and dragging the cursor on one of the planes displayed on the screen. Problem is that I draw the cursor as a cross hair over each plane, red lines in the x direction, green in the y direction, and blue in the z direction, and the quads I try to map the 3d texture slices on to are simply the color of the last cross hair line I drew. In the interest of keeping things simple I'll just try to post the minimal code to understand the situation.

The program uses wxWidgets and I basically have a frame that can hold multiple Volume objects in tabs. This is some of the code in the Volume constructor. The View objects represent the different views of the volume and their second arguments tell them what direction they are to look in. Also texture is a public member of Volume and raw_file_name and dimensions were read from the text file file_name describes.

Volume::Volume(const wxString& file_name, wxFrame *frame, wxWindow *parent, bool power_of_two) : wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, file_name)
{
unsigned char * data;
...
...
ifstream file(raw_file_name.c_str(), ios::in|ios::binary);
data = new unsigned char[dimensions[0] * dimensions[1] * dimensions[2]];
file.read((char *)data, dimensions[0] * dimensions[1] * dimensions[2]);
texture_dimensions[0] = dimensions[0];
texture_dimensions[1] = dimensions[1];
texture_dimensions[2] = dimensions[2];
}
file.close();

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, <strong class="highlight">texture</strong>);
glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE, texture_dimensions[0], texture_dimensions[1], texture_dimensions[2], 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
delete []data;
...
...
xy_view = new View(this, Z_PLANE);
xz_view = new View(this, Y_PLANE);
yz_view = new View(this, X_PLANE);
}

This function gets gets called when the Volume redraws itself

void Volume::on_paint(wxPaintEvent &amp;event)
{
SetCurrent();
wxPaintDC(this);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();

glViewport(0, 0, (GLint)GetSize().x, (GLint)GetSize().y);
glOrtho(0, (GLint)GetSize().x, 0, (GLint)GetSize().y, -1.0, 1.0);

glBindTexture(GL_TEXTURE_3D, <strong class="highlight">texture</strong>);
xy_view->draw();
xz_view->draw();
yz_view->draw();

glFlush();
SwapBuffers();
}

and this is the draw function for the Views. Note, parent points to the volume.

void View::draw()
{
glEnable(GL_TEXTURE_3D);
glBegin(GL_QUADS);
if(view == X_PLANE)
{
glTexCoord3d(parent->cursor[0], 0, 0);
glVertex3d(volume_x, volume_y, 0);

glTexCoord3d(parent->cursor[0], 0, parent->texture_dimensions[2]);
glVertex3d(volume_x + volume_w, volume_y, 0);

glTexCoord3d(parent->cursor[0], parent->texture_dimensions[1], parent->texture_dimensions[2]);
glVertex3d(volume_x + volume_w, volume_y + volume_h, 0);

glTexCoord3d(parent->cursor[0], parent->texture_dimensions[1], 0);
glVertex3d(volume_x, volume_y + volume_h, 0);
}
else if(view == Y_PLANE)
{
glTexCoord3d(0, parent->cursor[1], 0);
glVertex3d(volume_x, volume_y, 0);

glTexCoord3d(parent->texture_dimensions[0], parent->cursor[1], 0);
glVertex3d(volume_x + volume_w, volume_y, 0);

glTexCoord3d(parent->texture_dimensions[0], parent->cursor[1], parent->texture_dimensions[2]);
glVertex3d(volume_x + volume_w, volume_y + volume_h, 0);

glTexCoord3d(0, parent->cursor[1], parent->texture_dimensions[2]);
glVertex3d(volume_x, volume_y + volume_h, 0);
}
else if(view == Z_PLANE)
{
glTexCoord3d(0, 0, parent->cursor[2]);
glVertex3d(volume_x, volume_y, 0);

glTexCoord3d(parent->texture_dimensions[0], 0, parent->cursor[2]);
glVertex3d(volume_x + volume_w, volume_y, 0);

glTexCoord3d(parent->texture_dimensions[0], parent->texture_dimensions[1], parent->cursor[2]);
glVertex3d(volume_x + volume_w, volume_y + volume_h, 0);

glTexCoord3d(0, parent->texture_dimensions[1], parent->cursor[2]);
glVertex3d(volume_x, volume_y + volume_h, 0);
}
glEnd();
glDisable(GL_TEXTURE_3D);

glBegin(GL_LINES);
if(view == X_PLANE)
{
glColor3f(0,0,1);
glVertex3d(base_x, cursor[1], 0);
glVertex3d(base_x + parent->view_size, cursor[1], 0);
glColor3f(0,1,0);
glVertex3d(cursor[0], base_y, 0);
glVertex3d(cursor[0], base_y + parent->view_size, 0);
}
else if(view == Y_PLANE)
{
glColor3f(1,0,0);
glVertex3d(base_x, cursor[1], 0);
glVertex3d(base_x + parent->view_size, cursor[1], 0);
glColor3f(0,0,1);
glVertex3d(cursor[0], base_y, 0);
glVertex3d(cursor[0], base_y + parent->view_size, 0);
}
else if(view == Z_PLANE)
{
glColor3f(1,0,0);
glVertex3d(base_x, cursor[1], 0);
glVertex3d(base_x + parent->view_size, cursor[1], 0);
glColor3f(0,1,0);
glVertex3d(cursor[0], base_y, 0);
glVertex3d(cursor[0], base_y + parent->view_size, 0);
}
glEnd();
}

Here's a picture too
http://img.photobucket.com/albums/v4...er_problem.jpg

scratt
03-25-2009, 01:12 AM
Your photobucket link does not work, and your problem description is not that clear.

Please try to clarify it a bit or re-link the image.

OffbeatPatriot
03-26-2009, 12:50 PM
Perhaps I'll just ask this, how do I map a 3D texture?

In my constructor for an object I make the 3D texture. In my draw method before I draw my quads I call:

glBindTexture(GL_TEXTURE_3D, texture);
glEnable(GL_TEXTURE_3D);

in that order and when I'm done I call

glDisable(GL_TEXTURE_3D);

And yet nothing happens and my quads are just whatever color I last passed to glColour. What's more I've compiled and run this demo just fine.

http://gpwiki.org/index.php/OpenGL_3D_Textures

So I know 3D textures work and I'm frustrated because I think I'm doing exactly what the demo does and glGetErrors() just returns no error.

Also, I'm using glee(wglGetProcAddress returned null in my program), I wondered if that could be the problem but I plugged glee into the demo and it still worked.

dletozeun
03-26-2009, 03:16 PM
Your program looks right, maybe it is something with your data. You should try to debug and trace your program and check if all is right or write a simpler test program (Maybe starting from the gpwiki demo).

ZbuffeR
03-26-2009, 04:36 PM
The default texturing requires mipmaps to be complete. if you don't want mipmaps, specify GL_LINEAR as min filter.

OffbeatPatriot
03-27-2009, 08:43 PM
I have this before I call glTexImage3D

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

And I get the same results.

Recently I tried this, in my drawing method I put this code and a breakpoint, I also made data a member of the object. Note, 700, 92, 1351 are the dimensions of the volume I'm trying look at.

unsigned char *test = new unsigned char[700*92*1351];
glGetTexImage(GL_TEXTURE_3D, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, test);
data;

I wonder if this is suggesting a problem or if I'm incorrectly using glGetTexImage. data looks normal, when I mouse over it(I'm using visual studio 2008) I see it points to a really long string of characters, however test is a string but it's filled with fs, that is.

data = "fdjig945t;gj'atgi0439tuv4btatu4896yvat;/'ty0[3wg..."
test = "ffffffffffffffffffffffffffffffffffffffffffffffff.. ."

I'm assuming that test should contain the same thing as data.