Lighting not working in opengl [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am having trouble getting the lighting to work on just the decline portion of my ground. Below is my code for the ground and the decline (making it a ditch):
static void ground(double x, double y, double z, double dx, double dy,
double dz){
float white[] = {1,1,1,1};
float Emission[] = {0.0,0.0,0.01*emission,1.0};
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white);
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,Emission);
// Save transformation
glPushMatrix();
// Offset, scale and rotate
glTranslated(x,y,z);
glScaled(dx, dy, dz);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
glColor3f(0.5, 1.0, 0.5);
glNormal3f(0,0,0);
glTexCoord2f(0.0, 0.0); glVertex3f(-100, 0, -300);
glTexCoord2f(300.0,0.0); glVertex3f(-100,0,300);
glTexCoord2f(300.0,300.0); glVertex3f(-3,0,300);
glTexCoord2f(0.0,300.0); glVertex3f(-3,0,-300);
glEnd();
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 0.5);
glNormal3f(0,0,-1);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.99,0,-300);
glTexCoord2f(300.0,0.0); glVertex3f(-2.99,0,300);
glTexCoord2f(300.0,300.0); glVertex3f(-1,-1,300);
glTexCoord2f(0.0,300.0); glVertex3f(-1,-1,-300);
glEnd();
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 0.5);
glNormal3f(0,0,1);
glTexCoord2f(0.0, 0.0); glVertex3f(0.99,-1,-300);
glTexCoord2f(300.0,0.0); glVertex3f(0.99,-1,300);
glTexCoord2f(300.0,300.0); glVertex3f(2.99,0,300);
glTexCoord2f(0.0,300.0); glVertex3f(2.99,0,-300);
glEnd();
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
glColor3f(0.5, 1.0, 0.5);
glNormal3f(0,0,0);
glTexCoord2f(0.0, 0.0); glVertex3f(2.99, 0, -300);
glTexCoord2f(300.0,0.0); glVertex3f(2.99,0,300);
glTexCoord2f(300.0,300.0); glVertex3f(100,0,300);
glTexCoord2f(0.0,300.0); glVertex3f(100,0,-300);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
So the code the doesn't have lighting working correctly is the middle two snippets of "glBegin(GL_QUADS)"

This is just an instance of GIGO (garbage in, garbage out):
glNormal3f(0,0,0);
Nope. That is not a valid normal vector, and will totally break any lighting calculation.
The next one
glNormal3f(0,0,-1);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.99,0,-300);
glTexCoord2f(300.0,0.0); glVertex3f(-2.99,0,300);
glTexCoord2f(300.0,300.0); glVertex3f(-1,-1,300);
glTexCoord2f(0.0,300.0); glVertex3f(-1,-1,-300);
is at least some non-null vector, but it isn't normal to the face you are describing, so the lighting will be just wrong.

Related

Use values instead of -1...1 for OpenGL drawing shapes?

If I wanted to draw a plane in OpenGL, I would do something like the below:
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();
This draws a white plane that covers 50% of the canvas (from -0.5 to 0.5 on two axes). I want to use numbers instead, however. I don't want to use -1 to 1, but instead something like 0 to n, where n is the dimension of my canvas. For the above example, something like 250 to 750 on two axes on a 1000 pixel canvas rather than -0.5 to 0.5.
That's what the transformation matrices are for. In your case you'd set a ortho projection matrix with the limits as you desire. In your example case
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1000, 0, 1000, -1, 1);
would set up a viewing volume so that the boundaries are at 0,0 for the lower left corner and 1000,1000 for the upper right.
Note that this (and the code you've given) use the old, deprecated fixed function pipeline. You should drop that in favour of a shader based approach.

Half cylinder/Closed cylinder in opengl

I currently have a cylinder
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0, 0, 0);
gluDisk(quad, 0.0, cylinder->radius, 300, 90);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();
but it only renders half of a cylinder instead of the whole thing (the half coming towards the view). Second issue is I don't know how to close the cylinder. The gludisk only closes the bottom of the cylinder and I'm not sure how to close the top side.
If I understand what you're describing, it sounds like you might have back face culling enabled. Do you have a glEnable(GL_CULL_FACE) call in your code? This will eliminate all polygons that face away from you. In any case, once you draw a cylinder that is closed at both sides, it will be fine to keep it enabled.
You can close the cylinder at the top with another gluDisk() call, after applying a translation that moves it to (0, 0, height). For correctness, I believe you need to rotate the disk that closes the cylinder at the bottom. Otherwise it will face to the inside of the cylinder instead of to the outside, which affects the normals, and would get it eliminated by back face culling when it should be visible.
For the full thing, it should look something like this (untested):
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0f, 0.0f, 0.0f);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
glPushMatrix();
glTranslatef(0.0f, 0.0f, cylinder->height);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
glPopMatrix();
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();

OpenGL 2D moving relation

