Objects moving together with lighting

Started by Daslee, March 04, 2013, 15:25:15

Previous topic - Next topic

Daslee

So I just started to work with lighting in lwjgl and I never used it before. Now I'm just looking at the code and exploring what line what does, and trying to move lighting and blabla... And now I got problem when I tried to move objects in scene, so lighting moves together with all objects, as I see. Here are two screenshots how it looks by default positions, and moved to left:

http://img152.imageshack.us/img152/8601/defaulta.png

http://img152.imageshack.us/img152/1420/movedx.png

Those two spheres x position in first image is 0 and lighting x position is also 0, and in second image spheres are at around -5 and lighting still at 0, but lighting shines anyway to spheres center, where it must shine to right side of sphere. Here is my rendering code:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
		glColor3f(0.6f, 0.6f, 0.6f);
		glPushMatrix();
			glTranslatef(x - 4f, 4f, zTranslation-5);
			glBegin(GL_QUADS);
				glVertex3f(0, 0, 0);
				glVertex3f(8, 0, 0);
				glVertex3f(8, -8, 0);
				glVertex3f(0, -8, 0);
			glEnd();
		glPopMatrix();
		
		glColor3f(0.1f, 0.4f, 0.9f);
		glPushMatrix();
			glTranslatef(x, -2.5f, zTranslation);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s = new Sphere();
			s.draw(2.2f, 25, 25);
		glPopMatrix();
		
		glColor3f(0.9f, 0.0f, 0.15f);
		glPushMatrix();
			glTranslatef(x, 2.5f, zTranslation);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s2 = new Sphere();
			s2.draw(2.2f, 25, 25);
		glPopMatrix();


And lighting init:
initLightArrays();
		glMaterial(GL_FRONT, GL_SPECULAR, specularColor);				// sets specular material color
		glMaterialf(GL_FRONT, GL_SHININESS, 25.0f);					// sets shininess
		
		glLight(GL_LIGHT0, GL_POSITION, lightPosition);				// sets light position
		glLight(GL_LIGHT0, GL_SPECULAR, diffuseColor);				// sets specular light to white
		glLight(GL_LIGHT0, GL_DIFFUSE, diffuseColor);					// sets diffuse light to white
		glLightModel(GL_LIGHT_MODEL_AMBIENT, lModelAmbient);		// global ambient light 
		
		glEnable(GL_LIGHTING);										// enables lighting
		glEnable(GL_LIGHT0);										// enables light0
		
		glEnable(GL_COLOR_MATERIAL);								// enables opengl to use glColor3f to define material color
		glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);


Where could be the problem?

Fool Running

I think we're going to need to see your entire render loop. Nothing looks blatantly wrong in the code you posted.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Daslee

private void render(){
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glLoadIdentity();
		glTranslatef(0, 0, -20);
		
		glColor3f(1f, 1f, 1f);
		glPushMatrix();
			glDisable(GL_LIGHTING);
			glTranslatef(lightPosX, lightPosY, 1.0f);
			Sphere sLight = new Sphere();
			sLight.draw(0.5f, 25, 25);
			glEnable(GL_LIGHTING);
		glPopMatrix();
		
		glColor3f(0.6f, 0.6f, 0.6f);
		glPushMatrix();
			glTranslatef(x - 4f, 4f, zTranslation-5);
			glBegin(GL_QUADS);
				glVertex3f(0, 0, 0);
				glVertex3f(10, 0, 8);
				glVertex3f(10, -8, 8);
				glVertex3f(0, -8, 0);
			glEnd();
		glPopMatrix();
		
		glColor3f(0.1f, 0.4f, 0.9f);
		glPushMatrix();
			glTranslatef(x, -2.5f, zTranslation);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s = new Sphere();
			s.draw(2.2f, 25, 25);
		glPopMatrix();
		
		glColor3f(0.9f, 0.0f, 0.15f);
		glPushMatrix();
			glTranslatef(x, 2.5f, zTranslation);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s2 = new Sphere();
			s2.draw(2.2f, 25, 25);
		glPopMatrix();
		glLoadIdentity();
	}


And if you want, here is full source: http://www.solidfiles.com/d/f0203a882f/

Fool Running

The problem is that you are creating a light that is "infinitely away". This means that the light isn't coming from a single point, but from so far away that the light rays are parallel. The problem is that when you move the light, you are just changing the angle that the light hits the spheres instead of moving a point.

Here is the code that you want (I think):
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.Sphere;

public class TestIt {
	private boolean done = false;
	
	long lastFrame;
	int fps;
	long lastFPS;
	
	FloatBuffer lightPosition, lightPosition2;
	FloatBuffer ambientColor;
	FloatBuffer diffuseColor;
	FloatBuffer specularColor;
	FloatBuffer lModelAmbient;
	//FloatBuffer emission;
	
	private float zTranslation = -20f;
	
	float x = -5, roty = 0;
	float lightPosX = 1, lightPosY = 1;
	
