Unpredictable GL Frame Awt Key Handler or gluLookAt
Posted by Vincent on Aug 13, 2012; 2:31am
URL: https://forum.jogamp.org/Unpredictable-GL-Frame-Awt-Key-Handler-or-gluLookAt-tp4025788.html
I am getting textures to map to polygons and I want move the camera up and down staying parallel to the z plane. I use the awt handler to update two float variables, lookUD and lookLR. Whenever the right arrow key is hit, I add 0.01 to lookLR. Whenever I hit the left arrow key it subtracts 0.01 from lookLR. lookLR is fed to the gluLookAt parameters. This is done so I can use the directional keys to move the camera. I do the same for looking up and down using lookUD. I and gluLookAt to do this. Sometimes I am able to do this, and sometimes the textures don't move with the keystroke handler.
I am wondering if there is thread mis-communication between the keyhandler and the render loop. Or I am making the wrong gl calls.
I just want a more predictable way.
Important Areas
...
frame.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
switch (e.getKeyCode())
{
case KeyEvent.VK_UP:
lookLR = lookLR - 0.01f;
break;
case KeyEvent.VK_DOWN:
lookLR = lookLR + 0.01f;
break;
case KeyEvent.VK_LEFT:
lookUD = lookUD + 0.01f;
break;
case KeyEvent.VK_RIGHT:
lookUD = lookUD - 0.01f;
break;
}
}
});
...
private void render(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
GLU glu = GLU.createGLU(gl);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustum(-3.0, 3.0, -4.5, 4.5, 1.0, 5.0 );
////////////////////////////////
////////////////////////////////updated lookUD and lookLR
glu.gluLookAt(0.0+lookUD, 0.0+lookLR, 2.0, //glulookat translates and scales the modelview
0.0+lookUD, 0.0+lookLR, -1.0,
0.0, 1.0, 0.0);
__________________________________________________
__________________________________________________
The Whole File
__________________________________________________
__________________________________________________
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.media.opengl.*;
import javax.media.opengl.awt.GLCanvas;
import java.nio.*;
import java.awt.image.*;
import com.jogamp.opengl.util.*;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import java.net.*;
import java.io.*;
import javax.media.opengl.glu.GLU;
import javax.imageio.*;
public class SimpleScene implements GLEventListener {
private ByteBuffer checkImageBuf = GLBuffers.newDirectByteBuffer(64 * 64 * 4);
LinkedList<Drawable> a; //= new LinkedList<Drawable>();
private float xrot = 0;
private float yrot = 0;
private float zrot = 0;
private float rtri = 0;
private static float lookUD = 0;
private static float lookLR = 0;
private int texture = 0;
public static void main(String[] args) {
GLProfile glp = GLProfile.getDefault();
GLCapabilities caps = new GLCapabilities(glp);
GLCanvas canvas = new GLCanvas(caps);
Frame frame = new Frame("AWT Window Test");
frame.setSize(800, 600);
frame.add(canvas);
frame.setVisible(true);
// by default, an AWT Frame doesn't do anything when you click
// the close button; this bit of code will terminate the program when
// the window is asked to close
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
switch (e.getKeyCode())
{
case KeyEvent.VK_UP:
lookLR = lookLR - 0.01f;
break;
case KeyEvent.VK_DOWN:
lookLR = lookLR + 0.01f;
break;
case KeyEvent.VK_LEFT:
lookUD = lookUD + 0.01f;
break;
case KeyEvent.VK_RIGHT:
lookUD = lookUD - 0.01f;
break;
}
}
});
canvas.addGLEventListener(new SimpleScene());
Animator animator = new Animator(canvas);
//Animator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();
}
@Override
public void display(GLAutoDrawable drawable) {
update();
render(drawable);
}
private void update() {
rtri = rtri + (float) .1;
xrot = xrot + (float) .1;
yrot = yrot + (float) .1;
zrot = zrot + (float) .1;
//calculate me
//calculate other characters
//calculate vehicles
//load map data off screen - calculate points out of viewport
}
private void render(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
GLU glu = GLU.createGLU(gl);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustum(-3.0, 3.0, -4.5, 4.5, 1.0, 5.0 );
//gl.glTranslatef(0.0f,0.0f,-5.0f);
glu.gluLookAt(0.0+lookUD, 0.0+lookLR, 2.0, //glulookat translates and scales the modelview
0.0+lookUD, 0.0+lookLR, -1.0,
0.0, 1.0, 0.0);
//gl.glRotatef(xrot,1.0f,0.0f,0.0f);
//gl.glRotatef(yrot,0.0f,1.0f,0.0f);
//gl.glRotatef(zrot,1.0f,0.0f,0.0f);
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
float x1 = 0.0f, y1 = 0.0f, z1 = 0.0f; // bottom face, top left
float x2 = 1.0f, y2 = 1.0f, z2 = 1.0f; // top face, bottom right
gl.glBegin(GL2.GL_QUADS);
// Front Face
gl.glNormal3f(0.0f,0.0f,1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, .5f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, .5f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, .5f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, .5f);
// Back Face
gl.glNormal3f(0.0f, 0.0f, -1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -.5f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -.5f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -.5f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -.5f);
// Top Face
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -.5f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, 1.0f, .5f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, 1.0f, .5f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -.5f);
// Bottom Face
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -.5f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -.5f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, .5f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, .5f);
// Right face
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -.5f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -.5f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, .5f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, .5f);
// Left Face
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -.5f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, .5f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, .5f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -.5f);
gl.glEnd();
gl.glBegin(GL2.GL_QUADS);
// Front Face
gl.glNormal3f(0.0f,0.0f,1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, 1.0f);
// Back Face
gl.glNormal3f(0.0f, 0.0f, -1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, -1.0f);
// Top Face
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, -1.0f);
// Bottom Face
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, 1.0f);
// Right face
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, -1.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f+4.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f+4.0f, -1.0f, 1.0f);
// Left Face
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, -1.0f);
gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f+4.0f, -1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f+4.0f, 1.0f, -1.0f);
gl.glEnd();
gl.glFlush();
}
@Override
public void dispose(GLAutoDrawable arg0) {
}
@Override
public void init(GLAutoDrawable drawable) {
//LinkedList<Drawable> a = new LinkedList<Drawable>();
//Cube c = new Cube();
//c.AddPoints();
//c.AddTexture();
//a.add(c);
//a.add(c);
GL2 gl = drawable.getGL().getGL2();
GLU glu = GLU.createGLU(gl);
gl.glViewport(0,0,800,600);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustum(-10.0, 10.0, -10.5, 10.5, -10.0, 10.0 );
drawable.getGL().setSwapInterval(1);
gl.glShadeModel(GL2.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepth(1.0f);
//gl.glShadeModel(GL2.GL_FLAT);
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDepthFunc(GL2.GL_LEQUAL); //
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations
gl.glEnable(GL.GL_TEXTURE_2D);
texture = genTexture(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
makeImage();
//BufferedImage img = readPNGImage("/bricks.png");
//makeRGBTexture(gl, glu, img, GL2.GL_TEXTURE_2D, false);
int texture_dimensions = GL2.GL_TEXTURE_2D;
int multiple_textures = 0;
int rgba_channels = 3;
int width = 64;
int height = 64;
int border_width = 0;
int texture_buffer_format = GL2.GL_RGB;
int texture_buffer_type = GL.GL_UNSIGNED_BYTE;
gl.glTexImage2D(texture_dimensions, multiple_textures, rgba_channels, width,
height, border_width, texture_buffer_format, texture_buffer_type,
checkImageBuf);// checkImage[0][0][0]);
int errorCode = gl.glGetError();
String errorStr = glu.gluErrorString( errorCode );
System.out.println( "error codes: " );
System.out.println( errorStr );
System.out.println( errorCode );
//s and t mapping instructions
gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP);
gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameterf(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
//sets the drawing mode to GL_DECAL so that the textured
//polygons are drawn using the colors from the texture map
//(rather than taking into account what color the polygons would have been drawn without the texture)
gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL);
//gl.glEnable(GL2.GL_TEXTURE_2D);
//texture = genTexture(gl);
}
private int genTexture(GL gl)
{
final int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
return tmp[0];
}
@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
}
/** Retrieve a URL resource from the jar. If the resource is not found, then
* the local disk is also checked.
* @param filename Complete filename, including parent path
* @return a URL object if resource is found, otherwise null.
*/
public final static URL getResource(final String filename)
{
// Try to load resource from jar
URL url = ClassLoader.getSystemResource(filename);
// If not found in jar, then load from disk
if (url == null)
{
try
{
//change for jar use
url = new URL("file", "localhost", filename);
}
catch (Exception urlException){} // ignore
}
return url;
}
private BufferedImage readPNGImage(String resourceName)
{
try
{
URL url = getResource(resourceName);
if (url == null)
{
throw new RuntimeException("Error reading resource " + resourceName);
}
BufferedImage img = ImageIO.read(new File(url.getFile()));
java.awt.geom.AffineTransform tx = java.awt.geom.AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -img.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
img = op.filter(img, null);
return img;
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
private ByteBuffer makeRGBTexture(BufferedImage img, int target, boolean mipmapped)
{
ByteBuffer dest = null;
switch (img.getType())
{
case BufferedImage.TYPE_3BYTE_BGR:
case BufferedImage.TYPE_CUSTOM:
{
byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();
dest = ByteBuffer.allocateDirect(data.length);
dest.order(ByteOrder.nativeOrder());
System.out.println(data.length);
dest.put(data, 0, data.length);
break;
}
case BufferedImage.TYPE_INT_RGB:
{
int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
dest = ByteBuffer.allocateDirect(data.length * 4);
dest.order(ByteOrder.nativeOrder());
dest.asIntBuffer().put(data, 0, data.length);
break;
}
default:
throw new RuntimeException("Unsupported image type " + img.getType());
}
//byte[] x =dest.get(i);
for(int i =0;i<64*64*3;i++) {
byte y = dest.get(i);
System.out.println(y);
}
return dest;
}
private void makeImage() {
BufferedImage img = readPNGImage("/data/bricks.png");
ByteBuffer a = makeRGBTexture(img, GL2.GL_TEXTURE_2D, false);
for(int i = 0; i < (64*64*3)-8; i++){
checkImageBuf.put((byte) a.get(i));
}
checkImageBuf.rewind();
}
}