Okay, I’ve tried to incorporate everything you guys have said. I’ve set the light’s w to 1 so it’s not directional. I’ve made sure that glViewport() and glFrustrum() are called when the matrix mode is projection, and that everything else is called when the matrix mode is the modelview.
However, I’m still getting pretty much the same result. Updated code is below, and as always, if anybody can point out what I’m doing wrong, I’m all ears.
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.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight());
gl.glFrustum(-1, 1, -1, 1, 1, 100000);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glEnable(GL.GL_CULL_FACE);
gl.glCullFace(GL.GL_BACK);
gl.glEnable(GL.GL_DEPTH_TEST);
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.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}, 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.glLoadIdentity();
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
}
}