I have the two methods hich are doing the same thing. Now I am wondering what is their differences and which one can perform faster.
Here are the methods:
1th Method
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0); glVertex2f( x, y);
glTexCoord2f( 1, 0); glVertex2f( x+texWidth, y);
glTexCoord2f( 1, 1); glVertex2f( x+texWidth, y+texHeight);
glTexCoord2f( 0, 1); glVertex2f( x, y+texHeight);
glEnd();
x++; y++;
2th Method
glPushMatrix();
glTranslatef(x, y, 0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0); glVertex2f( 0.0f, 0.0f);
glTexCoord2f( 1, 0); glVertex2f( 1.0f, 0.0f);
glTexCoord2f( 1, 1); glVertex2f( 1.0f, 1.0f);
glTexCoord2f( 0, 1); glVertex2f( 0.0f, 1.0f);
glEnd();
glPopMatrix();
x++; y++;
Regarding performance, you are using immediate mode, which is slow anyway (its the "old" way of doing things; unfortunately most OpenGL tutorials on the web are hopelessly outdated). Use buffers (gpu-side) like VBOs and VAOs if you really care about performance.
A nice modern tutorial is http://open.gl/ which introduces VBOs here: http://open.gl/drawing
The second method is alot faster, because it is translating the whole matrix, and doesn't do many calculations as it does in method one.
The second method is a lot faster, because it translates the whole QUAD matrix with less calculations.

Rotate object around another object

I drew two rectangles in my scene, and now I'm trying to rotate one rectangle around the other.
When I press the "Left key" my first rectangle moves in direction to the other, but I don't have the effect of rotate because it is only moving in a straight line in direction of the other rectangle.
How do I change the Z direction of the first rectangle?
tl;dr: It's like a solar system, but I don't understand how can I have the depth effect.
I'm using GLUT and OpenGL.
EDIT: More Info:
This is my current code (function that shows the scene):
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glFlush();
}
And a image to help:
Please enable depth test to hide objects beyond other objects.
Give a high value z vaue for the far object.
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -26.0f); // Z value of behind object is set far from eye
glPopMatrix();
What you want to do is moderately complicated.
The only way I know to locate rectangles in 3-space is to build them using glVertex3f() like this:
glBegin(GL_QUADS);
glVertex3f(x0, y0, z0);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
Your "solar system" will have to be located in screen coordinates: X->left/right, Y->up/down, Z->into/out of screen. To create the effect of orbiting, you'll have to recalculate all four X and Z for each movement increment.
I also suggest using gluLookAt() if you want to see a different view.
The man page for glPerspective() says that zNear is always positive but you've given it a negative number. I'd leave that line commented out until I saw some orbiting.
HTH.

OpenGL Lighting struggles

I'm in the middle of a project teaching the basics of OpenGL. I've got most of the requirements working fine in terms of camera rotation, translation etc. However I'm struggling a lot with the lighting.
This picture is a comparison of my current program (left) vs the sample solution (right).
In case you can't tell, I'm getting very monochrome colours on the truck. The shadows are very sharp and dark, the high points are singly coloured instead of specular.
The project calls for the use of textures; the one I've shown here is a basic texture of plain grey pixels but i could use any texture (including the beach sand one being used for the ground).
I'm drawing the object from a mesh:
GLfloat ambient[] = {0.1, 0.1, 0.1, 1};
GLfloat diffuse[] = {0.1, 0.1, 0.1, 1};
GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat shine = 100.0;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, shine);
glEable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureNumber);
glBegin(GL_TRIANGLES);
for (int i = 0; i < meshes[n]->nTriangles; i++) {
for (int j = 0; j < 3; j++) {
glNormal3fv(mesh -> normals[mesh->triangles[i][j]]);
glTexCoord2fv(mesh->texCoords[mesh->triangles[i][j]]);
glVertex3fv(mesh -> vertices[mesh->triangles[i][j]]);
}
}
glEnd();
There is one light in the scene:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST)
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);
Is there something major that I'm missing that could be causing this severe difference? Particular values I should play with? Or a glEnable call I've missed?
Any help, advice or pointers to elsewhere much appreciated.
To eliminate the sharp drop-off, amp up the ambient light. There's no global illumination model in OpenGL so that parameter has absolutely no effect beyond being the colour the face will be if no other light falls upon it.
Since you're using glVertex-type calls, I'll go out on a limb and guess you're using the fixed functionality pipeline? If so then lighting is calculated at vertices, then interpolated across polygon surfaces. That means that specular highlights don't work very well on 'large' polygons — roughly speaking, the highlight can't appear in the middle of a polygon. GPUs with programmable pipelines (which includes the ones in mobile phones nowadays) can calculate lighting per pixel instead of per vertex but OpenGL doesn't do this for you, so you'd need to delve into shader programming yourself. Or just ensure that your model is made up of small enough polygons.
Your shininess exponent is also quite high - have you tried dialling that down a few notches?
when looking at the background, it looks like a spotlight on the right just bathing the Scene into warm light, and a Flakscheinwerfer on the left basking everything in extreme lightning, eliminating every shadow

Resources