tango2009
asked on
Opengl lighting
I am creating a simple game in opengl I am trying to light the whole scene. This is the code I am using
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
yet when I run the prgram there is nothing. This is my main class below
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
yet when I run the prgram there is nothing. This is my main class below
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <math.h>
#include "Enemy.h"
#include "Item.h"
//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
float cRadius = 10.0f; // our radius distance from our character
float lastx, lasty;
void DrawFloor();
void DrawSnowMan();
void DrawWeapon();
static int weapon = 0;
void skybox();
Enemy enemy;
Item item;
//positions of the cubes
float positionz[10];
float positionx[10];
int Score = 0;
// Load in textures
#define SNOW 0
//#define HORIZON 0
//#define WOOD 0
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
struct Vector3
{
float x;
float y;
float z;
};
struct BoundingBox
{
Vector3 max;
Vector3 min;
};
struct Image
{
unsigned long size_x;
unsigned long size_y;
char *data;
};
typedef struct Image Image;
const int textureCount = 1; // specifies # of textures
Image myTextureData[textureCount]; //array storing image texture info
GLuint theTexture[textureCount]; //array storing OpenGL texture info
/* texture filename list */
char* textureFilenames[textureCount] = {"Snow.bmp"};
int window_width = 800; //sets the width of the window
int window_height = 600; //sets the hight of the window
///////////////////////////////////////////////
//////////////////////////////////////////////
void output(GLfloat x, GLfloat y, char *format)
{
va_list args;
char buffer[200], *p;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glPushMatrix();
glTranslatef(x, y, 0);
for (p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopMatrix();
}
int imageLoader(const char *filename, Image *image)
{
FILE *file;
unsigned long size;
unsigned long i;
unsigned short int planes;
unsigned short int bpp;
char temp;
char finalName[80];
glTexCoord2f(1.0, 0.0);
strcpy(finalName, "" );
strcat(finalName, filename);
if ((file = fopen(finalName, "rb"))==NULL)
{
printf("File Not Found : %s\n",finalName);
return 0;
}
fseek(file, 18, SEEK_CUR);
glTexCoord2f(1.0, 0.0);
if ((i = fread(&image->size_x, 4, 1, file)) != 1)
{
printf("Error reading width from %s.\n", finalName);
return 0;
}
if ((i = fread(&image->size_y, 4, 1, file)) != 1)
{
printf("Error reading height from %s.\n", finalName);
return 0;
}
size = image->size_x * image->size_y * 3;
if ((fread(&planes, 2, 1, file)) != 1)
{
printf("Error reading planes from %s.\n", finalName);
return 0;
}
if (planes != 1)
{
printf("Planes from %s is not 1: %u\n", finalName, planes);
return 0;
}
if ((i = fread(&bpp, 2, 1, file)) != 1)
{
printf("Error reading bpp from %s.\n", finalName);
return 0;
}
if (bpp != 24)
{
printf("Bpp from %s is not 24: %u\n", finalName, bpp);
return 0;
}
fseek(file, 24, SEEK_CUR);
image->data = (char *) malloc(size);
if (image->data == NULL)
{
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1)
{
printf("Error reading image data from %s.\n", finalName);
return 0;
}
for (i=0;i<size;i+=3)
{
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
return 1;
}
//////////////////////////////////////////////////////
////Texture Loader
//////////////////////////////////////////////////////
void textureLoader()
{
/* set the pixel storage, GL_UNPACK_ALIGNMENT : specifies alignment requirements
for the start of each pixel row in memory 1 = byte-alignment*/
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(int k=0; k < textureCount; k++)
{
if(!imageLoader(textureFilenames[k], &myTextureData[k]))
exit(1);
/* generate texture names */
glGenTextures(1, &theTexture[k]);
/* create a named texture bound to a texture target */
glBindTexture(GL_TEXTURE_2D, theTexture[k]);
/* set the texture parameters */
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
/* builds and load a set of mipmaps */
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data);
}
}
void DrawWeapon(void)
{
// Draw the Handle
glPushMatrix();
glRotatef(90.0f,5.0f,10.0f,5.0f);
glScalef (2.0, 0.4, 1.0);
glTranslatef(0.5f,-1.0f,0.6f);
glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
glutSolidCube (0.6);
glPopMatrix();
//Draw the hammer
glPushMatrix();
glTranslatef(0.6f,0.6f,-1.0f);
glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
glutSolidCube(0.9);
glPopMatrix();
}
void DrawSnowMan(void)
{
// Draw Body
/* if (box->min.x>x) box->min.x = x;
if (box->min.y>y) box->min.y = y;
if (box->min.z>z) box->min.z = z;
if (box->max.x<x) box->max.x = x;
if (box->max.y<y) box->max.y = y;
if (box->max.z<z) box->max.z = z;*/
glTranslatef(0.0f ,0.1f, 0.0f);
glutSolidSphere(0.75f,20,20);
// Draw Head
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.4f,20,20);
// Draw Hand
glPushMatrix();
glTranslatef(0.5f ,-0.5f, 0.0f);
glutSolidSphere(0.4f,20,20);
glPopMatrix();
//Draw Second hand
glPushMatrix();
glTranslatef(-0.5f ,-0.5f, 0.0f);
glutSolidSphere(0.4f,20,20);
glPopMatrix();
// Draw Eyes
glPushMatrix();
glColor3f(0.0f,0.0f,0.0f);
glTranslatef(0.05f, 0.10f, -0.4f);
glutSolidSphere(0.05f,10,10);
glTranslatef(-0.1f, 0.0f, 0.0f);
glutSolidSphere(0.05f,10,10);
glPopMatrix();
// Draw Nose
glPushMatrix();
glColor3f(1.0f, 0.5f , 0.5f);
glTranslatef(0.0f,0.0f,-0.2f);
glRotatef(180.0f,0.0f,0.0f,0.0f);
glutSolidCone(0.08f,0.5f,10,2);
glPopMatrix();
}
void cubepositions (void) { //set the positions of the cubes
for (int i=0;i<10;i++)
{
positionz[i] = rand()%10 + 3;
positionx[i] = rand()%10 + 3;
}
}
//draw the cube
void cube (void) {
for (int i=0;i<10 - 1;i++)
{
glPushMatrix();
glTranslated(-positionx[i + 1] * 10, 0, -positionz[i + 1] * 10); //translate the cube
// house
glPushMatrix();
glTranslatef(0,5,0);
//glBindTexture(GL_TEXTURE_2D,texture[0]);
glutSolidCube(12); // building
glTranslatef(0,5,0);
glPushMatrix(); // roof
glRotatef(-90,1,0,0);
glutSolidCone(10.5,10,16,19);
glPopMatrix();
glTranslatef(.75,.20,-.75);
glPushMatrix(); // chimney
glScalef(2,8,2);
glutSolidCube(.25);
glPopMatrix();
glPopMatrix();
glTranslatef(0,-.65,2);
// glutSolidCube(2); //draw the cube
glPopMatrix();
}
}
void init (void) {
glEnable (GL_LIGHTING); //enable the lighting
glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
cubepositions();
glEnable(GL_TEXTURE_2D);
// texture[0] = loadtextures("Wood.bmp", 256,256);
// texture[1] = loadtextures("Snow.bmp", 256,256);
}
void enable (void) {
glEnable (GL_DEPTH_TEST); //enable the depth testing
glEnable (GL_COLOR_MATERIAL);
glShadeModel (GL_SMOOTH); //set the shader to smooth shader
glEnable(GL_TEXTURE_2D);
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0); //clear the screen to
//blacks
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//clear the color buffer and the depth buffer
enable();
glLoadIdentity();
textureLoader();
// glutSolidCube(12);
glTranslatef(0.0f, 0.0f, -cRadius);
glRotatef(xrot,1.0,0.0,0.0);
glColor3f(1.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
output(80, 2800, "SnowMan Game Score.");
if (Score == 100)
{
output(80, 2800, "You Win.");
}
//glutSolidCube(2); //Our character to follow*/
glTranslatef(0.4f,0.0f,0.0f);
DrawSnowMan();
glPushMatrix();
DrawWeapon();
glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
glPopMatrix();
glRotatef(yrot,0.0,1.0,0.0);
glTranslated(-xpos,0.0f,-zpos);
glColor3f(1.0f, 1.0f, 1.0f);
cube(); //call the cube drawing function
//Weapon();`
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
DrawFloor();
enemy.DrawEnemy(1.0f,0.0f,0.0f);
item.DrawItem(1.0f,0.0f,0.0f);
// glutWireCube (5.0);
glPopMatrix();
glutSwapBuffers(); //swap the buffers
angle++; //increase the angle
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport
//to the current window specifications
glMatrixMode (GL_PROJECTION); //set the matrix to projection
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //set the perspective (angle of sight, width, height, , depth
glMatrixMode (GL_MODELVIEW); //set the matrix back to model
}
void keyboard (unsigned char key, int x, int y) {
if (key=='q')
{
xrot += 1;
if (xrot >360) xrot -= 360;
}
if (key=='z')
{
xrot -= 1;
if (xrot < -360) xrot += 360;
}
if (key=='w')
{
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos += float(sin(yrotrad));
zpos -= float(cos(yrotrad));
ypos -= float(sin(xrotrad));
}
if (key=='s')
{
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos -= float(sin(yrotrad));
zpos += float(cos(yrotrad));
ypos += float(sin(xrotrad));
}
if (key=='d')
{
float yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xpos += float(cos(yrotrad)) * 0.2;
zpos += float(sin(yrotrad)) * 0.2;
}
if (key=='e')
{
weapon = (weapon + 5) % 360;
glutPostRedisplay();
}
if (key=='a')
{
float yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xpos -= float(cos(yrotrad)) * 0.2;
zpos -= float(sin(yrotrad)) * 0.2;
}
if (key==27)
{
exit(0);
}
}
void DrawFloor(void) {
glBindTexture(GL_TEXTURE_2D, theTexture[SNOW]);
glTranslatef(0.0f,-3.0f,0.0f);
glBegin(GL_QUADS);
glTexCoord2f(1.0f,0.0f);
//glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-100.0,-0.5, -100);
glTexCoord2f(1.0f,1.0f);
// glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-100.0,-0.5, 100.0);
glTexCoord2f(0,1.0f);
// glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(100.0, -0.5, 100.0);
glTexCoord2f(0,0);
// glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(100.0, -0.5, -100.0);
glEnd();
}
void mouseMovement(int x, int y) {
int diffx=x-lastx; //check the difference between the
//current x and the last x position
int diffy=y-lasty; //check the difference between the
//current y and the last y position
lastx=x; //set lastx to the current x position
lasty=y; //set lasty to the current y position
xrot += (float) diffy; //set the xrot to xrot with the addition
//of the difference in the y position
yrot += (float) diffx; //set the xrot to yrot with the addition
//of the difference in the x position
}
void skybox(void)
{
glBindTexture(GL_TEXTURE_2D, theTexture[SNOW]);
glNormal3f( 0.0f, 0.0f, 0.5f);
glVertex3f(-300.0f, -300.0f, 300.0f);
glVertex3f( 300.0f, -300.0f, 300.0f);
glVertex3f( 300.0f, 300.0f, 300.0f);
glVertex3f(-300.0f, 300.0f, 300.0f);
// Back Face
glNormal3f( 0.0f, 0.0f,-0.5f);
glVertex3f(-300.0f, -300.0f, -300.0f);
glVertex3f(-300.0f, 300.0f, -300.0f);
glVertex3f( 300.0f, 300.0f, -300.0f);
glVertex3f( 300.0f, -300.0f, -300.0f);
// Top Face
glNormal3f( 0.0f, 0.5f, 0.0f);
glVertex3f(-300.0f, 300.0f, -300.0f);
glVertex3f(-300.0f, 300.0f, 300.0f);
glVertex3f( 300.0f, 300.0f, 300.0f);
glVertex3f( 300.0f, 300.0f, -300.0f);
// Bottom Face
glNormal3f( 0.0f,-0.5f, 0.0f);
glVertex3f(-300.0f, -300.0f, -300.0f);
glVertex3f( 300.0f, -300.0f, -300.0f);
glVertex3f( 300.0f, -300.0f, 300.0f);
glVertex3f(-300.0f, -300.0f, 300.0f);
// Right Face
glNormal3f( 0.5f, 0.0f, 0.0f);
glVertex3f( 300.0f, -300.0f, -300.0f);
glVertex3f( 300.0f, 300.0f, -300.0f);
glVertex3f( 300.0f, 300.0f, 300.0f);
glVertex3f( 300.0f, -300.0f, 300.0f);
// Left Face
glNormal3f(-0.5f, 0.0f, 0.0f);
glVertex3f(-300.0f, -300.0f, -300.0f);
glVertex3f(-300.0f, -300.0f, 300.0f);
glVertex3f(-300.0f, 300.0f, 300.0f);
glVertex3f(-300.0f, 300.0f, -300.0f);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Snow Man Game");
init ();
glEnable(GL_TEXTURE_2D);
//drawSnowMan();
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutPassiveMotionFunc(mouseMovement); //check for mouse
// movement
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}
ASKER
I have changed my code to use lights like you said above. It still makes no difference I have a skybox in my scene which seems to be making everything in the scene white. Could it be that the skybox is blocking the light, if so how do I get around this.
No thhe sky box cant "block" the light since there is no concept of "blocking" built in in opengl or any other graphics api, otherwise programmers would try so hard to program effects such as shadow for example, the calculation of the pixel color is in fact a very simple equation: is's the dot product of the surface normal and the light direction times object color times light color i.e: dot(normal, light_dir)*color*light_col or.
So it's something else.
Perhaps you could post a minimal sample? Just one box, no textures etc...
So it's something else.
Perhaps you could post a minimal sample? Just one box, no textures etc...
ASKER
When I comment out the calls for the skybox the lighting works fine. Could it be simply how I display the skybox? Maybe the order I make the calls in the display function.
void display (void) {
glClearColor (0.0,0.0,0.0,1.0); //clear the screen to
//blacks
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//clear the color buffer and the depth buffer
enable();
glColor3f(1.0f, 0.0f, 0.0f);
//CG->Prepare(CH->GetElaps edSeconds( 1));
//CG->Render();
glLoadIdentity();
GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight
GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight
glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change
glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); //change
GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the
glLightfv (GL_LIGHT0, GL_POSITION, LightPosition);
textureLoader();
glTranslatef(0.0f, 0.0f, -cRadius);
glRotatef(xrot,1.0,0.0,0.0 );
//glColor3f(1.0f, 1.0f, 1.0f);
output(0, 2, "Kill the Robots.");
if (Score > 100)
{
output(0, 2, "You Win.");
}
glPushMatrix();
//glutSolidCube(2); //Our character to follow*/
glTranslatef(0.4f,0.0f,0.0 f);
DrawSnowMan();
glPopMatrix();
glPushMatrix();
DrawWeapon();
// glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
glPopMatrix();
glRotatef(yrot,0.0,1.0,0.0 );
glTranslated(-xpos,0.0f,-z pos);
cube(); //call the cube drawing function
drawitems();
drawEnemy();
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
DrawFloor();
//CG->Prepare(CH->GetElaps edSeconds( 1));
//CG->Render();
glPopMatrix();
glutSwapBuffers(); //swap the buffers
angle++; //increase the angle
}
I have commented out the skybox parts above.
void display (void) {
glClearColor (0.0,0.0,0.0,1.0); //clear the screen to
//blacks
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//clear the color buffer and the depth buffer
enable();
glColor3f(1.0f, 0.0f, 0.0f);
//CG->Prepare(CH->GetElaps
//CG->Render();
glLoadIdentity();
GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight
GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight
glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change
glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); //change
GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the
glLightfv (GL_LIGHT0, GL_POSITION, LightPosition);
textureLoader();
glTranslatef(0.0f, 0.0f, -cRadius);
glRotatef(xrot,1.0,0.0,0.0
//glColor3f(1.0f, 1.0f, 1.0f);
output(0, 2, "Kill the Robots.");
if (Score > 100)
{
output(0, 2, "You Win.");
}
glPushMatrix();
//glutSolidCube(2); //Our character to follow*/
glTranslatef(0.4f,0.0f,0.0
DrawSnowMan();
glPopMatrix();
glPushMatrix();
DrawWeapon();
// glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
glPopMatrix();
glRotatef(yrot,0.0,1.0,0.0
glTranslated(-xpos,0.0f,-z
cube(); //call the cube drawing function
drawitems();
drawEnemy();
glPushMatrix();
glScalef (2.0, 0.4, 1.0);
DrawFloor();
//CG->Prepare(CH->GetElaps
//CG->Render();
glPopMatrix();
glutSwapBuffers(); //swap the buffers
angle++; //increase the angle
}
I have commented out the skybox parts above.
I dont see the skybox function neither in your last post nor in your original posting... That is the function itself is present in the original post but you don't call it from anywhere in the code...
ASKER
The skybox is called from another class using this part of the code in the display function
//CG->Prepare(CH->GetElaps edSeconds( 1));
//CG->Render();
//CG->Prepare(CH->GetElaps
//CG->Render();
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml
For example:
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);