Login  Register

Re: Lighting the inside of a cube

Posted by KevinWorkman on Nov 05, 2014; 5:49pm
URL: https://forum.jogamp.org/Lighting-the-inside-of-a-cube-tp4033471p4033497.html

Thanks for the replies, guys.

I've changed the first line of my step() function to this:

gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, new float[]{(float)lightPos.x, (float)lightPos.y, (float)lightPos.z}, 1);

(the only change was changing the last 0 to a 1)

But now my walls are flickering instead of being evenly lit. Is there anything else I need to do?

Edit: Here is the entirety of my updated code. It now separates the camera from the light source. The camera is controlled via the arrow, p, and o keys, and the light source is controlled via the number keys 1-6.

import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;


import com.jogamp.opengl.util.FPSAnimator;

public class CameraTest implements GLEventListener {


	private final GLCanvas canvas = new GLCanvas();

	private final int worldX = -400;
	private final int worldY = -400;
	private final int worldWidth = 800;
	private final int worldHeight = 800;
	private final int worldZ = 100;
	private final int worldDepth = 800;

	public GL2 gl;

	private boolean upPressed = false;
	private boolean downPressed = false;
	private boolean leftPressed = false;
	private boolean rightPressed = false;
	private boolean pPressed = false;
	private boolean oPressed = false;

	double speed = 5;

	private double pitchAngle = 0;
	private double rollAngle = 210;

	Vector3D cameraPos = new Vector3D((worldX + worldWidth)/2, (worldY+worldHeight)/2, (worldZ + worldDepth)/2);

	Vector3D lightPos = new Vector3D((worldX + worldWidth)/2-10, (worldY+worldHeight)/2-10, (worldZ + worldDepth)/2+100);

