PDA

View Full Version : Simple object not showing up



fx_beginner
01-13-2008, 04:38 PM
Hello,

I have a slight issue: I'm trying to draw a gradient in the background of an OpenGL scene. To do that, the first thing I draw is a GL_QUADS with four vertices of different colours. Now, the tricky thing is that this gradient doesn't appear on screen, unless there has previously been a call to gluSphere(), even if the sphere is of size zero (I discovered that because I "debugged" the problem by marking the origin of the coordinate system with a sphere).

So, I'm thinking I am probably missing a call to some gl* function, that gluSphere() makes; but I can't figure out *what* call I'm missing (and I've fiddle a bit with ktrace, but that didn't help). So, here's my code: if you comment out the call to gluSphere(), the gradient doesn't show up any more. Does that ring a bell to someone? Many thanks.



glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (-1, 1, -1, 1, -10, 10);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();

glClearColor (0, 0, 0, 1);
glShadeModel (GL_SMOOTH);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
GLfloat mat_shininess[] = { 50.0 };
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
GLfloat light_ambient[] = { 1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
GLfloat light_position[] = { -3.0, -3.0, 10.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

GLUquadric * s = gluNewQuadric();
gluSphere (s, 0.0, 2, 1);
gluDeleteQuadric (s);

glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Draw the gradient
glBegin (GL_QUADS);
float color1[4] = { 0.4, 0.4, 0.4, 1.0 };
float color2[4] = { 0.9, 0.9, 0.9, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color2);
glVertex3f ( x, -y, -9.9);
glVertex3f (-x, -y, -9.9);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color1);
glVertex3f (-x, y, -9.9);
glVertex3f ( x, y, -9.9);
glEnd ();

glFlush();

PS: I hope it's not something *too* common, but I've tried googling and reading and could not explain this.

Korval
01-13-2008, 04:53 PM
You may not call glMaterial* within glBegin/glEnd boundaries. This should give rise to a glError. You might want to download and use GL Intercept (http://glintercept.nutty.org/download.html), as it can spot these things easily enough.

If all you're trying to draw is a gradient, I don't know why you're turning on lighting at all. But assuming that you really want a lit quad for some reason, then what you need to do is use glColorfv instead of glMaterialfv, and use glColorMaterial (http://www.opengl.org/sdk/docs/man/xhtml/glColorMaterial.xml) to tell OpenGL to get the material color from the color, not the material parameter.

-NiCo-
01-13-2008, 05:01 PM
According to the spec:

Material properties can be changed inside a Begin/End pair by calling Ma-
terial. However, when a vertex shader is active such property changes are not
guaranteed to update material parameters, defined in table 2.11, until the following
End command.


I tried your code and it seems to work, the gradient is just not noticeable. If you replace float color1[4] = { 0.4, 0.4, 0.4, 1.0 } with float color1[4] = { 0.0, 0.0, 0.0, 1.0 } you can see the gradient. Ow yeah, and the sphere doesn't change a thing.

N.

fx_beginner
01-13-2008, 05:53 PM
You may not call glMaterial* within glBegin/glEnd boundaries. This should give rise to a glError. You might want to download and use GL Intercept (http://glintercept.nutty.org/download.html), as it can spot these things easily enough.

Thanks for the diagnostics and link, I'll try it (no MacOS binaries, though, I'll try and get it compiled). I have switched to glColorfv() and glEnable(GL_COLOR_MATERIAL), though it didn't solve the problem.


If all you're trying to draw is a gradient, I don't know why you're turning on lighting at all.

I was working (wrongly) under the understanding that lighting was a global parameter to be set up first thing, and not changed afterwards. Apparently, this is not the case, and I have changed the call to enable lighting after the gradient quad is drawn. This got rid of the problem, though I'm don't understand why.

fx_beginner
01-13-2008, 05:58 PM
I tried your code and it seems to work, the gradient is just not noticeable. If you replace float color1[4] = { 0.4, 0.4, 0.4, 1.0 } with float color1[4] = { 0.0, 0.0, 0.0, 1.0 } you can see the gradient. Ow yeah, and the sphere doesn't change a thing.

Well, quite intringuing, then. A target-specific problem, then? (I'm using MacOS 10.4 and the Cocoa OpenGL framework.) In my case, the call to gluSphere() is definitely making things work, which don't otherwise. (And, for the gradient, I've checked with color pickers and using more contrated colours, and it's definitely not present when there is no call to gluSphere()).

Anyway, it's now working when I don't light the quad. Thanks to you and Korval for your help, I'll continue reading this board as I go on developing my OpenGL code (a molecular viewer/builder, so it requires little else than sphere and cylinders!), and hopefully will not have to bother you again with my questions (fingers crossed)!