OpenGL Lighting questions

My light keeps moving!

Page 1 of 1

7 Replies - 6355 Views - Last Post: 27 February 2009 - 12:15 PM Rate Topic: -----

#1 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

OpenGL Lighting questions

Posted 16 February 2009 - 11:27 AM

Yesterday I tried to get some help on the java forms but no one seemed to know OpenGl so I will try here and see if I do any better.

I figured out shading but I can't seem to figure out my light position.

Now I have a figure which is rotating -- and my light continues to rotate with it!

Here is the basic flow of what I do:

//Begin initialization
#1 Set ModelView and load identityMatrix
#2 Set Projection Mode and load identityMatrix and establish my view
#3 Set ModelView, load identity Matrix, push
#4 preform a roation and then translation.
#5 Save Model Matrix as View1.
#6 Pop Matrix.
//End initialization

#6.5 Clear buffers....

//Establish light position
#7 Set ModelView, Push, load IdentityMatrix
#8 Establish positional light at (5,5,5)
#9 Pop
// End establish light position

//Begin to draw model
#10 Set ModelView, Push
#11 Load View1 Matrix
#12 Draw...
#13 Rotate arround y axis
#14 Save View1
#15 Pop
// End draw model

#16 goto #6.5

My model looks great. The problem is that the light source is rotating -- or at least moving.

I have checked to ensure that I am pushing and poping by checking the ModelMatrix stack depth at each stage and indeed the seem to be correct. I have tried only establishing the light source once by putting it between steps #2 and #3. (after setting perspective and before setting up View1).

I also tried putting right before step 12 -- which resulted in screwing with my perspective.

Here is the code where I set the light:

	public void insertLight() {
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glPushMatrix();
			gl.glDisable( GL.GL_LIGHT1 );
		gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightpos, 0);
//		gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightdir, 0); // Directional light also rotates....
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_AMBIENT, colorWhite, 0);
		gl.glLightfv( GL.GL_LIGHT1, GL.GL_DIFFUSE, colorGray, 0);
			gl.glLightfv( GL.GL_LIGHT1, GL.GL_SPECULAR, colorLightYellow, 0);
		//gl.glEnable( GL.GL_LIGHT0 );
		gl.glEnable( GL.GL_LIGHT1 );
		printDepth("Setting Lights");
		gl.glPopMatrix();
	}


I suppose my next step is to draw an object at the light's coordinates and try to see if it is really rotating.

Is This A Good Question/Topic? 0
  • +

Replies To: OpenGL Lighting questions

#2 WolfCoder  Icon User is offline

  • Isn't a volcano just an angry hill?
  • member icon


Reputation: 790
  • View blog
  • Posts: 7,623
  • Joined: 05-May 05

Re: OpenGL Lighting questions

Posted 16 February 2009 - 11:33 AM

Yeah, it sounds like a transformation stage where your light gets stuck with it. I'm not that good at OpenGL yet but I do know you have to be careful in the order you place your transformation and object creation instructions. One time I wanted a single sprite to rotate and I ended up causing the entire game to rotate!

OpenGL is a state machine, so try resetting the transformation matrices for normal objects and keep re-arranging the order of commands until the effect you want happens.
Was This Post Helpful? 0
  • +
  • -

#3 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: OpenGL Lighting questions

Posted 16 February 2009 - 02:44 PM

There are times when I just want to smash something into the computer over and over and over...

So I really think it has something to do with the normals. To assess the situation I figured I would add a sphere and see if the light revolved around it.... SO I found a tutorial on materials and lighting and figured out how to add a sphere... BUT the sphere comes out with no shading. Its just a big yellow circle!

Now I was able to show that the rotation of my model was not universal since when rendered as a wireframe the sphere does move -- but does when I add it to the model's matrix.

But after all the trouble I went though to get model lit I am REALLY frustrated by the sphere not shading.



