LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-11-2011, 04:47 PM   #1
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
OpenGL lighting doesn't follow viewpoint


I'm trying to use OpenGL in a programme, but I'm running into problems with lighting. What I would like is for the models to be lit from the direction of the viewpoint (ie. as if there were a torch strapped to the viewer's head, or a light on the camera or something).

The code I have works for some facings, but when I rotate by 180 degrees the light seems to "go out". I'm not entirely sure if it's not actually following my viewpoint, or whether something isn't configured correctly. This is a compilable code example showing the problem:

Code:
#include <GL/freeglut.h>
#include <math.h>
#define WIDTH 11
#define HEIGHT 11
#define BLOCKSIZE 5.0
const static float fdspeed = BLOCKSIZE*(0.002/1.5), rotspeed = 0.05;
const static double deg_to_rad = 3.141592653589793/180;
static float x = WIDTH*BLOCKSIZE/2, z= HEIGHT*BLOCKSIZE/2, facing = 0.0;
static int fd = 0, rt = 0, strafe = 0;

void drawWalls(int width, int height){
        glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
        glColor3f(1.0,1.0,1.0);
        glBegin(GL_POLYGON);
                glVertex3f(0.0,0.0,0.0);
                glVertex3f(0.0,-BLOCKSIZE,0.0);
                glVertex3f(width*BLOCKSIZE,-BLOCKSIZE,0.0);
                glVertex3f(width*BLOCKSIZE,0.0,0.0);
        glEnd();
        glBegin(GL_POLYGON);
                glVertex3f(0.0,0.0,0.0);
                glVertex3f(0.0,-BLOCKSIZE,0.0);
                glVertex3f(0.0,-BLOCKSIZE,height*BLOCKSIZE);
                glVertex3f(0.0,0.0,height*BLOCKSIZE);
        glEnd();
        glBegin(GL_POLYGON);
                glVertex3f(0.0,0.0,height*BLOCKSIZE);
                glVertex3f(0.0,-BLOCKSIZE,height*BLOCKSIZE);
                glVertex3f(width*BLOCKSIZE,-BLOCKSIZE,height*BLOCKSIZE);
                glVertex3f(width*BLOCKSIZE,0.0,height*BLOCKSIZE);
        glEnd();
        glBegin(GL_POLYGON);
                glVertex3f(height*BLOCKSIZE,0.0,0.0);
                glVertex3f(height*BLOCKSIZE,-BLOCKSIZE,0.0);
                glVertex3f(height*BLOCKSIZE,-BLOCKSIZE,height*BLOCKSIZE);
                glVertex3f(height*BLOCKSIZE,0.0,height*BLOCKSIZE);
        glEnd();
}
void display(void){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
        glRotatef(facing, 0.0, 1.0, 0.0); // Rotate to the correct facing
        glTranslatef(-x, 0.5*BLOCKSIZE, -z); // Move the models to the correct x and z co-ordinates
        drawWalls(WIDTH,HEIGHT);
        glPopMatrix();
        glutSwapBuffers();
}
void reshape(int w, int h){
        glViewport(0, 0, (GLsizei) w, (GLsizei) h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 0.45, (WIDTH>HEIGHT)?1.42*WIDTH*BLOCKSIZE:1.42*HEIGHT*BLOCKSIZE);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0); // y is 'up', we begin looking up the -ve z axis.
}
void movePlayer(void){
        z += cos(facing*deg_to_rad)*fd*fdspeed;
        x -= sin(facing*deg_to_rad)*fd*fdspeed;
        z -= cos((facing+90)*deg_to_rad)*strafe*fdspeed;
        x += sin((facing+90)*deg_to_rad)*strafe*fdspeed;
        facing -= rt * rotspeed;
        while(facing < 0) facing += 360.0;
        while(facing >= 360) facing -= 360.0;
        glutPostRedisplay();
}
void skeyboard(int key, int x, int y){
        switch(key){
                case GLUT_KEY_RIGHT:
                        rt = 1;
                        break;
                case GLUT_KEY_LEFT:
                        rt = -1;
                        break;
                default:
                        break;
        }
        if(fd == 0 && rt == 0 && strafe == 0) glutIdleFunc(NULL);
        else glutIdleFunc(movePlayer);
}
void keyboard(unsigned char key, int x, int y){
        switch(key){
                case 'a':
                        strafe = -1;
                        break;
                case 'd':
                        strafe = 1;
                        break;
                case 'w':
                        fd = 1;
                        break;
                case 's':
                        fd = -1;
                        break;
                default:
                        break;
        }
        if(fd == 0 && rt == 0 && strafe == 0) glutIdleFunc(NULL);
        else glutIdleFunc(movePlayer);
}
void skeyboardUp(int key, int x, int y){
        switch(key){
                case GLUT_KEY_RIGHT:
                case GLUT_KEY_LEFT:
                        rt = 0;
                        break;
                default:
                        break;
        }
        if(fd == 0 && rt == 0 && strafe == 0) glutIdleFunc(NULL);
        else glutIdleFunc(movePlayer);
}
void keyboardUp(unsigned char key, int x, int y){
        switch(key){
                case 'a':
                case 'd':
                        strafe = 0;
                        break;
                case 'w':
                case 's':
                        fd = 0;
                        break;
                default:
                        break;
        }
        if(fd == 0 && rt == 0 && strafe == 0) glutIdleFunc(NULL);
        else glutIdleFunc(movePlayer);
}
void init(void){
        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 };

        glClearColor (0.0, 0.0, 0.0, 0.0);
        glShadeModel (GL_SMOOTH);
        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);

        glEnable(GL_NORMALIZE);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_DEPTH_TEST);

        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
        glutKeyboardFunc(keyboard);
        glutKeyboardUpFunc(keyboardUp);
        glutSpecialFunc(skeyboard);
        glutSpecialUpFunc(skeyboardUp);
        glutIdleFunc(movePlayer);
}
int main(int argc, char** argv){
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(500, 500);
        glutInitWindowPosition(100, 100);
        glutCreateWindow(argv[0]);
        init();
        glutMainLoop();
        return 0;
}
Compile with
Code:
gcc file.c -o file -lglut -lGL -lGLU -Wall
The OpenGL-y stuff is in "main", "reshape", "display" and "init". The other functions are for handling input, plus a function to draw the walls.