	public TestIt(){
		init();
		
		getDelta();
		lastFPS = getTime();
		
		while(!done){
			if(Display.isCloseRequested()) done = true;

			if(Mouse.isButtonDown(0)){
				roty += Mouse.getDX();
				if(roty > 360) roty = 0;
			}
			if(Mouse.isButtonDown(1)){
				x += Mouse.getDX() * 0.025f;
			}
			
			if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)) lightPosX -= 0.01;
			if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) lightPosX += 0.01;
			if(Keyboard.isKeyDown(Keyboard.KEY_UP)) lightPosY += 0.01;
			if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)) lightPosY -= 0.01;
			
			while(Keyboard.next()){
				if(Keyboard.getEventKeyState()){
					switch(Keyboard.getEventKey()){
					case Keyboard.KEY_RETURN:
						if(glGetBoolean(GL_LIGHTING)){
							glDisable(GL_LIGHTING);
						}else{
							glEnable(GL_LIGHTING);
						}
					}
				}
			}
			
			render();
			updateFPS();
			Display.update();
		}
		Display.destroy();
	}
	
	public int getDelta(){
		long time = getTime();
		int delta = (int)(time - lastFrame);
		lastFrame = time;
		return delta;
	}
	public long getTime(){
		return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
	public void updateFPS(){
		if(getTime() - lastFPS > 1000){
			Display.setTitle("Lighting FPS: " + fps);
			fps = 0;
			lastFPS += 1000;
		}
		fps++;
	}
	
	private void render(){
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glLoadIdentity();
		glTranslatef(0, 0, zTranslation);
		
		glPushMatrix();
			glTranslatef(lightPosX, lightPosY, 5.0f);
			lightPosition.rewind();
			glLight(GL_LIGHT0, GL_POSITION, lightPosition);				// sets light position
		
			glColor3f(1f, 1f, 1f);
			glDisable(GL_LIGHTING);
			Sphere sLight = new Sphere();
			sLight.draw(0.5f, 25, 25);
			glEnable(GL_LIGHTING);
		glPopMatrix();
		
		glColor3f(0.6f, 0.6f, 0.6f);
		glPushMatrix();
			glTranslatef(x - 4f, 4f, -10);
			glBegin(GL_QUADS);
				glVertex3f(0, 0, 0);
				glVertex3f(10, 0, 8);
				glVertex3f(10, -8, 8);
				glVertex3f(0, -8, 0);
			glEnd();
		glPopMatrix();
		
		glColor3f(0.1f, 0.4f, 0.9f);
		glPushMatrix();
			glTranslatef(x, -2.5f, 0);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s = new Sphere();
			s.draw(2.2f, 25, 25);
		glPopMatrix();
		
		glColor3f(0.9f, 0.0f, 0.15f);
		glPushMatrix();
			glTranslatef(x, 2.5f, 0);
			glRotatef(roty, 0f, 1f, 0f);
			Sphere s2 = new Sphere();
			s2.draw(2.2f, 25, 25);
		glPopMatrix();
	}
	
	private void init(){
		int w = 800;
		int h = 600;
		
		try{
			Display.setDisplayMode(new DisplayMode(w, h));
			Display.setVSyncEnabled(true);
			Display.setTitle("Lighting");
			Display.create();
		}catch(Exception e){
			e.printStackTrace();
		}
		
		glViewport(0,0,w,h);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45.0f, ((float)w/(float)h),0.1f,100.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glShadeModel(GL_SMOOTH);
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClearDepth(1.0f);
		glEnable(GL_DEPTH_TEST);
		glDepthFunc(GL_LEQUAL);
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
		
		//Lighting first try
		initLightArrays();
		glMaterial(GL_FRONT, GL_SPECULAR, specularColor);				// sets specular material color
		glMaterialf(GL_FRONT, GL_SHININESS, 25.0f);					// sets shininess
		
		glLight(GL_LIGHT0, GL_POSITION, lightPosition);				// sets light position
		glLight(GL_LIGHT0, GL_SPECULAR, diffuseColor);				// sets specular light to white
		glLight(GL_LIGHT0, GL_DIFFUSE, diffuseColor);					// sets diffuse light to white
		glLightModel(GL_LIGHT_MODEL_AMBIENT, lModelAmbient);		// global ambient light 
		
		glEnable(GL_LIGHTING);										// enables lighting
		glEnable(GL_LIGHT0);										// enables light0
		
		glEnable(GL_COLOR_MATERIAL);								// enables opengl to use glColor3f to define material color
		glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);	
	}
	
	private void initLightArrays(){
		lightPosition = BufferUtils.createFloatBuffer(4);
		lightPosition.put(0).put(0).put(0.0f).put(1.0f).flip();		
		ambientColor = BufferUtils.createFloatBuffer(4);
		ambientColor.put(0.0f).put(0.0f).put(0.0f).put(1.0f).flip();
		diffuseColor = BufferUtils.createFloatBuffer(4);
		diffuseColor.put(1.0f).put(1.0f).put(1.0f).put(1.0f).flip();
		specularColor = BufferUtils.createFloatBuffer(4);
		specularColor.put(1.0f).put(1.0f).put(1.0f).put(1.0f).flip();
		lModelAmbient = BufferUtils.createFloatBuffer(4);
		lModelAmbient.put(0.2f).put(0.2f).put(0.2f).put(1f).flip();
		
		//emission = BufferUtils.createFloatBuffer(4);
		//emission.put(0.0f).put(0.0f).put(0.0f).put(1.0f).flip();
	}
	
	public static void main(String[] args){
		new TestIt();
	}
}

Notice that the location of the light is always 0,0,0,1 and the light is moved with glTranslate() instead.

Hope that helps. ;D
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Daslee