PDA

View Full Version : problem with lighting of a 2d-plane



rob willemsen
06-12-2005, 12:18 AM
Hi,

I'm having a problem with the lighting of a 2D-plane. In the start situation the light is shining on the front-side of the plane, and therefore os course the colors of the plane are shown. If I move the camera to the back-side of the plane, however, I still the colors of the plane. This happens when the pointing to the normal vector and the position of the light are both at the 'same' side of the plane, i.e. the normal-vector is pointing in positive x-direction and the light is at the right side of the plane, are both the other way. I would have expected that if I move the camera to the left -in the negative x-direction) when first starting the app, that once I get 'behind' the plane (x-position of camera is less than -2), that I would see a 'black' back-side of the plane.
I tried all kinds of settings - hence the keys for the global settings and toggling the normal vector -, but it doesn't seem to work like I expect.
Am I expecting the wrong things or is this the wrong code to achieve what I want to achieve?

All help appreciated.
rob willemsen

PS1: I'm working in VS.NET 2003, C++, Windows.

PS2: Tha little app has some 'function'-keys:


Characteristics of this mini-appl:
* X/Y/Z-axes are shown as red/green/blue lines
* Posiition of the light is whown as a small yellow sphere
* Center of sphere is located at (2,0,0)
* Center of plane is located at (-2,0,0)
* Camera: position is (x, 2, 10) where:
* x be changed with keys e/r/d/f (-0.1,+0.1,-0.5,+0.5)
* Light: a point-light is positioned at (x, 0, 2) where:
* x be changed with keys q/w/a/s (-0.1,+0.1,-0.5,+0.5)
* The plane has a normal vector that is either (1,0,0) or (-1,0,0):
* the x-coordinate can be toggeld with key 0 (defsault 1)
* Following general settings can be toggled (seetings are written to stdout):
* key 1 toggles flat/smooth-shading (default smooth)
* key 2 toggles 2 sided lighting (default false)
* key 3 toggles blending (default false)
* key 4 toggles showing of sphere (default true)
* Escape-key exits app
PS3: Following is the 1 and only source:

#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <iostream>
using namespace std;

GLfloat cameraX = 2.0;
GLfloat punt_position[] = {0.0, 0.0, 2.0, 1.0 };
GLfloat normalX = 1.0;
int shadeModel = GL_SMOOTH;
int twoSides = GL_FALSE;
bool blending = false;
bool showSphere = true;

GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat blue[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat shiny_little[] = { 10.0 };

void axes(double grootte)
{
// in code: eerst translatie, dan rotatie
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-grootte, 0.0, 0.0);
glVertex3f(grootte, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -grootte, 0.0);
glVertex3f(0.0, grootte, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, -grootte);
glVertex3f(0.0, 0.0, grootte);
glEnd();
glEnable(GL_LIGHTING);
}

void light()
{

//GLfloat punt_specular[] = { 1.0, 1.0, 1.0, 1.0 };

// Puntbron
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glLightfv(GL_LIGHT0, GL_SPECULAR, white);
glLightfv(GL_LIGHT0, GL_POSITION, punt_position);
}

void lightPos()
{
glPushMatrix();
glDisable(GL_LIGHTING);
glColor3f(1.0, 1.0, 0.0);
glTranslatef(punt_position[0],punt_position[1],punt_position[2]);
glutWireSphere(0.1,8,8);
glEnable(GL_LIGHTING);
glPopMatrix();
}

void sphere()
{
// Materiaal Teapot
glPushMatrix();
glTranslatef(2.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialfv(GL_FRONT, GL_SHININESS, shiny_little);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glutSolidSphere(1.0, 20, 20);
glPopMatrix();
}

void plane()
{
glPushMatrix();
glTranslatef(-2.0, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_SPECULAR, white);
glMaterialfv(GL_FRONT, GL_SHININESS, shiny_little);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glBegin(GL_POLYGON);
glNormal3f(normalX, 0.0, 0.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
glVertex3f(0.0,-2.0,2.0);
glVertex3f(0.0,2.0,2.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, red);
glVertex3f(0.0,2.0,-2.0);
glVertex3f(0.0,-2.0,-2.0);
glEnd();
glPopMatrix();
}

void display(void)
{
glShadeModel(shadeModel);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, twoSides);
if (blending)
{glEnable(GL_BLEND);}
else
{glDisable(GL_BLEND);}

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(cameraX, 2.0, 10.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);

axes(25.0);
lightPos();
light();
if (showSphere)
{sphere();}
plane();

glutSwapBuffers();
}

void reshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 0.1, 50.0);
glMatrixMode(GL_MODELVIEW);
}


