OpenGL Lightning - c++

After enabling lighting in OpenGL, color in lines and polygons are no longer rendering. (Created color from glColor3f() )
This is code:
glLightModelf(GL_LIGHT_MODEL_AMBIENT, GL_TRUE);
GLfloat light1_position[] = { 5000, 2000, 1000,1 };
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light1_position);
GLfloat light_ambient[] = { 1,1,1,1 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHTING);
What am I doing wrong?

You must enable these things before using them :
glEnable ( GL_LIGHTING);
glEnable( GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glShadeModel( GL_SMOOTH);

You do not have to use GL_SMOOTH, you can also use GL_FLAT.

Related

OpenGL lighting: half of triangles not lit

I'm using the marching cubes algorithm described here http://paulbourke.net/geometry/polygonise/ to turn a scalar field into a triangle mesh, and then displaying the mesh using OpenGL's GL_TRIANGLES mode. However, I'm having trouble with the lighting.
It seems like half the triangles are not being lit at all, and it's occurring in a distinct pattern.
In the program depicted below I've set the background to red, the front face color to green, and the back face color to blue. There is one light source with position (1.0, 1.0, 1.0, 0.0) and a sphere included for reference.
http://i.imgur.com/JutXhbb.png
And here it is with the triangles flipped, as in the drawing order of the last two vertices are switched:
http://i.imgur.com/iUgqm3N.png (back face color is blue)
Whats really confusing me is why the flipped version has color everywhere whereas the normal version doesn't. I figured that even if I drew stuff wrong, at least the flipped version should reflect the same error. Any idea what's happening?
Here is the complete lighting initialization code:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat mat_color1[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_color2[] = { 0.0, 1.0, 0.0, 1.0 };
glMaterialfv(GL_BACK, GL_DIFFUSE, mat_color1);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_color2);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_BACK, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);

OpenGL Multiple Lights

I'm attempting to add a second light to my scene. I was under the impression that all I needed to do, was enable another light (LIGHT1 in this case), and set it's parameters in order for it to work alongside the existing light. With this in mind, this is my lighting initialization:
void ThemePark::lightInit(GLfloat sun_position[], GLfloat light1_position[])
{
// Enable Lighting
glEnable(GL_LIGHTING);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
glLightfv(GL_LIGHT0, GL_POSITION, sun_position); // Position the lights
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
// Set light intensity and color for each component
glLightf(GL_LIGHT0, GL_DIFFUSE, (0.5,0.5,0.5,1));
glLightf(GL_LIGHT0, GL_AMBIENT, (0.5,0.5,0.5,1));
glLightf(GL_LIGHT0, GL_SPECULAR, (1,1,1,1));
glLightf(GL_LIGHT1, GL_DIFFUSE, (0.7,0.7,0.7,1));
glLightf(GL_LIGHT1, GL_AMBIENT, (0.3,0.3,0.3,1));
glLightf(GL_LIGHT1, GL_SPECULAR, (1,1,1,1));
// Set attenuation
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, -1.0);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.2);
// Enable Lights
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
}
I am also positioning my lights again in my display function as follows:
if(lighting)
{
glLightfv(GL_LIGHT0, GL_POSITION, sun_position);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
}
Their positions are:
GLfloat sun_position[] = {10, 10, -2, 1};
GLfloat light1_position[] = {1, 1, 1, 1};
However, when doing this I still only have a single active light, LIGHT0. Taking out the enable statement for LIGHT0 gives me a scene with no lights. As a test, I modified the lighting initialization function to the following, which essentially makes LIGHT1 the same as LIGHT0, but never enables or initializes LIGHT0.
void ThemePark::lightInit(GLfloat sun_position[], GLfloat light1_position[])
{
// Enable Lighting
glEnable(GL_LIGHTING);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
glLightfv(GL_LIGHT1, GL_POSITION, sun_position);
// Set light intensity and color for each component
glLightf(GL_LIGHT1, GL_DIFFUSE, (0.5,0.5,0.5,1));
glLightf(GL_LIGHT1, GL_AMBIENT, (0.5,0.5,0.5,1));
glLightf(GL_LIGHT1, GL_SPECULAR, (1,1,1,1));
// Set attenuation
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.5);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, -1.0);
// Enable Lights
glEnable(GL_LIGHT1);
}
I also modified my display function accordingly. However, I still see no lighting in my scene. Is there something I'm missing here?
GL_LIGHT1-7 actually have different defaults than GL_LIGHT0 ... so you will have to find the ones you forgot to set. Perhaps GL_QUADRATIC_ATTENUATION? If not try setting all the params in the spec Many of them default to zero/off states for GL_LIGHT1-7.

