PDA

View Full Version : calculating viewing angle & back-to-front ordering



torisutan
07-21-2003, 02:18 AM
Hi, I'm trying to render a slice stack (later for use in volume rendering) in back-to-front order dependant of the viewing angle.

I have managed to get the basis down, but the code i have is quite buggy.

The main problem is that my tests for which order the slices should be rendered in does not always work properly, and sometimes returns front-to-back ordering, or doesn't pick up that it should change the ordering at certain angles.

At first i thought this may be due to Gimbal lock, but upon using quaternions the problem has not been fixed. So i assume it is an error somewhere in my calculations.

can anyone possibly shead some light for me?

Thanks
--Tristan

Note: i built this code from the psuedo code from the Course notes of this site
http://www.cs.utah.edu/~jmk/sigg_crs_02/courses_0067.html




void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f);
CQuat test;
test.eulerToQuat(ogld::COpenGLDriver::getInstance( )->camera_rotation.x, ogld::COpenGLDriver::getInstance()->camera_rotation.y, ogld::COpenGLDriver::getInstance()->camera_rotation.z);
glMultMatrixf(test.quatToMatrix().array);

GLdouble pModelViewMatrix[16];
GLdouble pModelViewRotationMatrix[16];
// obtain the current modeling/viewing matrix from the OpenGL state
glGetDoublev(GL_MODELVIEW_MATRIX, pModelViewMatrix);

// GetRotation( pModelViewMatrix, pModelViewRotationMatrix );
pModelViewRotationMatrix[0] = pModelViewMatrix[0];
pModelViewRotationMatrix[1] = pModelViewMatrix[1];
pModelViewRotationMatrix[2] = pModelViewMatrix[2];
pModelViewRotationMatrix[4] = pModelViewMatrix[4];
pModelViewRotationMatrix[5] = pModelViewMatrix[5];
pModelViewRotationMatrix[6] = pModelViewMatrix[6];
pModelViewRotationMatrix[8] = pModelViewMatrix[8];
pModelViewRotationMatrix[9] = pModelViewMatrix[9];
pModelViewRotationMatrix[10] = pModelViewMatrix[10];
pModelViewRotationMatrix[15] = 1;

// rotate the initial viewing direction
GLdouble pViewVector[3] = {0.0f, 0.0f, -1.0f};

// MatVecMultiply(pModelViewRotationMatrix, pViewVector);
GLdouble temp[3];
pViewVector[0] = pModelViewRotationMatrix[8]*pViewVector[2];
pViewVector[1] = pModelViewRotationMatrix[9]*pViewVector[2];
pViewVector[2] = pModelViewRotationMatrix[10]*pViewVector[2];

temp[0] = fabs(pViewVector[0]);
temp[1] = fabs(pViewVector[1]);
temp[2] = fabs(pViewVector[2]);

// find the maximal vector component
int index = -1;
if (temp[0] < temp[1]) {
if (temp[1] < temp[2])
index = 2;
else
index = 1;
} else {
if (temp[0] < temp[2])
index = 2;
else
index = 0;
}

int slices = 32;

glBegin(GL_QUADS);

if (index == 0)
{
glColor3f(1.0f, 0.0f, 0.0f);

if (pViewVector[0] < 0.0f) {

std::cout << "x:+\n";
// draw slice stack positive x
for (float f = 1.0f ; f > -1.0f ; f -= 2.0f/slices) {
glVertex3f(f, -1.0f, -1.0f);
glVertex3f(f, -1.0f, 1.0f);
glVertex3f(f, 1.0f, 1.0f);
glVertex3f(f, 1.0f, -1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
}

} else {

std::cout << "x:-\n";
// draw slice stack negative x
for (float f = -1.0f ; f < 1.0f ; f += 2.0f/slices) {
glVertex3f(f, -1.0f, -1.0f);
glVertex3f(f, -1.0f, 1.0f);
glVertex3f(f, 1.0f, 1.0f);
glVertex3f(f, 1.0f, -1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
}
}


}
else if (index == 1)
{
glColor3f(1.0f, 0.0f, 0.0f);

if (pViewVector[1] < 0.0f) {

std::cout << "y:+\n";
for (float f = 1.0f ; f > -1.0f ; f -= 2.0f/slices) {
glVertex3f(-1.0f, f, -1.0f);
glVertex3f(-1.0f, f, 1.0f);
glVertex3f( 1.0f, f, 1.0f);
glVertex3f( 1.0f, f, -1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
}

} else {

std::cout << "y:-\n";
for (float f = -1.0f ; f < 1.0f ; f += 2.0f/slices) {
glVertex3f(-1.0f, f, -1.0f);
glVertex3f(-1.0f, f, 1.0f);
glVertex3f( 1.0f, f, 1.0f);
glVertex3f( 1.0f, f, -1.0f);
glColor3f(1.0f, 1.0f, 1.0f);
}
}
}
else if (index == 2)
{
glColor3f(1.0f, 0.0f, 0.0f);

if (pViewVector[2] > 0.0f) {

std::cout << "z:+\n";
for (float f = 1.0f ; f > -1.0f ; f -= 2.0f/slices) {
glVertex3f(-1.0f, -1.0f, f);
glVertex3f( 1.0f, -1.0f, f);
glVertex3f( 1.0f, 1.0f, f);
glVertex3f(-1.0f, 1.0f, f);
glColor3f(1.0f, 1.0f, 1.0f);
}

} else {

std::cout << "z:-\n";
for (float f = -1.0f ; f < 1.0f ; f += 2.0f/slices) {
glVertex3f(-1.0f, -1.0f, f);
glVertex3f( 1.0f, -1.0f, f);
glVertex3f( 1.0f, 1.0f, f);
glVertex3f(-1.0f, 1.0f, f);
glColor3f(1.0f, 1.0f, 1.0f);
}
}
}

glEnd();
}

Rog
07-21-2003, 05:22 AM
If it helps - here's the code that I use to determine which stack to render and in what order (the enums should be self-explanatory) -


C2DRenderer::RenderOrder C2DRenderer::GetRenderingOrder()
{
// determine rendering order based on current view
float fMatrix[16];
RenderOrder nOrder;

// get current modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX, fMatrix);

//find the plane opposite the viewer
if (fabs(fMatrix[2]) > fabs(fMatrix[6]))
{
if (fabs(fMatrix[2]) > fabs(fMatrix[10]))
{
//X is largest
if (fMatrix[2] > 0.0f)
nOrder = RO_X_FRONT_TO_BACK;
else
nOrder = RO_X_BACK_TO_FRONT;
}
else
{
//Z is largest
if (fMatrix[10] > 0.0f)
nOrder = RO_Z_FRONT_TO_BACK;
else
nOrder = RO_Z_BACK_TO_FRONT;
}
}
else
{
if (fabs(fMatrix[6]) > fabs(fMatrix[10]))
{
//Y is largest
if (fMatrix[6] > 0.0f)
nOrder = RO_Y_FRONT_TO_BACK;
else
nOrder = RO_Y_BACK_TO_FRONT;
}
else
{
//Z is largest
if (fMatrix[10] > 0.0f)
nOrder = RO_Z_FRONT_TO_BACK;
else
nOrder = RO_Z_BACK_TO_FRONT;
}
}

// return result
return nOrder;
}

Any use?

torisutan
07-21-2003, 05:04 PM
thanks Rog
works beautifully ^_^

--Tristan