I am new to OpenGL and 3d programmin in general. I am working on a simple program to try things out in.
I can draw in the scene, but when I added an Animator to the canvas, the canvas turns out blank. I added some code to output the canvas to a file and have discovered that the first frame displays correctly, but all frames after that fail to draw anything.
Another problem is that I have three triangles here, two of them a behind the other one… but draw on top of the closer one… creating a weird optical illusion.
Below is the code for my jogl panel, does anyone see a problem or have any ideas?
Thanks
package ljb.first3d;
import net.java.games.jogl.*;
import net.java.games.jogl.util.*;
import javax.swing.*;
import javax.imageio.*;
import java.io.*;
import java.nio.*;
import java.awt.*;
import java.awt.image.*;
public class ThreeDPanel extends JPanel implements GLEventListener
{
private GLCanvas canvas;
public ThreeDPanel()
{
super();
GLCapabilities capabilities=new GLCapabilities();
capabilities.setHardwareAccelerated(true); //We want hardware acceleration
capabilities.setDoubleBuffered(true); //And double buffering
canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
canvas.addGLEventListener(this);
this.add(canvas);
Animator animator;
animator = new Animator(canvas);
animator.start();
this.add(canvas);
int w = 800, h = 600;
this.setSize(w,h);
canvas.setSize(w,h);//We want the JPanel and the GLCanvas to have the same size
canvas.setVisible(true);//This is somehow necessary
// begin render loop
new CameraLooper().start();
}
public void init(GLDrawable glDrawable)
{
GL myGL=glDrawable.getGL();//Get the GL object from glDrawable
myGL.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
myGL.glShadeModel (GL.GL_FASTEST);
}
public void reshape(GLDrawable glDrawable, int i, int i1, int i2, int i3)
{
GL myGL=glDrawable.getGL();
int width=canvas.getWidth();
int height=canvas.getHeight();
}
public void display(GLDrawable glDrawable)
{
GL gl=glDrawable.getGL();
GLU glu = glDrawable.getGLU();
gl.glMatrixMode(GL.GL_PROJECTION);
glu.gluPerspective(45.0, 900 / 600, 0.1, 100.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(camx, camy, camz, 0, 0, 0, 0, 1, 0);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
drawHorizPlane(gl,10,10);
drawTriangle(gl,0,0,0,1,1);
gl.glPushMatrix();
gl.glTranslatef(1, 0, -1);
drawTriangle(gl,0,0,0,1,1);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(-1, 0, -1);
drawTriangle(gl,0,0,0,1,1);
gl.glPopMatrix();
//gl.glEnd();
writeBufferToFile(glDrawable, new File("c:\\opengl"+(num++)+".png"));
}
private int num = 0;
private void drawTriangle(GL gl, int x, int y, int z, int width, int height)
{
gl.glBegin(GL.GL_TRIANGLES);
byte r,g,b;
r = (byte)255;
g = (byte)0;
b = (byte)0;
gl.glColor3ub(r,g,b);
gl.glVertex3i(x,y + height,z);
r = (byte)0;
g = (byte)255;
b = (byte)0;
gl.glColor3ub(r,g,b);
gl.glVertex3i(x + width, y - height, z);
r = (byte)0;
g = (byte)0;
b = (byte)255;
gl.glColor3ub(r,g,b);
gl.glVertex3i(x - width, y - height, z);
gl.glEnd();
}
private void drawHorizPlane(GL gl, int width, int height)
{
gl.glBegin(GL.GL_TRIANGLES);
byte r,g,b;
r = (byte)0;
g = (byte)150;
b = (byte)0;
gl.glColor3ub(r,g,b);
gl.glVertex3i(-width,0,-height);
gl.glVertex3i(width, 0, -height);
gl.glVertex3i(-width, 0, height);
r = (byte)0;
g = (byte)0;
b = (byte)150;
gl.glColor3ub(r,g,b);
gl.glVertex3i(-width, 0, height);
gl.glVertex3i(width, 0, -height);
gl.glVertex3i(width, 0, height);
gl.glEnd();
}
public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged)
{
}
private double camx = 0;
private double camy = 0;
private double camz = 6;
private class CameraLooper extends Thread
{
public void run()
{
boolean fx = true, fy = true, fz = true;
while(true)
{
if(camx >= 100 || camx <= -100)
fx = !fx;
if(camy >= 100 || camy <= -100)
fy = !fy;
if(camz >= 100 || camz <= -100)
fx = !fx;
if(fx)
camx += .01;
else
camx -= .01;
if(fy)
camy += .01;
else
camy -= .01;
if(fz)
camz += .01;
else
camz -= .01;
//repaint();
try
{
Thread.sleep(1);
}
catch(Exception e)
{
e.printStackTrace();
}
//System.out.println("new frame");
}
}
}
private void writeBufferToFile(GLDrawable drawable, File outputFile)
{
int width = drawable.getSize().width;
int height = drawable.getSize().height;
ByteBuffer pixelsRGB = BufferUtils.newByteBuffer(width * height * 3);
GL gl = drawable.getGL();
gl.glReadBuffer(GL.GL_BACK);
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
gl.glReadPixels(0, // GLint x
0, // GLint y
width, // GLsizei width
height, // GLsizei height
GL.GL_RGB, // GLenum format
GL.GL_UNSIGNED_BYTE, // GLenum type
pixelsRGB); // GLvoid *pixels
int[] pixelInts = new int[width * height];
// Convert RGB bytes to ARGB ints with no transparency. Flip image vertically by reading the
// rows of pixels in the byte buffer in reverse - (0,0) is at bottom left in OpenGL.
int p = width * height * 3; // Points to first byte (red) in each row.
int q; // Index into ByteBuffer
int i = 0; // Index into target int[]
int w3 = width*3; // Number of bytes in each row
for (int row = 0; row < height; row++) {
p -= w3;
q = p;
for (int col = 0; col < width; col++) {
int iR = pixelsRGB.get(q++);
int iG = pixelsRGB.get(q++);
int iB = pixelsRGB.get(q++);
pixelInts[i++] = 0xFF000000
| ((iR & 0x000000FF) << 16)
| ((iG & 0x000000FF) << 8)
| (iB & 0x000000FF);
}
}
BufferedImage bufferedImage =
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bufferedImage.setRGB(0, 0, width, height, pixelInts, 0, width);
try {
ImageIO.write(bufferedImage, "PNG", outputFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}