Lighting and material color problems - opengl

I can't change any object color when lighting is enabled.
This is my init function (the part of the light and material):
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
GLfloat light_ambient[] = {0.5, 0.5, 0.5, 1.0};
GLfloat light_diffuse[] = {0.0, 0.5, 0.5, 1.0};
GLfloat light_specular[] = {0.0, 0.0, 0.5, 1.0};
GLfloat light_position[]={0, -1.0, 0, 0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Each object has a vector of colors. This is how I draw my objects:
float mat_a[] = {0.0, 0.0, 0.0, 1.0};
float mat_d[] = {0.0, 0.0, 0.0, 1.0};
float mat_s[] = {0.0, 0.0, 0.0, 1.0};
...
colors_vect = some_object->getColor();
glDisable(GL_COLOR_MATERIAL);
mat_a[0] = colors_vect.at(0);
mat_a[1] = colors_vect.at(1);
mat_a[2] = colors_vect.at(2);
mat_d[0] = colors_vect.at(3); //The values are correct.
mat_d[1] = colors_vect.at(4);
mat_d[2] = colors_vect.at(5);
mat_s[0] = colors_vect.at(6);
mat_s[1] = colors_vect.at(7);
mat_s[2] = colors_vect.at(8);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_a);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_d);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_s);
glEnable(GL_COLOR_MATERIAL);
glBegin(GL_POLYGON);
...
This code doesn't work. I tried to give the mat some random values and still nothing changes.
What am I doing wrong? Any help would be appreciated!

Your problem is caused by this line:
glEnable(GL_COLOR_MATERIAL);
This enables functionality that allows material properties to track the current color, which is the color set with regular glColor() calls. If this is enabled, glColorMaterial() controls which parts of the material parameters track the current color. The default is GL_AMBIENT_AND_DIFFUSE, which means that the current color is used for the ambient and diffuse material parameters.
You need to make a choice about how you want to update your material properties:
If you need to change colors very frequently, it can be most efficient to enable GL_COLOR_MATERIAL, and use glColor() to update the material properties.
You can use glColorMaterialfv(), which gives you more control, and e.g. allows you to set different colors for ambient and diffuse. For this approach, you need to keep GL_COLOR_MATERIAL disabled.
You used a mix of these two, where you set the material properties with glColorMaterialfv(), but then also enabled GL_COLOR_MATERIAL. This means that the ambient and diffuse material properties you set are not used. Instead the current color is used for those two properties. These properties would then change any time you call glColor(). If you never call glColor(), they would use the default value for the current color, which is white (1.0, 1.0, 1.0, 1.0).

Related

Lighting not working on OpenGL - Solid color

The lighting doesn't work, the object appears with solid color. The color itself changes with the material or lighting parameters but no shadow or anything just solid grey.
Here's part of the code:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glFrontFace(GL_CCW);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
GLfloat amb[] = {0.6, 0.6, 0.6, 1.0};
GLfloat dif[] = {0.8, 0.8, 0.8, 1.0};
GLfloat spec[] = {0.5, 0.5, 0.5, 1.0};
GLfloat pos[] = {0.0, 0.0, 30.0};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
GLfloat co[4]={0.5, 0.5, 0.5, 0.5};
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, co);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
for(int i=0; i < numofTr; i++)
{
glBegin(GL_TRIANGLES);
glNormal3f(tr[i].v1->n.x, tr[i].v1->n.y, tr[i].v1->n.z);
glVertex3f(tr[i].v1->x, tr[i].v1->y, tr[i].v1->z);
glNormal3f(tr[i].v2->n.x, tr[i].v2->n.y, tr[i].v2->n.z);
glVertex3f(tr[i].v2->x, tr[i].v2->y, tr[i].v2->z);
glNormal3f(tr[i].v3->n.x, tr[i].v3->n.y, tr[i].v3->n.z);
glVertex3f(tr[i].v3->x, tr[i].v3->y, tr[i].v3->z);
glEnd();
}
I don't know what I'm missing, the normals look good when displayed along with the object.
You are using dim light on a gray object. Obviously the result is gray.
If you mean that faces are flat shaded, that's because of glShadeModel(GL_FLAT);. Change it to GL_SMOOTH to enable interpolation.
If the object is in 3D, I think that the fact you are only passing 3 floats as position might be relevant; default value is [0,0,1,0], and the function expects four floats (4th being the W coordinate, which should in most cases be equal to 1, or 0 for lights in infinite distance).
Also double check that the data you give to glVertex and glNormal is correct. When rendering a sphere at 0,0,0, the normal of every vertex is the normalized position of such vertex (only holds for spheres, obviously).
As a side note, this code is obviously outdated, and as a disclaimer I would ditch it alltoghether, if you are only learning, and switch to something that's relatively modern and uses programmable pipeline.

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 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

Making a light source visible in OpenGL

I want to move my light source in my OpenGL-Scene, which is working. But to actually I want to see thee light source as well.
How can I do this?
...
glPushMatrix();
GLfloat lightPos[] = {0, 0, 200, 1};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
GLfloat ambientLight[] = { 0.2, 0.2, 0.2, 1.0};
GLfloat lightColor[] = { 0.5, 0.5, 0.5, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor);
glutSolidSphere(5,50,50);
glPopMatrix();
...
A light source is not a visible object, per se. If you want to "see" a light, you have to place some object at the position that your light is. Maybe use a sphere, a sprite, an arrow (pointing in the direction the light is pointing in, if it's a directional light), etc.

OpenGL: What happens if I specify a light as both specular and diffuse?

On the sphere lighting example of the redbook I read this:
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Then it says:
In this example, the first three calls
to glLightfv() are superfluous, since
they’re being used to specify the
default values for the GL_AMBIENT,
GL_DIFFUSE, and GL_SPECULAR parameter
As I understand so far, every light source has default values for its ambient, diffuse and specular parameters and these three arrays specify what are those default values, is that right? Does every light source is by default diffuse, specular and ambient?
In the OpenGL lighting model, 4 separate lighting equations are computed for an object: Ambient, Diffuse, Specular, and Emission. Ambient doesn't take the normals into account, Diffuse and Specular do, and Emission doesn't take light into account at all.
All these different lighting values are summed to give the final color of an object.
Yes, these are the default values for Light0: http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml