   Lame shading/lighting effects
  Hello,I'm totally baffled about 2 things in OpenGL.  The first is the very lame shdaing and lighting effects that I get when building a visual object from scratch using triangles and quads as opposed to using quadrics which appear beautifully.The triangle and quads do respond to lights but very meagerly.  The entire surface, which is composed of many polygons at various angles to the light, all get rendered with the same shading.I've enabled (I believe) normals, smooth shading and gave the primitives suitable material properties.  What's missing?  Here's a snippet of code:   GLfloat ambientColor[]  = { 0.6, 0.75, 0.85, 1.0 };   GLfloat diffuseColor[]  = { 0.3, 0.4, 0.5, 1.0 };   GLfloat specularColor[] = { 0.2, 0.2, 0.9, 1.0 };   glPushMatrix();   GLUquadricObj* pQuadric = gluNewQuadric();   glTranslatef(xPos, yPos, zPos);   glEnable(GL_NORMALIZE);   glShadeModel(GL_POLYGON_SMOOTH);   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 16.0);   const int   NUM_SEGMENTS = 32;   const float centerRadius = radius * 0.2;   const float innerRadius = radius * 0.6;   glTranslatef( 0.0, 1.0, 0.0f );   // Quadric responds perfectly to lighting!   glBegin(GL_POLYGON); glColor3ub(30, 50, 50); gluSphere(pQuadric, radius, 30, 30);    glEnd();   glTranslatef( 0.0, -1.0, 0.0f );   // Pitiful lighting effects!   glBegin(GL_TRIANGLE_FAN); glColor3ub(30, 50, 50); // center vertex of fan glVertex3f(0.0, 0.0, length + 0.3); for (int i = 0; i <= NUM_SEGMENTS; i ++) {    const double angle = (double)(i) / (double)NUM_SEGMENTS * M_PI * 2.0;    glVertex3f(sin(angle) * centerRadius, cos(angle) *centerRadius, length); }   glEnd();   glPopMatrix();This is my first post here and after spending hundreds of hours learning OpenGL I'm completely hindered from making it usable in a commercial product so help would be very, very much appreciated.Philip   
  OpenGL needs normals for light calculations. So for each triangle there has to be a call to glNormal3f() (or not, if you want to use the same normal for a couple of triangles).OpenGL does NOT automatically generate normals for you. The reason that quadrics work but your triangles don't, is simple: They specific the normals with glNormal3f(), you don't. Fix that, and the lights will work.glEnable(GL_NORMALIZE) normalizes all normals to a length of 1. You really don't want to do that every frame. Calculate your normals, normalize them ONCE and disable GL_NORMALIZE (normalisation is a rather expensive operation, as it requires the calculation of a square root).   ;Quote:Original post by ExpandableglEnable(GL_NORMALIZE) normalizes all normals to a length of 1. You really don't want to do that every frame. Calculate your normals, normalize them ONCE and disable GL_NORMALIZE (normalisation is a rather expensive operation, as it requires the calculation of a square root).glEnable(GL_NORMALISE) used to be expensive, but it's now practically free. nVidia even have it listed in one of their performance presentations where they say you might as well leave it switched on.   ;  Go into wireframe mode and look and see how tesselated that quadric is vs. your polygon. If you want your polygon to look as good you will need more vertices or do per pixel lighting to attain a better lighting model than either of those two.   ;  You need to specify normals yourself (using glNormal3f() or similar).You also need to test for OpenGL errors -- I see several places where you probably don't do the right thing (although it might not matter right now).Make it a habit to call a function to verify that things are all right every 4 calls you make to OpenGL (or more often).#include <assert.h>void checkGl() {#if !defined( NDEBUG )  GLint err = glGetError();  assert( err == 0 );#endif}Call this function after each OpenGL call, and it will stop in the debugger after the call where you pass bad parameters. In release builds, NDEBUG will be defined, so the call will be optimized out and cost nothing.;  Not to be mean or anything, but this statement"after spending hundreds of hours learning OpenGL I'm completely hindered from making it usable in a commercial product"can you honestly say that a few hundred hours and you would be ready to make a commercial product coming from no background in OpenGL? I think you set your expectations a bit high... All will come in due time patience is a must grasshopper! :)   ;  Wow!  You guys are fantastically knowledgable and wonderful help.  None of the 3 books I have discuss these things.Yes, a mere few hundred hours doesn't make you computer graphics wizard but my applications are not so complex in terms of the graphics.  The GUI is really candy.  The value is in the DSP algorithms.Thanks so much, I'll monitor the posts and maybe I can help out with some mathematics or Physics things.Philip   ;Quote:Original post by OrangyTangQuote:Original post by ExpandableglEnable(GL_NORMALIZE) normalizes all normals to a length of 1. You really don't want to do that every frame. Calculate your normals, normalize them ONCE and disable GL_NORMALIZE (normalisation is a rather expensive operation, as it requires the calculation of a square root).glEnable(GL_NORMALISE) used to be expensive, but it's now practically free. nVidia even have it listed in one of their performance presentations where they say you might as well leave it switched on.Really? That surprises me. I mean how can it be almost free to normalize hundreds of thousands normals per frame? Or do they cache the result somehow? Probably not. I mean it doesn't really make sense anyway. Most of the time you have to renormalize the normals in the fragment shader anyway... so you can skip the per-vertex normalisation.And if you don't use shaders, chances are you're targeting lower-end hardware which doesn't have fast vertex shaders and in that case GL_NORMALIZE would probably be expensive.Anyway, I always send normalized normals to OpenGL so I actually don't have that problem ;)   ;Quote:Original post by ExpandableQuote:Original post by OrangyTangQuote:Original post by ExpandableglEnable(GL_NORMALIZE) normalizes all normals to a length of 1. You really don't want to do that every frame. Calculate your normals, normalize them ONCE and disable GL_NORMALIZE (normalisation is a rather expensive operation, as it requires the calculation of a square root).glEnable(GL_NORMALISE) used to be expensive, but it's now practically free. nVidia even have it listed in one of their performance presentations where they say you might as well leave it switched on.Really? That surprises me.Yeah, it surprised me too which is why I still remember it. [grin] I suspect they've got some dedicated hardware which is lighning fast and/or the normalisation can be done in parallel with other vertex ops which makes it 'for free'.But obviously if you're completely sure that the normals will always be correct then you don't need it.;  Wouldn't that mean the performance boost would only exist with NVIDIA cards? I suppose the extension (?) could be detected and used, but then again if you already have the normals for use with other cards, you might as well not bother in the first place...   