void myKey(unsigned char key, int x, int y)
{
switch (key) {
case 27: // escape stopt de applicatie
exit(0);
break;

// toggle flat en smooth shading
case '1':
if (shadeModel == GL_FLAT)
shadeModel = GL_SMOOTH;
else
shadeModel = GL_FLAT;
cout << "shadeModel: " << shadeModel << endl;
break;

case '2':
if (twoSides == GL_FALSE)
twoSides = GL_TRUE;
else
twoSides = GL_FALSE;
cout << "twoSides: " << twoSides << endl;
break;

// toggle blending
case '3':
blending = !blending;
cout << "blending: " << blending << endl;
break;

case '4':
showSphere = !showSphere;
cout << "showSphere: " << showSphere << endl;
break;

case '0':
normalX = -1*normalX;
cout << "normalX: " << normalX << endl;
break;


case 'q':
punt_position[0] -= 0.1;
break;
case 'w':
punt_position[0] += 0.1;
break;

case 'a':
punt_position[0] -= 0.5;
break;
case 's':
punt_position[0] += 0.5;
break;

case 'e':
cameraX -= 0.1;
break;
case 'r':
cameraX += 0.1;
break;
case 'd':
cameraX -= 0.5;
break;
case 'f':
cameraX += 0.5;
break;
}
glutPostRedisplay();
}

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glEnable(GL_DEPTH_TEST);
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(myKey);
glutMainLoop();
return 0;
}

CWiC
06-12-2005, 11:24 PM
Front face of your plane is turned to negative direction of X axis (default front face direction is CCW and you not change that), so, "moving camera to the left (in the negative x-direction)" you, actually, move not to behind the plane but in front of plane.

rob willemsen
06-13-2005, 10:57 AM
Hi CWiC,

2 Remarks:
1. If that would be the cause, wouldn't that mean that I would have to see a difference if I were on the left side of the plane. I now see the same form both sides, that's whats astonishing to me.
2. If I toggle between CCW and CW with the glFrontFace function, I don't see a difference.

rob

CWiC
06-14-2005, 11:56 PM
You right, front face direction doesn't matter in this case, only normal direction. The situation that you see same picture on both sides of polygon using one_side_lighting is correct, if you want dark back side, you must use two_side_lighting in order to invert the normals.

rob willemsen
06-15-2005, 01:27 PM
Hi CWiC,

I have tried that! If you make an EXE of the cpp-source, then you can toggle between 1- and 2-sided lighting with the '2'-key, and you can also toggle the x-direction of the normal vector with the '0'-key.
At the start 1-sided lighting is on and the normal vector is (1,0,0). Yet, in that situation I can see that both sides of the plane are illuminated and lighted in the same way by moving the camerato the left.
So either I misunderstand something or there something else in play.

rob

CWiC
06-16-2005, 12:12 AM
Originally posted by rob willemsen:
Hi CWiC,
At the start 1-sided lighting is on and the normal vector is (1,0,0). Yet, in that situation I can see that both sides of the plane are illuminated and lighted in the same way by moving the camerato the left.
So either I misunderstand something or there something else in play.
robI'm pretty sure that you see what expected, why you think that back side (from light sourse, actually it is front side of polygon) will be not illuminated at application start? You set one_side_lighting, normals direction for both sides are equal, for both sides normals pointed to the light source (so illuminated), so why they should look different one from another?

rob willemsen
06-29-2005, 02:29 AM
Hi CWiC,

A bit late but still thnx for the response. I think I'm starting to get what I should be expecting to see under the different circumstances...

rob