So here is where I calculate my quads and normals:
	private void drawFrmArrays(double[][] xvalues,double[][] yvalues,double[][] zvalues) {
		double x1,y1,z1,x2,y2,z2,nx,ny,nz;
		for (int i = 0; i < xvalues.length-1; i++ ) {
			for (int j = 0; j < yvalues.length-1; j++ ) {
				x1 = xvalues[i+1][j] - xvalues[i][j];
				y1 = yvalues[i+1][j] - yvalues[i][j];
				z1 = zvalues[i+1][j] - zvalues[i][j];
				x2 = xvalues[i][j+1] - xvalues[i][j];
				y2 = yvalues[i][j+1] - yvalues[i][j];
				z2 = zvalues[i][j+1] - zvalues[i][j];
				
				nx = y1 * z2 - z1 * y2;
				ny = z1 * x2 - x1 * z2;
				nz = x1 * y2 - y1 * x2;
				
				double size = Math.sqrt(nx * nx + ny * ny + nz * nz);
				nx/=size;
				ny/=size;
				nz/=size;
				float[] color = {.1f, .5f, .8f};
				gl.glBegin(GL.GL_QUADS);
					gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, color, 0);
					gl.glNormal3d(nx,ny,nz);
					gl.glVertex3d(xvalues[i][j+1], zvalues[i][j+1], yvalues[i][j+1]);
					gl.glVertex3d(xvalues[i+1][j+1], zvalues[i+1][j+1], yvalues[i+1][j+1]);
					gl.glVertex3d(xvalues[i+1][j], zvalues[i+1][j], yvalues[i+1][j]);
					gl.glVertex3d(xvalues[i][j], zvalues[i][j], yvalues[i][j]);
				gl.glEnd();
				
//				gl.glBegin(GL.GL_LINES);
//					gl.glVertex3d(xvalues[i][j], zvalues[i][j], yvalues[i][j]);
//					gl.glVertex3d(xvalues[i][j]+nx, zvalues[i][j]+ny, yvalues[i][j]+nz);		
//				gl.glEnd();
				
			}
		}   	
	}

Was This Post Helpful? 0
  • +
  • -

#4 bobjob  Icon User is offline

  • D.I.C Head

Reputation: 23
  • View blog
  • Posts: 163
  • Joined: 29-March 08

Re: OpenGL Lighting questions

Posted 17 February 2009 - 03:49 AM

I also use openGL with Java, (but I use LWJGL)

can I please look at your openGL init code, there could be a problem with smooth shading in there.

make sure you place your camera before placing your lightposition.

I personally setup lights straight after the camera position code.
smothing like:
void placeCameraFPS() {
  GL11.glTranslated(-xPos,-yPos,-zPos); //translate the screen to the position of our camera
  GL11.glRotatef(xRot,1.0f,0.0f,0.0f);
  GL11.glRotatef(yRot,0.0f,1.0f,0.0f)
}


public static void initLighting() {
  GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, lightPosition); 
  GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, lightAmbients);		
  GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, lightDiffuse);		
}



so call placeCamera() and then initLighting()
then draw your objects.

edit:
its probably better for debugging purposes, to use a simple two sided quad with oposite normals, in order to test how the lighting is working.

This post has been edited by bobjob: 17 February 2009 - 03:53 AM

Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: OpenGL Lighting questions

Posted 27 February 2009 - 09:03 AM

I fixed it! It was after all a problem with the normals. It was driving me crazy. When I had created my arrays of values I had three xvalues, yvalues, and zvalues -- the problem is that y and z were swapped.

So when I was calculating my normals I was swapping the y and z values back and thus my frustration. Here is the complete program -- to run it you need the QtJambi jars and the JOGL jars

my classpath:
    JOGL libs
  • jogl.jar
  • gluegen-rt.jar
    Qt Jambi libs
  • qtjambi-4.4.3_01.jar
  • qtjambi-win32-msvc2005-4.4.3_01.jar
Here is the code (java):

/**
 * QtJambi OpenGL example 1: Plotting an equation:
 * Coded by NickDMax for DreamInCode 2009.
 */
package qtglfunc.display;

import java.nio.DoubleBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;

import com.trolltech.qt.core.QBasicTimer;
import com.trolltech.qt.core.QTimerEvent;
import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.opengl.QGLWidget;

/**
 * This class displays a 3D Graph with hidden surface removal using OpenGL.
 * The class demonstrates how to use OpenGL within Qt Widgets.
 * @author NickDMax
 */
public class ExampleEQ1 extends QGLWidget {
	
    
	/**
	 * -- the OpenGL Context
	 */
	GLContext ctx = null;
	