OpenGL lighting don't work

I'm trying to setup lighting in my scene
but for some reason it doesn't work, i'm trying to figure out why
here's how I initialize OpenGL:
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHT0);
and here is how I try to draw with lighting on:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
GLfloat diffuse0[]={1.0, 1.0, 1.0, 1.0};
GLfloat ambient0[]={1.0, 1.0, 1.0, 1.0};
GLfloat specular0[]={1.0, 1.0, 1.0, 1.0};
GLfloat light0_pos[]={1.0, 1.0, 1,0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 2.0);
object->draw();
the object is not affected by the lighting at all
all normals are set and all the information that opengl require for lighting a scene
is there... what am I missing?
EDIT:
OK! I finally found a solution to the problem.
my opengl init function was misplaced in the code
I had to call it after showing the window and not before
and that's what caused the problem...
Probably you should tell us the position of the object.
Suspect 1: The position of the object and the light are too far
Suspect 2: Hide all ATTENUATION settings or make LINEARATTENUATION to 0.0

OpenGL shading not working. Object looks solid colored

I am currently trying to get into OpenGL shading and lighting to display a 3D model exported from Blender in a simple GLUT window.
I tried to display the typical glutSolidTeapot to validate my OpenGL settings.
With the Teapot everything looks perfectly fine as can be seen in the pic below.
If I now want to replace the teapot with my own Blender-exported model, the shading doesn't work. The model ( a car rim ) just looks solid-colored.
The color changes when the model is rotated, but it stays solid all the time.
What does glutSolidTeapot do under the hood to draw the teapot model?
Here's the code I'm using to set up OpenGL :
void SetupRC()
{
glClearColor(0.4, 0.4, 0.4, 1.0);
// Enable lighting and the light we have set up
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
//Set lighting parameters
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT,light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Enable shading
glShadeModel(GL_SMOOTH);
// Set up the projection parameters
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
And the code to repaint the frames :
void RenderScene(void)
{
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -2.5f);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set input data to arrays
glVertexPointer(3, GL_FLOAT, 0, BlenderGuru_CarWheelVerts);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
GLfloat ambConst[] = { 0.24725, 0.1995, 0.0745, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambConst);
GLfloat diffConst[] = { 0.75164, 0.60648, 0.22648, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffConst);
GLfloat specConst[] = { 0.628281, 0.555802, 0.366065, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specConst);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 51.2);
// draw data
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, BlenderGuru_CarWheelNumVerts);
glDisableClientState(GL_VERTEX_ARRAY);
glFlush();
}
Since you are exporting from Blender, your exported data will most likely also contain normals. If not, make sure you generate them for your model and export them. You need normal data for your lighting to work.
The call to glEnable(GL_AUTO_NORMAL); does not do what you might think it does. It will only
generate normal vectors when either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4 is used to generate vertices.
So export normal data yourself and use this, or perhaps calculate the normals from the mesh data that is available to you.
Your code lacks loading/setting normal data. Without normals, lighting doesn't work.

working with openGL