	public CameraTest(){



		canvas.addGLEventListener(this);
		gl = (GL2) canvas.getGL();



		FPSAnimator animator = new FPSAnimator(canvas, 60);
		animator.start();

		canvas.addKeyListener(new KeyAdapter(){

			@Override
			public void keyReleased(KeyEvent e) {

				if(e.getKeyCode() == KeyEvent.VK_UP){
					upPressed = false;
				}
				else if(e.getKeyCode() == KeyEvent.VK_DOWN){
					downPressed = false;
				}
				else if(e.getKeyCode() == KeyEvent.VK_LEFT){
					leftPressed = false;
				}
				else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
					rightPressed = false;
				}
				else if(e.getKeyCode() == KeyEvent.VK_P){
					pPressed = false;
				}
				else if(e.getKeyCode() == KeyEvent.VK_O){
					oPressed = false;
				}
			}

			@Override
			public void keyPressed(KeyEvent e) {


				if(e.getKeyCode() == KeyEvent.VK_UP){
					upPressed = true;
				}
				else if(e.getKeyCode() == KeyEvent.VK_DOWN){
					downPressed = true;
				}
				else if(e.getKeyCode() == KeyEvent.VK_LEFT){
					leftPressed = true;
				}
				else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
					rightPressed = true;
				}
				else if(e.getKeyCode() == KeyEvent.VK_P){
					pPressed = true;
				}
				else if(e.getKeyCode() == KeyEvent.VK_O){
					oPressed = true;
				}

				else if(e.getKeyCode() == KeyEvent.VK_1){
					lightPos = lightPos.add(new Vector3D(-10, 0, 0));
				}
				else if(e.getKeyCode() == KeyEvent.VK_2){
					lightPos = lightPos.add(new Vector3D(10, 0, 0));
				}
				else if(e.getKeyCode() == KeyEvent.VK_3){
					lightPos = lightPos.add(new Vector3D(0, -10, 0));
				}
				else if(e.getKeyCode() == KeyEvent.VK_4){
					lightPos = lightPos.add(new Vector3D(0, 10, 0));
				}
				else if(e.getKeyCode() == KeyEvent.VK_5){
					lightPos = lightPos.add(new Vector3D(0, 0, -10));
				}
				else if(e.getKeyCode() == KeyEvent.VK_6){
					lightPos = lightPos.add(new Vector3D(0, 0, 10));
				}

				//System.out.println();
				System.out.println("Pos: " + lightPos.toString());
			}
		});

		JFrame frame = new JFrame("Camera Test");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(canvas, BorderLayout.CENTER);

		frame.setSize(500, 500);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

		canvas.requestFocusInWindow();
	}


	public void init(GLAutoDrawable drawable) {

	}

	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
		gl = (GL2) canvas.getGL();

		gl.glEnable(GL.GL_CULL_FACE);
		gl.glCullFace(GL.GL_BACK);

		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glMatrixMode(GL2.GL_MODELVIEW);
		gl.glEnable(GL.GL_BLEND);

		gl.glEnable(GL2.GL_LIGHTING);
		gl.glEnable(GL2.GL_LIGHT0);

		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, new float[]{1f, 1f, 1f, 1}, 0);
		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_EMISSION, new float[]{.1f, .1f, .1f, 1}, 0);
		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, new float[]{0f, 0f, 0f, 1}, 0);
		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, new float[]{1f, 1f, 1f, 1}, 0);

		gl.glBlendFunc(GL.GL_SRC_ALPHA,  GL.GL_ONE_MINUS_SRC_ALPHA);

		gl.glLoadIdentity();
		gl.glFrustum(-1, 1, -1, 1, 1, worldZ + worldDepth + 10);
		gl.glViewport(0, 0, width, height);

		gl.glClearColor(.25f, .25f, .25f, 1f);
	}


	public void display(GLAutoDrawable drawable){
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		step();
		displayFromCamera(drawable);
	}

	private void step(){

		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, new float[]{(float)lightPos.x, (float)lightPos.y, (float)lightPos.z}, 1);

		if(upPressed){
			pitchAngle+=1;
		}
		if(downPressed){
			pitchAngle-=1;
		}

		while(pitchAngle < 0){
			pitchAngle += 360;
		}
		while(pitchAngle > 360){
			pitchAngle -= 360;
		}

		if(leftPressed){
			if(pitchAngle < 270 && pitchAngle > 90){
				rollAngle+=1;
			}
			else{
				rollAngle-=1;
			}

		}
		if(rightPressed){
			if(pitchAngle < 270 && pitchAngle > 90){
				rollAngle-=1;
			}
			else{
				rollAngle+=1;
			}
		}
		
		if(pPressed){
			double newPosX = speed *  Math.sin(Math.toRadians(rollAngle)) * Math.cos(Math.toRadians(pitchAngle ));
			double newPosY = speed * -Math.sin(Math.toRadians(pitchAngle) );
			double newPosZ = speed *  Math.cos(Math.toRadians(rollAngle) ) * Math.cos(Math.toRadians(pitchAngle));

			cameraPos = cameraPos.add(new Vector3D(newPosX, newPosY, -newPosZ));
		}

		if(oPressed){
			double newPosX = speed *  Math.sin(Math.toRadians(rollAngle)) * Math.cos(Math.toRadians(pitchAngle ));
			double newPosY = speed * -Math.sin(Math.toRadians(pitchAngle) );
			double newPosZ = speed *  Math.cos(Math.toRadians(rollAngle) ) * Math.cos(Math.toRadians(pitchAngle));

			cameraPos = cameraPos.add(new Vector3D(-newPosX, -newPosY, newPosZ));
		}
	}

	public void displayFromCamera(GLAutoDrawable drawable){
		gl.glPushMatrix();


		gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight());

		gl.glLoadIdentity();

		gl.glFrustum(-1, 1, -1, 1, 1, 100000);

		gl.glRotated(pitchAngle, 1, 0, 0);
		gl.glRotated(rollAngle, 0, 1, 0);

		gl.glTranslated(-cameraPos.x, -cameraPos.y, -cameraPos.z);

		displayWholeScene(drawable, false);

		gl.glPopMatrix();
	}


	public void material(float r, float g, float b){

		float[] m = {r, g, b, 1};

		gl.glMaterialfv(GL.GL_FRONT, GL2.GL_SPECULAR, m,0);
		//   gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, 100.0f);
		gl.glMaterialfv(GL.GL_FRONT, GL2.GL_DIFFUSE, m, 0);
		//gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, m, 0);
		//gl.glMaterialfv(GL.GL_FRONT, GL.GL_EMISSION, m, 0);
	}

	public void displayWholeScene(GLAutoDrawable drawable, boolean drawSnake){
		
		
		
		material(1, 1, 1);
        gl.glPointSize(1000/(cameraPos.distance(lightPos)+1));
        gl.glBegin(GL.GL_POINTS);
        gl.glVertex3d(lightPos.x, lightPos.y, lightPos.z);
        gl.glEnd();

		double w = (worldWidth)/10;
		double h = (worldHeight)/10;
		double d = worldDepth/10;

		for(double x = worldX; x < worldX+worldWidth; x+=w){
			for(double y = worldY; y < worldY+worldHeight; y+=h){

				gl.glBegin(GL2.GL_POLYGON);

				gl.glColor3f(0, 1, 0);
				material(0, .5f, 0);
				gl.glNormal3d(0, 0, -1);
				
				gl.glVertex3d(x, y+h, (worldZ+worldDepth));
				gl.glVertex3d(x+w, y+h, (worldZ+worldDepth));
				gl.glVertex3d(x+w, y, (worldZ+worldDepth));
				
				gl.glVertex3d(x, y, (worldZ+worldDepth));
				
				
				
				gl.glEnd();
			}
		}

		for(double z = worldZ; z < worldZ + worldDepth; z+=d){
			for(double y = worldY; y < worldY+worldHeight; y+=h){
				gl.glBegin(GL2.GL_POLYGON);
				gl.glColor3f(0, 0, 1);
				material(0, 0, .5f);
				gl.glNormal3d(1, 0, 0);
				
				
				
				gl.glVertex3d(worldX, y, (z+d));
				gl.glVertex3d(worldX, y, (z));
				gl.glVertex3d(worldX, y+h, (z));
				gl.glVertex3d(worldX, y+h, (z+d));

				gl.glEnd();
			}
		}


		//		gl.glBegin(GL2.GL_POLYGON);
		//		gl.glColor3f(0, 0, 1);
		//		material(0, 0, 1);
		//		gl.glNormal3d(-1, 0, 0);
		//		gl.glVertex3d(worldX, worldY+worldHeight, -(worldZ+worldDepth));
		//		gl.glVertex3d(worldX, worldY+worldHeight, -(worldZ));
		//		gl.glVertex3d(worldX, worldY, -(worldZ));
		//		gl.glVertex3d(worldX, worldY, -(worldZ+worldDepth));
		//		gl.glEnd();

	}

	public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
	}


	private static class Vector3D{
		private final double x;
		private final double y;
		private final double z;

		public Vector3D(double x, double y, double z){
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public float distance(Vector3D other) {
			return (float) Math.sqrt((x-other.x)*(x-other.x) + (y-other.y)*(y-other.y) + (z-other.z)*(z-other.z));
		}

		public Vector3D add(Vector3D delta) {
			return new Vector3D(x+delta.x, y+delta.y, z+delta.z);
		}

		public String toString(){
			return x + ", " + y + ", " + z;
		}

	}

	public static void main(String[] args) {
		new CameraTest();
	}


	@Override
	public void dispose(GLAutoDrawable arg0)
	{
		// TODO Auto-generated method stub

	}
}