	/**
	 * The gl Object -- connection to OpenGL library.
	 */
	GL gl = null;
	
	/**
	 * the glu Object -- connection to OpenGL utility library.
	 */
	GLU glu = null;
	
	/**
	 * QtJambi Basic Timer used to for animation.
	 */
	QBasicTimer tmr;
	
	/**
	 * Phase shift for equation -- used to animate sinusoidal surface.
	 */
	double phase = 0;
	double angle = 0;
	
	/**
	 * Place to save the current Model View
	 */
	DoubleBuffer modelView = DoubleBuffer.allocate(16);
	

    float[] lightpos = { 5f, 5f, 5f, 1f };
    float[] lightdir = { -1f, -1f, 1f, 0f };
    
    float[] lightcolor = { 1f, 1f, 1f, 1f };
    float[] colorBlack  = {0.0f,0.0f,0.0f,1.0f};
    float[] colorWhite  = {1.0f,1.0f,1.0f,1.0f};
    float[] colorGray   = {0.6f,0.6f,0.6f,1.0f};
    float[] colorRed    = {1.0f,0.0f,0.0f,1.0f};
    float[] colorBlue   = {0.0f,0.0f,0.1f,1.0f};
    float[] colorYellow = {1.0f,1.0f,0.0f,1.0f};
    float[] colorLightYellow = {.5f,.5f,0.0f,1.0f};

	
	
