PDA

View Full Version : OpenGL Problem: Camera won't rotate around cube & screen doesn't refresh




RPGamerL99
Mar 10, 2008, 05:18 PM
I made this with Xcode 3, running Santa Rosa MacBook. All the frameworks and such are linked properly. When I run the code, the window pops up, but the screen is white. When I move another window over it or bring up widgets, it seems to refresh the screen and i can see the cube. The second problem is that the camera is supposed to rotate around the cube but doesn't, it seems to only call glutDisplayFunc once.

I gave my teacher my code, and he ran it on his Linux environment and it worked fine. I don't understand what is happening. I can run a simple program I have just displaying a square, so i know how to compile OpenGL code correctly. Any help?


double transform_eyex()
{
tempx = (cos(theta) * eyex) + (sin(theta) * eyez);
return tempx;
}

double transform_eyez()
{
tempz = (-sin(theta) * eyex) + (cos(theta) * eyez);
return tempz;
}

void display(void)
{
theta += 0.1;
eyex = transform_eyex();
eyez = transform_eyez();

// set up new view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, 1.0, 1.0, 10000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(eyex, 5.0, eyez, //eye
0.0, 0.0, 0.0, //target
0.0, 1.0, 0.0); // up

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw triangles
draw_cube_face();
draw_cube_back();

glFlush();
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("cube");
init_mod();
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutIdleFunc(glutPostRedisplay);
glutMainLoop();
}



lazydog
Mar 10, 2008, 05:26 PM
Hi

Is it a glut program? If it is then it sounds like you may have missed putting GLUT_DOUBLE in your glutInitDisplayMode() call.

How about posting some code, I'm sure you'll get a lot of help from the folks here.

EDIT: Ah your code has magically appeared!

b e n

lazydog
Mar 10, 2008, 05:37 PM
Hi I think the problem to do with the white screen is because you haven't set the colour before you clear the screen. I guess white is left over from drawing your cube… can't tell because you haven't included that bit of code.
So try:-


glClearColor( 0.0, 0.0, 0.0, 0.0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


b e n

lazydog
Mar 10, 2008, 05:55 PM
Just tried your program. Put my own model stuff in and it works ok, though I did take out your eye transformations and used glRotate() instead. By the way, I think it best that you use the gl transformations instead of doing them yourself.

b e n

RPGamerL99
Mar 10, 2008, 05:57 PM
This is my whole program:

#include <GLUT/glut.h> /* includes gl.h and glu.h for Mac OS X */
#include <math.h>

int edgeLen = 1;
GLfloat x1[13] = {-0.5, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};
GLfloat x2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};

GLfloat yy[13] = {-0.5, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};
GLfloat y2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};

GLfloat z1[13] = {0.5, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};
GLfloat z2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0};
double eyex = 5.0;
double eyez = 5.0;
double tempx = 0.0;
double tempz = 0.0;
double theta = 0.1;

/*
Calculates points of the cube given the bottom left
point on the front face of the cube and the length of
the sides. Stores points in arrays for future use.
*/
void init_mod()
{
int sidesDrawn = 0;
int axis1 = 0;
int axis2 = 1;
int loc = 1;
int m, n, q, r;

for(n = 0; n < 3; n++)
{
for(m = 0; m < 2; m++)
{
switch (axis1) {
case 0:
x1[loc] = x1[0] + edgeLen;
yy[loc] = yy[0];
z1[loc] = z1[0];
break;
case 1:
x1[loc] = x1[0];
yy[loc] = yy[0] + edgeLen;
z1[loc] = z1[0];
break;
case 2:
x1[loc] = x1[0];
yy[loc] = yy[0];
z1[loc] = z1[0] - edgeLen;
break;
}
loc++;

switch (axis2) {
case 0:
x1[loc] = x1[loc - 1] + edgeLen;
yy[loc] = yy[loc - 1];
z1[loc] = z1[loc - 1];
break;
case 1:
x1[loc] = x1[loc - 1];
yy[loc] = yy[loc - 1] + edgeLen;
z1[loc] = z1[loc - 1];
break;
case 2:
x1[loc] = x1[loc - 1];
yy[loc] = yy[loc - 1];
z1[loc] = z1[loc - 1] - edgeLen;
break;
}
loc++;

axis2 = axis1;
axis1 = (axis1 + 1) % 3;
}

if(axis2 == 0){ //------------------------------
axis2 = 2;} // reverse "(changept2 + 1) % 3"
else{axis2--;} //------------------------------
}

x2[0] = x1[0] + edgeLen;
y2[0] = yy[0] + edgeLen;
z2[0] = z1[0] - edgeLen;
loc = 1;
axis1 = 0;
axis2 = 1;

for(q = 0; q < 3; q++)
{
for(r = 0; r < 2; r++)
{
switch (axis1) {
case 0:
x2[loc] = x2[0] - edgeLen;
y2[loc] = y2[0];
z2[loc] = z2[0];
break;
case 1:
x2[loc] = x2[0];
y2[loc] = y2[0] - edgeLen;
z2[loc] = z2[0];
break;
case 2:
x2[loc] = x2[0];
y2[loc] = y2[0];
z2[loc] = z2[0] + edgeLen;
break;
}
loc++;

switch (axis2) {
case 0:
x2[loc] = x2[loc - 1] - edgeLen;
y2[loc] = y2[loc - 1];
z2[loc] = z2[loc - 1];
break;
case 1:
x2[loc] = x2[loc - 1];
y2[loc] = y2[loc - 1] - edgeLen;
z2[loc] = z2[loc - 1];
break;
case 2:
x2[loc] = x2[loc - 1];
y2[loc] = y2[loc - 1];
z2[loc] = z2[loc - 1] + edgeLen;
break;
}
loc++;

axis2 = axis1;
axis1 = (axis1 + 1) % 3;
}

if(axis2 == 0){ //------------------------------
axis2 = 2;} // reverse "(changept2 + 1) % 3"
else{axis2--;} //------------------------------
}
}

