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
}
}