	/**
	 * Build and launch widget in a window. 
	 * @param args
	 */
	public static void main(String[] args) {
		QApplication.initialize(args);
		ExampleEQ1 window = new ExampleEQ1();
		
		window.setGeometry(100,100,500,500);
		window.show();
		window.show();
		QApplication.exec();
		System.out.println("Closed");
	}
	
	
	/**
	 * Called to initialize the QGLWidget OpenGL connection. This is where
	 * we connect Qt With JOGL by associating this context with this thread.
	 */
	protected void initializeGL()
    {
	    //Get a context and GL object from JOGL
		GLDrawableFactory factory = GLDrawableFactory.getFactory();
	    ctx = factory.createExternalGLContext();
	    ctx.makeCurrent();
	    gl = ctx.getGL();
	    glu = new GLU();
		tmr = new QBasicTimer();
		tmr.start(10, this);
    }
	
    
	/**
	 * Setup our view upon resize.
	 */
	protected void resizeGL(int w, int h)
    {
	    double aspect = (float)w/(float)h;

	    
	    gl.glShadeModel(GL.GL_SMOOTH);
	    gl.glEnable( GL.GL_NORMALIZE );
		gl.glEnable( GL.GL_LIGHTING );
		//gl.glEnable( GL.GL_LIGHT0);
	    
	    

	    gl.glMatrixMode(GL.GL_PROJECTION);
	    gl.glLoadIdentity();
	    gl.glViewport(0, 0, w, h);
	    glu.gluPerspective(65, aspect, .001, 120);

	    gl.glMatrixMode(GL.GL_MODELVIEW);
	    gl.glPushMatrix();
	    gl.glLoadIdentity();
		    gl.glTranslated(0,-5,-15);
			gl.glRotated(30, 1, 0, 0);
		    gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelView);
		gl.glPopMatrix();
		//	
    }
    
	/**
	 * Where we actually draw the surface. Is called by Update().
	 */
	protected void paintGL()
    {
		//resizeGL(this.width(), this.height());
		// draw the scene:
		// ...
		gl.glClearColor(0.5f, 0.8f, 0.5f, 0);
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    	insertLight();
		
    	//Insert a big yellow ball...
//    	GLUquadric quad = glu.gluNewQuadric();
//	    gl.glMatrixMode(GL.GL_MODELVIEW);
//	    gl.glPushMatrix(); {
//	    	gl.glTranslated(0, 2, -10);
//	    	gl.glColor3d(1,1,0);
//			gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, colorYellow, 0);
//			glu.gluSphere(quad, 1, 17, 17);
//	    	//gl.glCallList(sun);
//	    } gl.glPopMatrix();    	
 
	    gl.glMatrixMode(GL.GL_MODELVIEW);
	    gl.glPushMatrix();
		gl.glLoadMatrixd(modelView);
		
		gl.glRotated(.75, 0, 1, 0);
		//Draw axis
		gl.glBegin(GL.GL_LINES); 
			gl.glColor3d(1,0,0); //RED = x
			gl.glVertex3d(-15, 0, 0);
			gl.glVertex3d(15, 0, 0);
		gl.glEnd();
		gl.glBegin(GL.GL_LINES);
			gl.glColor3d(0,1,0); //Green = Y
			gl.glVertex3d(0, -15, 0);
			gl.glVertex3d(0, 15, 0);
			gl.glEnd();
		gl.glBegin(GL.GL_LINES);
			gl.glColor3d(0,0,1); //BLUE = Z
			gl.glVertex3d(0, 0, -15);
			gl.glVertex3d(0, 0, 15);
		gl.glEnd();
		//printDepth("Durring Draw");		


		calculateSurface(-10, -10, 20, 20, 75, 75);
	    gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, modelView);
		gl.glPopMatrix();


		//Here we adjust the phase for the next iteration
		phase+=.025;
		//Since we are dealing with a sinusoidal surface we can wrap at 2Pi
		if (phase >= 2*Math.PI) { phase = 0; }
		//if ((angle-=0.25) >= 360) { angle = 0; }
		//printDepth("After Draw");
    }  
    
    /**
     * Timer Event called by QBasicTimer
     */
	protected void timerEvent(QTimerEvent event) {
        if (event.timerId() == tmr.timerId()) {
            update();
        } else {
            super.timerEvent(event);
        }
    }
	
	protected void printDepth(String prompt) {
		DoubleBuffer db = DoubleBuffer.allocate(1);
		gl.glGetDoublev(GL.GL_MODELVIEW_STACK_DEPTH, db);
		System.out.println(prompt + ":\t"+  db.get(0));
		
	}
    
    /**
     * This is where I am currently calculating the points and drawing the surface.
     * Later this will be broken up into more logical units.
     * @param ix -- the initial (x,z) coordinates
     * @param iz
     * @param xw -- The width of the surface along x axis
     * @param zw -- The width of the surface along z axis (actually the z-axis in OpenGL)
     * @param xf -- Number of points along the x-axis
     * @param zf -- Number of points along the z-axis
     */
	private void calculateSurface(double ix, double iz, double xw, double zw, int xf, int zf) {
    	double xs = xw/xf;
    	double zs = zw/zf;
    	double x, z, magnitude;
    	double[][] zvalues = new double[xf][zf]; 
    	double[][] xvalues = new double[xf][zf]; 
    	double[][] yvalues = new double[xf][zf];
 
    	for (int i = 0; i < xf; i++ ) {
			x = ix + xs * i;
    		for (int j = 0; j < zf; j++ ) {
    			z = iz + zs * j;
    			//magnitude = 0.4 * (5 - Math.sqrt(y * y + x * x)); //* Math.sin(offset) / 2);
    			
    			magnitude = Math.sqrt(z * z * 2 + x * x);
    			yvalues[i][j] = 1/(.125*magnitude+.1) * Math.cos(magnitude-phase);
    			xvalues[i][j]=x;
    			zvalues[i][j]=z;
    		}
    	}

    	//Draw the wirefram.... 
    	gl.glEnable(GL.GL_DEPTH_TEST);
    	gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
    	gl.glColor3d(.1, .5, .8);
		drawFrmArrays(xvalues, yvalues, zvalues, true);
    	
		//Fill in the quads -- effect is hidden line removal.
		gl.glEnable( GL.GL_LIGHTING );
		//gl.glEnable( GL.GL_COLOR_MATERIAL);
		gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
    	gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
		gl.glPolygonOffset(1.0f, 1.0f);
		//gl.glColor3d(.1, .5, .8);
		drawFrmArrays(xvalues, yvalues, zvalues, false);
		gl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
		//gl.glDisable( GL.GL_COLOR_MATERIAL);
		gl.glDisable( GL.GL_LIGHTING );
		
    }
    
    /**
     * Draw the actual Quads... Here is where the surface is actually drawn.
     */
	private void drawFrmArrays(double[][] xvalues,double[][] yvalues,double[][] zvalues, boolean drawNormals) {
		double x1,y1,z1,x2,y2,z2,nx,ny,nz;
		for (int i = 0; i < xvalues.length-1; i++ ) {
			for (int j = 0; j < zvalues[0].length-1; j++ ) {
    			x1 = xvalues[i+1][j] - xvalues[i][j];
    			y1 = yvalues[i+1][j] - yvalues[i][j];
    			z1 = zvalues[i+1][j] - zvalues[i][j];
    			x2 = xvalues[i][j] - xvalues[i][j+1];
    			y2 = yvalues[i][j] - yvalues[i][j+1];
    			z2 = zvalues[i][j] - zvalues[i][j+1];
    			
    			nx = y1 * z2 - z1 * y2;
    			ny = z1 * x2 - x1 * z2;
    			nz = x1 * y2 - y1 * x2;
    			
    			double size = Math.sqrt(nx * nx + ny * ny + nz * nz);
    			nx/=size;
    			ny/=size;
    			nz/=size;
				float[] color = {.1f, .5f, .8f};
				gl.glBegin(GL.GL_QUADS);
					gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, color, 0);
					gl.glNormal3d(nx,ny,nz);
    				gl.glVertex3d(xvalues[i][j+1], yvalues[i][j+1], zvalues[i][j+1]);
    				gl.glVertex3d(xvalues[i+1][j+1], yvalues[i+1][j+1], zvalues[i+1][j+1]);
    				gl.glVertex3d(xvalues[i+1][j], yvalues[i+1][j], zvalues[i+1][j]);
					gl.glVertex3d(xvalues[i][j], yvalues[i][j], zvalues[i][j]);
    			gl.glEnd();
    			
				//Draw The normals
    			if (drawNormals) {
					gl.glBegin(GL.GL_LINES);
						gl.glColor3d(1,0,0);
						gl.glVertex3d(xvalues[i][j], yvalues[i][j], zvalues[i][j]);
						gl.glVertex3d(xvalues[i][j]+nx/3, yvalues[i][j]+ny/3, zvalues[i][j]+nz/3);		
						gl.glColor3d(.1, .5, .8);
					gl.glEnd();
    			}    			
    		}
    	}   	
    }
	
	public void insertLight() {
	    gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glDisable( GL.GL_LIGHT1 );
	    gl.glLoadIdentity();
	    gl.glPushMatrix();
//	    gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightpos, 0);
	    gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightdir, 0);
	    gl.glLightfv( GL.GL_LIGHT1, GL.GL_AMBIENT, colorWhite, 0);
	    gl.glLightfv( GL.GL_LIGHT1, GL.GL_DIFFUSE, colorGray, 0);
        gl.glLightfv( GL.GL_LIGHT1, GL.GL_SPECULAR, colorLightYellow, 0);
		//gl.glEnable( GL.GL_LIGHT0 );
		gl.glEnable( GL.GL_LIGHT1 );
		//printDepth("Setting Lights");
	    gl.glPopMatrix();
	}
}