/*
Draws the 3 faces that touch the front bottom left corner
*/
void draw_cube_face()
{
int sidesDrawn1 = 0;
int i;
int a = 0;
float color1[3] = {1.0, 0.0, 0.0};
float color2[3] = {0.0, 1.0, 0.0};
float color3[3] = {0.0, 0.0, 1.0};

while(sidesDrawn1 < 3)
{
glColor3f(color1[sidesDrawn1], color2[sidesDrawn1], color3[sidesDrawn1]);

for(i = 0; i < 2; i++) // allows both triangles on one side to be drawn
{
glBegin(GL_TRIANGLES);
glVertex3f(x1[0], yy[0], z1[0]);
a++;
glVertex3f(x1[a], yy[a], z1[a]);
a++;
glVertex3f(x1[a], yy[a], z1[a]);
glEnd;
}
sidesDrawn1++;
}
}

/*
Draws the 3 faces that touch the back upper right corner
*/
void draw_cube_back()
{
int sidesDrawn2 = 0;
int k;
int a = 0;
float color1[3] = {1.0, 0.0, 0.0};
float color2[3] = {0.0, 1.0, 0.0};
float color3[3] = {0.0, 0.0, 1.0};

while(sidesDrawn2 < 3)
{
glColor3f(color1[sidesDrawn2], color2[sidesDrawn2], color3[sidesDrawn2]);

for(k = 0; k < 2; k++) // allows both triangles on one side to be drawn
{
glBegin(GL_TRIANGLES);
glVertex3f(x2[0], y2[0], z2[0]);
a++;
glVertex3f(x2[a], y2[a], z2[a]);
a++;
glVertex3f(x2[a], y2[a], z2[a]);
glEnd;
}
sidesDrawn2++;
}
}

double transform_eyex()
{
tempx = (cos(theta) * eyex) + (sin(theta) * eyez);
return tempx;
}

double transform_eyez()
{
tempz = (-sin(theta) * eyex) + (cos(theta) * eyez);
return tempz;
}

void display(void)
{
theta += 0.1;
eyex = transform_eyex();
eyez = transform_eyez();

// set up new view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, 1.0, 1.0, 10000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

gluLookAt(eyex, 5.0, eyez, //eye
0.0, 0.0, 0.0, //target
0.0, 1.0, 0.0); // up

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw triangles
draw_cube_face();
draw_cube_back();

glFlush();
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("cube");
init_mod();
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(display);
glutIdleFunc(glutPostRedisplay);
glutMainLoop();
}

I will try your suggestions.
Thanks =)

RPGamerL99
Mar 10, 2008, 06:02 PM
Just tried your program. Put my own model stuff in and it works ok, though I did take out your eye transformations and used glRotate() instead. By the way, I think it best that you use the gl transformations instead of doing them yourself.

b e n

I tried the glClearColor but it didn't help. I have to rotate the camera myself because its part of the assignment in my graphics class. it's very weird that you were able to compile it and also my teacher, but I get these weird problems...

