Link to home
Start Free TrialLog in
Avatar of AzraSound
AzraSoundFlag for United States of America

asked on

(60 pts) OpenGL question

Avatar of mlaughton
mlaughton

It looks like you're making your lighting call right after you're swapping buffers.  I don't have access to an OpenGL development environment right now, but the first thing I'd try would be flip/flopping the lighting and swap buffer calls.  That might take care of your problem.
Avatar of AzraSound

ASKER

thanks for the input.  i had thought of that and tried it but it didnt seem to make any difference.  the change doesnt occur until later when i do stuff with the mouse which always updates it right away.  or even other keyboard events not related to lighting update right away.  it is when those events occur that the lighting is finally updated.
Looking at the code again, I notice that your glLightf() call happens after all of the drawing you want to do takes place.  In order for your vertices/normals to reflect the changes in your lighting model, you have to make the glLightf() call first.  Try:

void display(void) {
   glClear(GL_COLOR_BUFFER_BIT |
         GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   /* moved here from bottom */
   glLightf(GL_LIGHT0,
      GL_SPOT_CUTOFF, angle);

   if(solid == TRUE)
      glutSolidSphere(r, 50, 40);
   else
      glutWireSphere(r, 50, 40);

   DrawVertices();
   glutSwapBuffers();
}

The reason your changes weren't taking immediate effect before is because the program had cycle through display() more than once in order to see the changes made at the end of the first time around (hence, you saw your changes after the next event).

I hope this works!
didnt seem to change anything...let me post all my code so maybe you can tinker with it.  its an assignment due in two days so if i dont get an answer by then it wont do me much good.  this is the only problem i have left.

#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#define TRUE 1
#define FALSE 0
#define ON 1
#define OFF 0
#define POINTLIGHT 0.0
#define SPOTLIGHT 1.0
#define SIZE 40  /*total number of points allowed to be drawn*/


void chngDimensions(int value);
float getZval(float x, float y);
void DrawVertices(void);
int onSphere(float x, float y);

int increase = 10;
int decrease = -10;
float r = 1.0;
int solid = TRUE;
float points [SIZE][3];   /*store all current points drawn*/
int numPoints;  /*store the number of points drawn thus far*/
int winH, winW, light;
float angle = 45.0;
float prevangle = 45.0;
GLfloat lightType = SPOTLIGHT;
GLfloat spot_direction[] = {0.0, 0.0, 10.0};
GLfloat position[] = {0.0, 0.0, 3.0, 1.0};



void myinit(void)
{
       glLightfv(GL_LIGHT0,GL_POSITION,position);
       //glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_direction);
    glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,angle);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    //glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
}

void display(void){
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,angle);
   if(solid == TRUE)
         glutSolidSphere(r, 50, 40);
   else
         glutWireSphere(r, 50, 40);
   DrawVertices();
   glutSwapBuffers();
}

void myReshape(int w, int h){
      winW = w;
   winH = h;
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   if (w <= h)
         glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
            1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
   else
         glOrtho (-1.5*(GLfloat)w/(GLfloat)h,
            1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   display();
}


void mouse(int button, int state, int x, int y){
      int valid; float z; float x0, y0;
      if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
         y = winH - y;
      x0 = x;
      y0 = y;
      x0 = (x0 - winW/2)/165;
      y0 = (y0 - winH/2)/165;
      valid = onSphere(x0,y0);
      if(valid == TRUE){
            z = getZval(x0,y0);
            points[numPoints][0] = x0;
            points[numPoints][1] = y0;
         points[numPoints][2] = z;
            numPoints = numPoints + 1;
         glutPostRedisplay();
            }
      else
            return;
      }
   else if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN){
         chngDimensions(increase);
      glutPostRedisplay();
      }
   else if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
         chngDimensions(decrease);
      glutPostRedisplay();
      }
   }

void DrawVertices(void){
    int i;
    glPointSize(3.0);
    glBegin(GL_POINTS);
             for(i=0;i<numPoints;i++)
                glVertex3f(points[i][0],points[i][1],points[i][2]);
    glEnd();
}

void keyboard(unsigned char key,int x,int y){
      if(key == 's' || key == 'S'){
         solid = !solid;
         glutPostRedisplay();
      }
   else if(key == 't' || key == 'T'){
         if(light == OFF){
            angle = prevangle;
               light = ON;
         }
      else{
            angle = 0.0;
            light = OFF;
         }
      glutPostRedisplay();
      }
   else if(key == 'i' || key == 'I'){
         angle = angle * 1.1;
      glutPostRedisplay;
      }
   else if(key == 'd' || key == 'D'){
         angle = angle * .9;
      glutPostRedisplay;
      }
   else
         glutPostRedisplay;
   }

int onSphere(float x, float y){
      double temp;
   temp = x*x + y*y;
   if(temp <= (r*r))
         return TRUE;
   else{
         printf("That point is not on the sphere!\n");
         return FALSE;
      }
   }


void chngDimensions(int value){
      int i;
      if(value == increase){
         r = r * 1.1;
         for(i=0; i<=numPoints; i++){
            points[i][0] = points[i][0]*1.1;
         points[i][1] = points[i][1]*1.1;
         points[i][2] = points[i][2]*1.1;
         }
      }
   else{
         r = r * .9;
         for(i=0; i<=numPoints; i++){
            points[i][0] = points[i][0]*.9;
         points[i][1] = points[i][1]*.9;
         points[i][2] = points[i][2]*.9;
         }
      }
   glutPostRedisplay();
   }


float getZval(float x, float y){
      float z;
   z = r*r - x*x - y*y;
   z = sqrt(z);
   return z;
   }


int main(int argc, char** argv)
{
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutCreateWindow("Sphere Program");
    myinit();
    glutReshapeFunc(myReshape);
    glutMouseFunc(mouse);
    glutKeyboardFunc(keyboard);
    glutDisplayFunc(display);
    glutMainLoop();
}


can you believe it?  look at my keyboard function where i code glutPostRedisplay rather than glutPostRedisplay().  i am surprised that doesnt result in a compilation error but that was my problem all along.
ASKER CERTIFIED SOLUTION
Avatar of mlaughton
mlaughton

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Adjusted points from 0 to 10
actually it seems to work just the same. pretty interesting.  just giving you something for looking at it for me.
Thanks for the charity, Azra. ;)  By the way, if you are considering doing more development using OpenGL and a cross-platform Window/Event API (such as GLUT) you might want to check out SDL (www.devolution.com/~slouken/SDL/) as an alternative to GLUT.

By my understanding, GLUT was developed for demonstration purposes to make OpenGL easier to teach.  I've heard that development on it has stagnated somewhat, even though there were ambitious visions of grandeur earlier on.  SDL (Simple DirectMedia Layer), on the other hand, is very actively developed, and has hooks into audio, cdrom, events, OpenGL, and all kinds of good stuff.

I've been quite happy with SDL so far and highly recommend it.
to be quite honest i'm just taking a graphics class for school and this will most likely be the last i ever see of opengl. however i may consider in the future playing around with it in VB which is my area of expertise. thanks for the input and the link.