im trying to do a little 3d scene with openGL and include a bit of lighting, im fine with my scene (although it isnt anything special) and im trying to add some lighting to give it some effect. however I can add material to my podium (which isnt textured) and that gives me light and anything that IS textured does not apply any material to it so it defies the point of having lights. Heres some of the code.
// Setup GL_LIGHT0
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); // Setup ambient light
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); // Setup diffuse light
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); // Setup specular light
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, ca);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, la);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, qa);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.0);
// Setup GL_LIGHT1
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); // Setup ambient light
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); // Setup diffuse light
glLightfv(GL_LIGHT1, GL_SPECULAR, lightSpecular); // Setup specular light
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, ca);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, la);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, qa);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 0.0);
// Setup GL_LIGHT2
glLightfv(GL_LIGHT2, GL_AMBIENT, lightAmbient); // Setup ambient light
glLightfv(GL_LIGHT2, GL_DIFFUSE, lightDiffuse); // Setup diffuse light
glLightfv(GL_LIGHT2, GL_SPECULAR, lightSpecular); // Setup specular light
glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, ca);
glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, la);
glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, qa);
glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 180.0f);
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 0.0);
// Setup GL_LIGHT3
glLightfv(GL_LIGHT3, GL_AMBIENT, lightAmbient); // Setup ambient light
glLightfv(GL_LIGHT3, GL_DIFFUSE, lightDiffuse); // Setup diffuse light
glLightfv(GL_LIGHT3, GL_SPECULAR, lightSpecular); // Setup specular light
glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, ca);
glLightf(GL_LIGHT3, GL_LINEAR_ATTENUATION, la);
glLightf(GL_LIGHT3, GL_QUADRATIC_ATTENUATION, qa);
glLightf(GL_LIGHT3, GL_SPOT_CUTOFF, 180.0f);
glLightf(GL_LIGHT3, GL_SPOT_EXPONENT, 0.0);
// OpenGL provides a global ambient light component - we don't want this so set to zero
GLfloat global_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
And to render my room + 3d object.
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3);
// Define position and direction
// NOTE: Placing these commands AFTER the above viewing (camera) transformations means the light position and direction appear to have a set point / direction in the 3D environment. If these commands are placed BEFORE the above viewing transformations, then the light appears to move with the camera (as if it is attached to the camera!)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, lightDirection1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition1);
glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, lightDirection2);
glLightfv(GL_LIGHT2, GL_POSITION, lightPosition2);
glLightfv(GL_LIGHT3, GL_SPOT_DIRECTION, lightDirection3);
glLightfv(GL_LIGHT3, GL_POSITION, lightPosition3);
// setup materials for objects to draw
glMaterialfv(GL_FRONT, GL_AMBIENT, ambientMaterial);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial);
glMaterialfv(GL_FRONT, GL_SPECULAR, specularMaterial);
// 2. Draw scene
glPushMatrix();
drawRoom();
glTranslatef(0.0,-0.75,0.0);
glRotatef(90.0, 1.0,0.0, 0.0);
glRotatef(-spin, 0.0,0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
drawPodium();
glPopMatrix();
// Save transformations prior to rendering scene
glPushMatrix();
glColor3f(0.0, 0.0, 1.0);
// Setup texture state
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glRotatef(spin, 0.0,1.0, 0.0);
// Render model
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial2);
glTranslatef(0.0,0.8,0.0);
glRotatef(1.0,1.0,0.0,0.0);
myModel->renderTexturedModel();
// Reset texture state
glDisable(GL_TEXTURE_2D);
// restore transformations after rendering scene
glPopMatrix();
And the current outcome with my 4 lights, in a square shape above the helicopter all looking down towards 0.0 is:
If you can make out the white dotted lines they are the direction the lights are looking. the surface of the podium is lit and the sides of the podium are lit as it spins. However the rest of the room and helicopter does not respond to light and act like lighting isnt even enabled hence why i think its because everything except the podium is textured.
You need to setup glTexEnv to specify how lighting should work for the textured objects
See:
21.030 Why doesn't lighting work when I turn on texture mapping?
http://www.opengl.org/resources/faq/technical/texture.htm
Or to address your problem more directly, the line
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
is what causes the behaviour. As the faq explains, when you specify GL_REPLACE, you replace the primitive lighting colour with the texture colour, which overwrites any lighting calculations. You can remove this line completely as GL_MODULATE is the default behaviour.
I don't know if the above method works for you. I had the same problem. My problem was that I had not specified the normals of the object.
//specify normals
glNormal3f();
hopefully this will solve the problem for anyone (i tried every other method over the internet but nothing worked; only this method worked).