Animalk
Mar 10, 2008, 06:37 PM
try putting "glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);" before any line of code in the display function. Or at least before any gl or glut function calls in the display function.

lazydog
Mar 10, 2008, 07:00 PM
Ah, I see something wrong… you have glEnd; instead of glEnd() ;


b e n

EDIT: The reason why it worked earlier for me was because I'd replaced your draw routines with ones that didn't have your typo!

RPGamerL99
Mar 10, 2008, 07:13 PM
Ah, I see something wrong… you have glEnd; instead of glEnd() ;


b e n

EDIT: The reason why it worked earlier for me was because I'd replaced your draw routines with ones that didn't have your typo!

OMG, YOU ARE A GENIUS!

THANK YOU =D I don't believe I missed that!

kainjow
Mar 10, 2008, 07:29 PM
Ah, I see something wrong… you have glEnd; instead of glEnd() ;


b e n

EDIT: The reason why it worked earlier for me was because I'd replaced your draw routines with ones that didn't have your typo!

How would that have gotten past the compiler? is glEnd defined as something else?

admanimal
Mar 10, 2008, 07:35 PM
How would that have gotten past the compiler? is glEnd defined as something else?

The name of a variable or function is a legal statement in C.

kainjow
Mar 10, 2008, 07:43 PM
The name of a variable or function is a legal statement in C.

Thanks. I think it's weird though. When would this ever be useful?

RPGamerL99
Mar 10, 2008, 07:50 PM
Now that it works correctly, I now realize my transformations are off lol If anyone wants to give hints on how to fix it, that would be great. I will try to correct the transformations now.

lazydog
Mar 10, 2008, 07:54 PM
Thanks. I think it's weird though. When would this ever be useful?

I may be wrong about this, but I think you can drop opcodes, or data, into your code this way.

b e n

RPGamerL99
Mar 10, 2008, 08:00 PM
Now that it works correctly, I now realize my transformations are off lol If anyone wants to give hints on how to fix it, that would be great. I will try to correct the transformations now.

nevermind, I figured it out! cube spins perfect and gracefully now =)

thanks for the help!

lazydog
Mar 10, 2008, 08:08 PM
Now that it works correctly, I now realize my transformations are off lol If anyone wants to give hints on how to fix it, that would be great. I will try to correct the transformations now.


Had a quick look at your transformations. I think the problem is you are using an incremental transformation for the eye coordinates, but you update theta as though it is an absolute angle. Try:-


void display(void)
{
// theta = 0.1; changed to...
theta = 0.01 ;


This way, you are rotating the camera by 0.01 radians each frame. The way you had it before, your were rotating the camera each frame by ever increasing amounts.

An easier way though would be to calculate the eye coordinates from theta and a radius. The radius is the distance of the camera from the centre of your scene.

b e n

Krevnik
Mar 10, 2008, 08:48 PM
I may be wrong about this, but I think you can drop opcodes, or data, into your code this way.

b e n

It is how you get a function pointer. :)

glEnd is a pointer to a function.
glEnd() calls the function given by the pointer 'glEnd'. :)

EDIT: Note that this is short-hand in C/C++ rather than the desirable way to do it.

kainjow
Mar 10, 2008, 09:00 PM
It is how you get a function pointer. :)

glEnd is a pointer to a function.
glEnd() calls the function given by the pointer 'glEnd'. :)

But why is glEnd; a valid statement? When would this ever be necessary to have a statement doing nothing?

Krevnik
Mar 10, 2008, 09:44 PM
But why is glEnd; a valid statement? When would this ever be necessary to have a statement doing nothing?

Because it simply is. :)

A statement that is 100% empty (';' by itself for example) is perfectly valid. As are statements that don't assign. Without this, void function calls become complex for the compiler to handle as it adds rules that you need to keep track of.

To help people write good code isn't always the same thing as keeping the compiler simple. In this case, it was simpler to let statements that don't assign exist, to handle void function calls, statements that do something yet don't assign, and so on, then it was to create an error out of 'functionNameHere;'

EDIT: To be clear, I wouldn't say I don't think the design has its problems, but at the time C was being designed, they were thinking about how to make the parser efficient and small... and not so much on how they could make the programmer's job easier.

lazydog
Mar 11, 2008, 05:53 AM
It is how you get a function pointer. :)

glEnd is a pointer to a function.
glEnd() calls the function given by the pointer 'glEnd'. :)

EDIT: Note that this is short-hand in C/C++ rather than the desirable way to do it.

Oops… I was talking rubbish (again), :) It was very late last night though!

b e n