Controls are WASD to move forward/left/back/right, left/right arrow keys to turn around. Expected behaviour is that you can always see the walls which are around you, actual behaviour is that the screen is almost black until you turn around to face the other direction.

Thanks in advance for any help

Last edited by Snark1994; 10-11-2011 at 04:49 PM.
 
Old 10-11-2011, 05:51 PM   #2
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Hi,
I don't know if it is the problem here, but I don't see any calls to glNormalXX in your code. You need to set normals to each surface you render so the OpenGL can determine the angle between the normal to the face and the direction to the source of the light. I don't know how Opengl treats normals if not specified, but it probably uses some default value such as 0.0, 0.0, 1.0 or so. If all normals are the same for all vertices in the scene, then if you look at the wall in one direction it is light because the normals are pointing towards you. If you then turn around 180 degrees the normals on the other wall will point away from you and the walls will be dark.

so for example the code to draw one of the walls could be
Code:
        glBegin(GL_POLYGON);
                glNormal3f(0.0, 0.0, 1.0);
                glVertex3f(0.0,0.0,0.0);
                glVertex3f(0.0,-BLOCKSIZE,0.0);
                glVertex3f(width*BLOCKSIZE,-BLOCKSIZE,0.0);
                glVertex3f(width*BLOCKSIZE,0.0,0.0);
        glEnd();
Note: Since the walls are rectangles, you could probably render them as GL_QUAD (or, even better, GL_TRIANGLE_STRIP) and draw all four walls within a single glBegin() / glEnd() pair, which should result in better performance.

Last edited by millgates; 10-11-2011 at 06:24 PM.
 
1 members found this post helpful.
Old 10-12-2011, 12:49 PM   #3
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632

Original Poster
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Ah brilliant!

That fixed it

Thank you very much.
 
Old 10-14-2011, 02:44 PM   #4
resetreset
Senior Member
 
Registered: Mar 2008
Location: Cyberspace
Distribution: Dynebolic, Ubuntu 10.10
Posts: 1,340

Rep: Reputation: 62
Sorry, since we're on the topic, can anyone tell me how to actually INSTALL OpenGL on a Ubuntu system? Snark?
 
Old 10-14-2011, 04:22 PM   #5
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,225

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
This was at the top of my first Google search:

http://ubuntuforums.org/showpost.php...00&postcount=2

Seriously, stop wasting people's time by asking questions that you can easily find the answers to yourself.

As this had been pointed out to you dozens of times, and your post was a threadjack, I have punished you by rating your post "not helpful".

Last edited by dugan; 10-14-2011 at 04:27 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
OpenGL: glScale(1,1,1) + lighting screws up quad rendering!? ntubski Programming 1 12-18-2009 02:24 PM
LXer: Linux Documentation From A User's Viewpoint LXer Syndicated Linux News 0 12-01-2009 12:40 PM
linux router and sonicwall viewpoint jleipert Linux - Networking 1 07-02-2005 05:02 PM
lighting in OpenGL (with C language) sterrenkijker Programming 4 08-24-2004 03:20 AM
OpenGL lighting with SDL MadCactus Programming 0 09-21-2003 11:52 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:31 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration