Hi,
In the process of learning OpenGL I decided I would give myself a variation on some existing examples I have looked at (such as NeHe lesson 8). Running the code I see a rotating cube with transparent textures, except they aren’t always transparent or the faces at the back seem to be missing when looking through the transparency. I just can’t work out what is happening. Follows is the code:
public class CubeChase extends Panel implements GLEventListener, Runnable {
GLU glu = new GLU();
GLCanvas canvas;
Cube cube;
float x = 0.0f;
private int[] textures = new int[3]; // Storage For 3 Textures
private float[] lightAmbient = {0.5f, 0.5f, 0.5f, 1.0f};
private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
private float[] lightPosition = {0.0f, 0.0f, 0.0f, -6.0f};
public CubeChase() {
GLCapabilities capabilities = new GLCapabilities();
canvas =
GLDrawableFactory.getFactory().createGLCanvas(capabilities);
canvas.addGLEventListener(this);
setLayout(new BorderLayout());
add(canvas);
Point3D centerPoint = new Point3D(0,0,0);
//create a cube around center point
cube = new Cube(centerPoint,2.0);
}
private boolean loadGLTextures(GLAutoDrawable gldrawable) {
TextureReader.Texture texture = null;
try {
texture = TextureReader.readTexture("data/glass.png");
} catch (IOException e) {
return false;
}
GL gl = gldrawable.getGL();
//Create Nearest Filtered Texture
gl.glGenTextures(3, textures,0); /* * */
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D,
0,
3,
texture.getWidth(),
texture.getHeight(),
0,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
texture.getPixels());
return true;
}
public void init(GLAutoDrawable drawable) {
if (!loadGLTextures(drawable)) {
System.out.println("Unable to load textures,Bailing!");
System.exit(0);
}
GL gl = drawable.getGL();
gl.glEnable(GL.GL_BLEND);
gl.glDisable(GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_TEXTURE_2D); // Enable Texture Mapping
gl.glShadeModel(GL.GL_SMOOTH); //Enables Smooth Color Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //This Will Clear The Background Color To Black
gl.glClearDepth(1.0); //Enables Clearing Of The Depth Buffer
gl.glEnable(GL.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); //The Type Of Depth Test To Do
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // Really Nice Perspective Calculations
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightAmbient,0); // Setup The Ambient Light
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, lightDiffuse,0); // Setup The Diffuse Light
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPosition,0); // Position The Light
gl.glEnable(GL.GL_LIGHT1); // Enable Light One
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f); // Full Brightness. 50% Alpha (new )
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); // Set The Blending Function For Translucency (new )
}
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
gl.glLoadIdentity();
gl.glTranslatef(0.0f,0.0f,-5.0f);
gl.glRotatef(x, 1.0f, 1.0f, 0.0f);
gl.glBindTexture(GL.GL_TEXTURE_2D, textures[0]);
Rectangle3D[] faces = cube.getFaces();
for ( int i=0; i<faces.length; i++) {
gl.glBegin(GL.GL_QUADS);
Point3D p1 = faces[i].getP1();
Point3D p2 = faces[i].getP2();
Point3D p3 = faces[i].getP3();
Point3D p4 = faces[i].getP4();
Point3D normal = findNormal(p3,p1);
gl.glNormal3d(normal.x,normal.y,normal.z);
gl.glTexCoord2f(1.0f, 1.0f);
gl.glVertex3d(p1.x,p1.y,p1.z);
gl.glTexCoord2f(1.0f, 0.0f);
gl.glVertex3d(p2.x,p2.y,p2.z);
gl.glTexCoord2f(0.0f, 0.0f);
gl.glVertex3d(p3.x,p3.y,p3.z);
gl.glTexCoord2f(0.0f, 1.0f);
gl.glVertex3d(p4.x,p4.y,p4.z);
gl.glEnd();
}
}
public static double dotProduct(Point3D p1, Point3D p2) {
return (p1.x*p2.x)+(p1.y*p2.y)+(p1.y*p2.y);
}
public static Point3D findNormal (Point3D p1, Point3D p2) {
double x = (p1.y * p2.z) - (p2.y * p1.z);
double y = (p1.z * p2.x) - (p2.z * p1.x);
double z = (p1.x * p2.y) - (p2.x * p1.y);
return new Point3D(x,y,z);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL gl = drawable.getGL(); ;
if (height == 0) height = 1;
gl.glViewport(0, 0, width, height); // Reset The Current Viewport And Perspective Transformation
gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
gl.glLoadIdentity(); // Reset The Projection Matrix
glu.gluPerspective(45.0f, width / (height*1.0f), 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
// TODO Auto-generated method stub
}
public void run () {
while (true) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
}
x+=0.05f;
canvas.repaint(0);
}
}
public static void main ( String[] args ) {
CubeChase cubeChase = new CubeChase();
Frame f = new Frame();
f.add(cubeChase);
f.setBounds(50,50,400,300);
f.setVisible(true);
(new Thread(cubeChase)).run();
}
}