From: Luke H. <lh...@us...> - 2002-11-25 06:53:12
|
Update of /cvsroot/java-game-lib/LWJGL/examples/nehe/lesson10 In directory sc8-pr-cvs1:/tmp/cvs-serv18314/lesson10 Added Files: Lesson10.java Texture.java Log Message: up we go =) --- NEW FILE: Lesson10.java --- CVS Browser: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/java-game-lib/LWJGL/examples/nehe/lesson10/Lesson10.java /* * Copyright (c) 2002 Light Weight Java Game Library Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'Light Weight Java Game Library' nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import java.nio.*; import java.io.*; import java.awt.image.BufferedImage; import java.util.regex.*; import javax.swing.JOptionPane; import javax.imageio.*; import org.lwjgl.*; import org.lwjgl.opengl.*; import org.lwjgl.input.*; /** * $Id: Lesson10.java,v 1.1 2002/11/25 06:53:09 lholden Exp $ * * Loading And Moving Through A 3D World * * Credit goes to Lionel Brits (ßetelgeuse) and Jeff Molofee (NeHe) whos tutorial this is based on * * @author Luke Holden * @version $Revision: 1.1 $ */ public class Lesson10 { private GL gl; private GLU glu; private boolean done = false; private boolean fullscreen = true; /* Blending OFF/ON? */ private boolean blend; private float heading; private float xpos; private float zpos; /* Y Rotation */ private float yrot; private float walkbias = 0.0f; private float walkbiasangle = 0.0f; private float lookupdown = 0.0f; /* Depth Into Screen */ private float z=0.0f; /* Which Filter To Use */ private int filter; /* Storage for 3 textures */ private IntBuffer textureBuf = createIntBuffer(3); private class Vertex { public float x, y, z; public float u, v; } private class Triangle { public Vertex[] vertex = new Vertex[3]; } private class Sector { public Triangle[] triangle; } Sector sector1 = new Sector(); /** Creates a new instance of Lesson */ public Lesson10() { } private void setupWorld() throws Exception { float x, y, z, u, v; String buf = ""; Matcher m; /* Example: NUMPOLLIES 36 */ Pattern numPattern = Pattern.compile(".*NUMPOLLIES\\s*([0-9]+)"); /* Example: -3.0 0.0 -3.0 0.0 6.0 */ Pattern pollyPattern = Pattern.compile("\\s*([\\-]?[0-9]+[\\.]{1}[0-9]+)" + "\\s+([\\-]?[0-9]+[\\.]{1}[0-9]+)" + "\\s+([\\-]?[0-9]+[\\.]{1}[0-9]+)" + "\\s+([\\-]?[0-9]+[\\.]{1}[0-9]+)" + "\\s+([\\-]?[0-9]+[\\.]{1}[0-9]+)"); try { BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("data/world.txt"))); /* Get the number of triangles */ while ((buf = in.readLine()) != null) { /* Find a match for numPattern */ m = numPattern.matcher(buf); if (m.matches()) { sector1.triangle = new Triangle[Integer.parseInt(m.group(1))]; break; } } if (buf == null) { throw new Exception ("Got to end of file before finding pattern: " + numPattern.pattern()); } /* Read the rest of the data into the world */ for (int loop = 0; loop < sector1.triangle.length; loop++){ sector1.triangle[loop] = new Triangle(); for (int vert = 0; vert < 3; vert++) { while ((buf = in.readLine()) != null) { m = pollyPattern.matcher(buf); if (m.matches()) { sector1.triangle[loop].vertex[vert] = new Vertex(); sector1.triangle[loop].vertex[vert].x = Float.parseFloat(m.group(1)); sector1.triangle[loop].vertex[vert].y = Float.parseFloat(m.group(2)); sector1.triangle[loop].vertex[vert].z = Float.parseFloat(m.group(3)); sector1.triangle[loop].vertex[vert].u = Float.parseFloat(m.group(4)); sector1.triangle[loop].vertex[vert].v = Float.parseFloat(m.group(5)); break; } } if (buf == null) { throw new Exception ("Got to end of file before finding pattern: " + pollyPattern.pattern()); } } } in.close(); } catch (Exception e) { throw new Exception("Problem setting up the world", e); } } /* A javafied version of AUX_RGBImageRec *LoadBMP(char*); */ private Texture loadImage(String filename) throws Exception { Texture texture = null; BufferedImage tmpImg = null; /* normally I would use StringUtils.isValid(String) from the jakarta commons lib, but thats beyond the scope of this lesson */ if ((filename != null) && (filename.trim() != "")) { try { InputStream is = getClass().getResourceAsStream(filename); tmpImg = (BufferedImage) ImageIO.read(is); if (tmpImg == null) { throw new Exception("Error: Got null from ImageIO.read()"); } texture = new Texture(tmpImg); } catch ( Exception e ) { throw new Exception("Problem loading bitmap", e); } } else { throw new Exception("Error: file name is not valid!"); } return texture; } /* Load Bitmaps And Convert To Textures */ private void loadGLTextures() throws Exception { /* Create Storage Space For The Texture */ Texture[] textureImage = new Texture[1]; /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */ try { textureImage[0] = loadImage("data/mud.png"); if (textureImage[0] == null) { throw new Exception("Error: got null from loadBmp()!"); } /* Create Three Textures */ gl.genTextures(3, Sys.getDirectBufferAddress(textureBuf)); /* Create Nearest Filtered Texture */ gl.bindTexture(GL.TEXTURE_2D, textureBuf.get(0)); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); gl.texImage2D(GL.TEXTURE_2D, 0, 3, textureImage[0].getWidth(), textureImage[0].getHeight(), 0, GL.RGB, GL.UNSIGNED_BYTE, textureImage[0].getPtr()); /* Create Linear Filtered Texture */ gl.bindTexture(GL.TEXTURE_2D, textureBuf.get(1)); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR); gl.texImage2D(GL.TEXTURE_2D, 0, 3, textureImage[0].getWidth(), textureImage[0].getHeight(), 0, GL.RGB, GL.UNSIGNED_BYTE, textureImage[0].getPtr()); /* Create Linear Filtered Texture */ gl.bindTexture(GL.TEXTURE_2D, textureBuf.get(2)); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_NEAREST); glu.build2DMipmaps(GL.TEXTURE_2D, 3, textureImage[0].getWidth(), textureImage[0].getHeight(), GL.RGB, GL.UNSIGNED_BYTE, textureImage[0].getPtr()); } catch (Exception e) { throw new Exception("Problem loading textures", e); } } private void resizeGLScene(int width, int height) { /* Reset The Current Viewport */ gl.viewport(0, 0, width, height); /* Select The Projection Matrix */ gl.matrixMode(GL.PROJECTION); /* Reset The Projection Matrix */ gl.loadIdentity(); /* Calculate The Aspect Ratio Of The Window */ glu.perspective(45.0f, ((float) Display.getWidth()) / ((float) Display.getHeight()), 0.1f, 100.0f); /* Select The Modelview Matrix */ gl.matrixMode(GL.MODELVIEW); /* Reset The Modelview Matrix */ gl.loadIdentity(); } private void initGL() throws Exception{ /* Jump To Texture Loading Routine */ try { loadGLTextures(); /* Enable Texture Mapping */ gl.enable(GL.TEXTURE_2D); /* Blending Function For Translucency Based On Source Alpha Value ( NEW ) */ gl.blendFunc(GL.SRC_ALPHA, GL.ONE); /* Black Background */ gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); /* Depth Buffer Setup */ gl.clearDepth(1.0f); /* The Type Of Depth Test To Do */ gl.depthFunc(GL.LESS); /* Enables Depth Testing */ gl.enable(GL.DEPTH_TEST); /* Enables Smooth Shading */ gl.shadeModel(GL.SMOOTH); /* Really Nice Perspective Calculations */ gl.hint(GL.PERSPECTIVE_CORRECTION_HINT, GL.NICEST); setupWorld(); } catch (Exception e) { throw new Exception("Problem initialising GL", e); } } private boolean drawGLScene() { float x_m, y_m, z_m, u_m, v_m; float xtrans = -xpos; float ztrans = -zpos; float ytrans = -walkbias - 0.25f; float sceneroty = 360.0f - yrot; /* Clear The Screen And The Depth Buffer */ gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); /* Reset The Current Modelview Matrix */ gl.loadIdentity(); gl.rotatef(lookupdown, 1.0f, 0, 0); gl.rotatef(sceneroty, 0, 1.0f, 0); gl.translatef(xtrans, ytrans, ztrans); gl.bindTexture(GL.TEXTURE_2D, textureBuf.get(filter)); for (int loop_m = 0; loop_m < sector1.triangle.length; loop_m++) { gl.begin(GL.TRIANGLES); gl.normal3f(0.0f, 0.0f, 1.0f); x_m = sector1.triangle[loop_m].vertex[0].x; y_m = sector1.triangle[loop_m].vertex[0].y; z_m = sector1.triangle[loop_m].vertex[0].z; u_m = sector1.triangle[loop_m].vertex[0].u; v_m = sector1.triangle[loop_m].vertex[0].v; gl.texCoord2f(u_m, v_m); gl.vertex3f(x_m, y_m, z_m); x_m = sector1.triangle[loop_m].vertex[1].x; y_m = sector1.triangle[loop_m].vertex[1].y; z_m = sector1.triangle[loop_m].vertex[1].z; u_m = sector1.triangle[loop_m].vertex[1].u; v_m = sector1.triangle[loop_m].vertex[1].v; gl.texCoord2f(u_m, v_m); gl.vertex3f(x_m, y_m, z_m); x_m = sector1.triangle[loop_m].vertex[2].x; y_m = sector1.triangle[loop_m].vertex[2].y; z_m = sector1.triangle[loop_m].vertex[2].z; u_m = sector1.triangle[loop_m].vertex[2].u; v_m = sector1.triangle[loop_m].vertex[2].v; gl.texCoord2f(u_m, v_m); gl.vertex3f(x_m, y_m, z_m); gl.end(); } return true; } public void killGLWindow() { Keyboard.destroy(); gl.destroy(); Display.destroy(); } public void createGLWindow(int width, int height, int bits, boolean fullscreenflag) throws Exception { fullscreen = fullscreenflag; try { Display.create(new DisplayMode(width, height, bits, 60), fullscreenflag); gl = new GL(bits, 0, bits, 8); gl.create(); glu = new GLU(gl); Keyboard.create(); Keyboard.enableBuffer(); resizeGLScene(Display.getWidth(), Display.getHeight()); initGL(); } catch (Exception e) { throw new Exception("Problem initialising Lesson", e); } } public void start() throws Exception { try { createGLWindow(640, 480, 16, fullscreen); while (!done) { loop(); } killGLWindow(); } catch (Exception e) { throw new Exception("Problem starting loop", e); } } private void loop() { drawGLScene(); gl.swapBuffers(); /* Keys that have a constant effect */ Keyboard.poll(); if (Keyboard.isKeyDown(Keyboard.KEY_PRIOR)) { z-=0.02f; lookupdown-= 1.0f; } if (Keyboard.isKeyDown(Keyboard.KEY_NEXT)) { z+=0.02f; lookupdown+= 1.0f; } if (Keyboard.isKeyDown(Keyboard.KEY_UP)) { xpos -= org.lwjgl.Math.sin(heading) * 0.05f; zpos -= org.lwjgl.Math.cos(heading) * 0.05f; if (walkbiasangle >= 359.0f) { walkbiasangle = 0.0f; } else { walkbiasangle+= 10; } walkbias = org.lwjgl.Math.sin(walkbiasangle) / 20.0f; } if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { xpos += org.lwjgl.Math.sin(heading) * 0.05f; zpos += org.lwjgl.Math.cos(heading) * 0.05f; if (walkbiasangle <= 1.0f) { walkbiasangle = 359.0f; } else { walkbiasangle-= 10; } walkbias = org.lwjgl.Math.sin(walkbiasangle) / 20.0f; } if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) { heading -= 1.0f; yrot = heading; } if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) { heading += 1.0f; yrot = heading; } /* Keys that have a toggle effect */ Keyboard.read(); for (int i = 0; i < Keyboard.getNumKeyboardEvents(); i++) { Keyboard.next(); if (Keyboard.key == Keyboard.KEY_ESCAPE && Keyboard.state) { done = true; } // /* F1 switch between fullscreen/windowed is buggy... // * So for now, we are leaving this ability disabled */ // if (Keyboard.key == Keyboard.KEY_F1 && Keyboard.state) { // try { // killGLWindow(); // fullscreen=!fullscreen; // createGLWindow(640, 480, 16, fullscreen); // } // catch (Exception e) { // /* We dont want to put exceptions into our loop... so */ // e.printStackTrace(); // System.exit(1); // } // } if (Keyboard.key == Keyboard.KEY_B && Keyboard.state) { blend=!blend; if(blend) { /* Turn Blending On */ gl.enable(GL.BLEND); /* Turn Depth Testing Off */ gl.disable(GL.DEPTH_TEST); } else { /* Turn Blending Off */ gl.disable(GL.BLEND); /* Turn Depth Testing On */ gl.enable(GL.DEPTH_TEST); } } if (Keyboard.key == Keyboard.KEY_F && Keyboard.state) { filter+=1; if (filter>2) { filter=0; } } } } private IntBuffer createIntBuffer(int size) { ByteBuffer temp = ByteBuffer.allocateDirect(4 * size); temp.order(ByteOrder.nativeOrder()); return temp.asIntBuffer(); } private FloatBuffer createFloatBuffer(int size) { ByteBuffer temp = ByteBuffer.allocateDirect(4 * size); temp.order(ByteOrder.nativeOrder()); return temp.asFloatBuffer(); } public static void main(String[] arguments) { int err = 0; Lesson10 lesson = new Lesson10(); try { lesson.start(); } catch (Exception e) { err = 1; e.printStackTrace(); } System.exit(err); } } --- NEW FILE: Texture.java --- CVS Browser: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/java-game-lib/LWJGL/examples/nehe/lesson10/Texture.java /* * Copyright (c) 2002 Light Weight Java Game Library Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'Light Weight Java Game Library' nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import java.nio.*; import java.awt.image.*; import java.awt.geom.*; import org.lwjgl.*; import org.lwjgl.opengl.*; import org.lwjgl.input.*; /** * $Id: Texture.java,v 1.1 2002/11/25 06:53:09 lholden Exp $ * * Just a small container class for holding texture data * * @author Luke Holden * @version $Revision: 1.1 $ */ public class Texture { private ByteBuffer data; private int height; private int width; /** Creates a new instance of Texture */ public Texture(BufferedImage tmpImg) { width = tmpImg.getWidth(); height = tmpImg.getWidth(); /* flip the image, so it displays right * There might be a way to do this differently... */ AffineTransform tx = AffineTransform.getScaleInstance(1, -1); tx.translate(0, -tmpImg.getHeight(null)); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); tmpImg = op.filter(tmpImg, null); data = ByteBuffer.allocateDirect(4 * width * height); data.order(ByteOrder.nativeOrder()); data.clear(); byte[] byteData = (byte[])tmpImg.getRaster().getDataElements(0, 0, width, height, null); data.put(byteData); data.flip(); } public int getData() { return data.get(0); } public ByteBuffer getBuffer() { return data; } public int getPtr() { return Sys.getDirectBufferAddress(data); } public int getHeight() { return height; } public int getWidth() { return width; } } |