This post has been edited by NickDMax: 27 February 2009 - 02:08 PM

Was This Post Helpful? 1

#6 Hyper  Icon User is offline

  • Banned

Reputation: 108
  • View blog
  • Posts: 2,129
  • Joined: 15-October 08

Re: OpenGL Lighting questions

Posted 27 February 2009 - 09:06 AM

Congrats! What're you making anyhow?
Was This Post Helpful? 0
  • +
  • -

#7 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: OpenGL Lighting questions

Posted 27 February 2009 - 12:13 PM

Well in all honesty I was just playing with OpenGL. The program is a rotating graph of the function given by:

1 / (A * sqrt(2 * z * z + x * x) + B ) * Cos(sqrt(2 * z * z + x * x) - Phase)

Which basically looks like a rippling surface with the ripples radiating from a central point at the origin and diminishing as they get further away from the origin.

-- One of the things that first really got me interested in programming was a BASIC program I found in a magazine that plotted a 3D sine wave. This is just a little more advanced version of the same program really -- but it makes me happy: comfort code.
Was This Post Helpful? 0
  • +
  • -

#8 Hyper  Icon User is offline

  • Banned

Reputation: 108
  • View blog
  • Posts: 2,129
  • Joined: 15-October 08

Re: OpenGL Lighting questions

Posted 27 February 2009 - 12:15 PM

Sounds... interesting.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1