This post was updated on .
Edit One: After not receiving any replies for a few days here, I've also crossposted this on JGO: http://www.java-gaming.org/topics/jogl-lighting-the-inside-of-a-cube/34745/view.html
Edit Two: As per gouessej's request, I've redone my post using JOGL 2. I'm trying to create a simple scene with a movable camera (arrow keys to change where you're looking, P to go forward, O to go backward), a light that stays at the camera's position, and a cube that surrounds the scene, so you're surrounded by the inside of a cube. I'm starting out with just two sides of the cube for simplicity. I would expect the sides of the cube to get brighter as the light moves closer, and dim as the light moves further away. And this seems to work with one of the sides of the cube: However, why is it all black until I reach some threshold distance from the wall? Is there a way to change that threshold? It also still has some strange artifacts when I'm not looking at it head-on: I'm also trying to split the blue wall into multiple polygons just like the green one, and it seems to work as long as I'm very close to the wall: But from almost every other position, the wall is entirely black: I've checked the other side of the blue wall, and I'm pretty sure my polygons and their normals are facing the correct direction. I've posted my updated code below, which only uses JOGL 2. I'd definitely appreciate any insights you can offer! 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 = 0; Vector3D cameraPos = new Vector3D(0, 0, 400); Vector3D cameraDirection = new Vector3D(0, 0, -1); 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; } System.out.println(); System.out.println("Pos: " + cameraPos.toString()); System.out.println("Dir: " + cameraDirection.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_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)cameraPos.x, (float)cameraPos.y, (float)cameraPos.z}, 0); 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; } } float dirX = (float) (Math.sin(Math.toRadians(rollAngle)) * Math.cos(Math.toRadians(pitchAngle ))); float dirY = (float) (-Math.sin(Math.toRadians(pitchAngle) )); float dirZ = (float) (Math.cos(Math.toRadians(rollAngle) ) * Math.cos(Math.toRadians(pitchAngle))); cameraDirection = new Vector3D(dirX, dirY, dirZ); 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){ 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, -(worldZ+worldDepth)); gl.glVertex3d(x+w, y, -(worldZ+worldDepth)); gl.glVertex3d(x+w, y+h, -(worldZ+worldDepth)); gl.glVertex3d(x, y+h, -(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 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 } } |
Administrator
|
Hi
I don't reply to people still using JOGL 1 as it only causes confusion, especially for beginners. The maintenance of JOGL 1 was stopped in 2010, it's obsolete. I remind you that JOGL 2 still supports OpenGL 1.1. Please don't post any source code using JOGL 1 here and don't use it. If you have some time, please update your source code above.
Julien Gouesse | Personal blog | Website
|
Thanks for the reply. I've edited my post to only use JOGL 2.
For the record, I'm only using JOGL 1 because that's what my professor is requiring we use. |
Administrator
|
You should ask for help on our IRC channel, maybe someone else could help you.
Julien Gouesse | Personal blog | Website
|
In reply to this post by KevinWorkman
I haven't done fixed pipeline OpenGL in many years so maybe I don't recall correctly but you are creating a directional light (w=0) - those do not have attenuation so your assumption is wrong. Also, you are putting a position into x,y,z but they should contain a normalized direction vector. I guess lighting 'works' by accident as long as position is between 0-1, after that all bets are off. Here is link that probably will answer most questions about lighting in OpenGL 1 http://www.glprogramming.com/red/chapter05.html |
Administrator
|
You're right, he should set w to 1 and the vector should be normalized.
Julien Gouesse | Personal blog | Website
|
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 } } |
Free forum by Nabble | Edit this page |