OffbeatPatriot 5 Junior Poster in Training

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, texture);
	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 &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, texture);
	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/v493/OffbeatPatriot/volume_viewer_problem.jpg

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.