PDA

View Full Version : Cube Map without using OpenGL's Cube Mapping



someoney
02-09-2010, 03:50 PM
I'm requesting a bit of help since I cannot find what exactly is wrong with this bit of code. It seems to render the sphere in exactly one color.




/**
* \brief calcTexCoord2 The final step in calculating texture coordinates.
*
* \param texture The texture to use
* \param axis The value of the axis to use.
* \param s_coord The value to plug in for the s equation.
* \param t_coord The value to plug in for the t equation.
* \return Nothing.
*/

void calcTexCoord2(int texture, GLdouble axis, GLdouble s_coord, GLdouble t_coord) {

//cout << "axis: " << axis << " ";

GLdouble s, t; //texture coordinates

s = (s_coord + axis) / (2 * axis);
t = (t_coord + axis) / (2 * axis);

//cout << "axis: " << axis << " s_coord: " << s_coord << " t_coord: " << t_coord << " s: " << s << " t: " << t << endl;
//cout.flush();

glBindTexture(GL_TEXTURE_2D, texture_name[texture]);
glTexCoord2f(s, t);

}

/**
* \brief calcTexCoord Inputs the texture coordinate at that point.
*
* \param vertex The vertex to calculate the texture coordinate for.
* Also, the assumption is that the vertex can be treated as the
* normal, since the sphere is of radius = 1 and centered at origin.
* \param viewer The view vector.
* \return Nothing.
*/

void calcTexCoord(GLdouble vertex[3], GLdouble *viewer) {

//cout << "normal: " << vertex[0] << ", " << vertex[1] << ", " << vertex[2] << " viewer: " << viewer[0] << ", " << viewer[1] << ", " << viewer[2];
//cout << " final: " << dist << endl;
//cout.flush();

//calc reflection vector via 2 * (n dot v) n - v
//start w/ n dot v
GLdouble dot_product = 0;

for (int i = 0; i < 3; i++)
dot_product += vertex[i]*viewer[i];

//2 * (n dot v)
dot_product *= 2;

//2 * (n dot v) n - v
GLdouble reflect[3];
for (int i = 0; i < 3; i++)
reflect[i] = (dot_product * vertex[i]) - viewer[i];

//find the texture to use
int index = 0;
for (int i = 1; i < 3; i++)
if (fabs(reflect[index]) < fabs(reflect[i]))
index = i;

switch (index) {

case 0:
if (reflect[index] > 0) //+x
calcTexCoord2(2, reflect[0], reflect[2], reflect[1]);
else
calcTexCoord2(3, reflect[0], reflect[2], reflect[1]);
break;
case 1:
if (reflect[index] > 0)
calcTexCoord2(0, reflect[1], reflect[0], reflect[2]);
else
calcTexCoord2(1, reflect[1], reflect[0], reflect[2]);
break;
case 2:
if (reflect[index] > 0)
calcTexCoord2(4, reflect[2], reflect[1], reflect[0]);
else
calcTexCoord2(5, reflect[2], reflect[1], reflect[0]);
}

}

/**
* \brief drawReflectivePole Draws the poles of the sphere using triangles.
* Borrowing the code from the book. This one is used
* for the reflective sphere.
* \param pole The pole that we are drawing.
* \param viewer The viewer vector
* \return Nothing.
*/

void drawReflectivePole(GLdouble **pole, GLdouble *viewer) {

glBegin(GL_TRIANGLE_FAN);
for (int i = 0; i < sphere_tri_strip_size; i++) {

calcTexCoord(pole[i], viewer);
glVertex3d(pole[i][0], pole[i][1], pole[i][2]);

}
glEnd();

}

/**
* \brief drawReflectiveSphere Draws a sphere (with reflection).
*
* \param viewer_x The viewer's x coordinate.
* \param viewer_y The viewer's y coordinate.
* \param viewer_z The viewer's z coordinate.
* \return Nothing.
*/

void drawReflectiveSphere(GLdouble viewer_x, GLdouble viewer_y, GLdouble viewer_z) {

if (sphere_quad_strip == NULL)
makeSphere();

//calc viewer vector
GLdouble distance = sqrt(viewer_x*viewer_x + viewer_y*viewer_y + viewer_z*viewer_z);
GLdouble viewer[] = { viewer_x / distance, viewer_y / distance, viewer_z / distance};

glBegin(GL_QUAD_STRIP);

for (int i = 0; i < sphere_quad_strip_size; i++) {

glNormal3dv(sphere_quad_strip[i]);
calcTexCoord(sphere_quad_strip[i], viewer);
glVertex3dv(sphere_quad_strip[i]);

}

glEnd();

drawReflectivePole(sphere_top_tri_strip, viewer);
drawReflectivePole(sphere_bottom_tri_strip, viewer);

}


Basically, I'm rendering a sphere, texturing it with a cube map. Since the distance from the origin of all the vertexes are exactly 1, I treat the vertexes the same as the normal.

I'm certain there is a bunch of error in my assignment of the coordinates to calcTexCoord2, but I still cannot see why the sphere is rendered in exactly one color.

Thank you for any help you may provide.

Rosario Leonardi
02-09-2010, 04:57 PM
I still don't understand why people want to program in C++ without using classes.

You have viewer position and I assume that the sphere is in the origin and your camera always point to the origin.
Here the first strange thing... you compute the direction only once.
The reflection direction is typically intended per vertex, so should be computer for every vertexes.
Direction should be the direction of the vertexPos-cameraPos vector.
Yes.. it's quite slow, that's why people use shaders (or fixed hardware implementation).
But this don't justify the uniform color.
I didn't check all the math but it seem ok, the real blunder is that you are trying to switch texture (glBindTexture) inside a glBegin glEnd block.

One trivial solution can be to put everything in a big texture and make an extra computation to find the final uv. But this will lead to terrible artifact on the image borders.

I can't find any easy solution, maybe you can set the texture border to transparent and use a multipass algorithm.

someoney
02-10-2010, 01:05 PM
Thank you for your response.

I've changed the code to implement the correct calculations for the reflection vector, but the shade color is still in one color.

I believe the reason why is exactly as you stated: glBindTexture cannot be used within the glBegin and glEnd block. I will probably have to find a different way of implementing this step.

Thank you!