import java.nio.*; // Native IO buffers: LWJGL uses these to efficiently exchange data with system memory import java.util.*; import org.lwjgl.Sys; import org.lwjgl.opengl.*; import org.lwjgl.opengl.glu.GLU; import org.lwjgl.opengl.glu.Sphere; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.glu.*; /** * Circle crawling in random direction, turning random colors and leaving traces on the screen combines lighting and screen saving -- draws in spheres, circles and squares Press 's' to toggle sqare mode, and 'f' to toggle circle mode */ public class circles5 { private boolean done = false; private final String windowTitle = "Crawlies"; private DisplayMode displayMode; double startTime, currentTime; Random rn = new Random(); int randx =0, randy = 0, randz =0; int randr =0, randg = 0, randb = 0; float r = .5f, g = .1f, b = .1f; float x = 0, y = 0, z = 0; // For copying screen image to a texture int screenTextureSize = 1024; // how large should texture be to hold screen // will hold screen image as texture int screenTextureHandle; boolean square = false, flat = false, ball = true; Sphere s = new Sphere(); // color of light source float lightDiffuse[] = { 1f, .6f, .6f, 1f }; // direct light (reddish) float lightSpecular[] = { 1f, .6f, .6f, 1f }; float lightAmbient[] = { .5f, .1f, .1f, 1f}; // light position: if last value is 0, then this describes light direction. If 1, then light position. float lightPosition[] = {-2, 4, 3, 0}; // Material for planet GLMaterial material = new GLMaterial(); float mtlDiffuse[] = { r, g, b, .2f }; // purple float mtlAmbient[] = { .1f, 0f, .2f, 1f }; // dark purple float mtlSpecular[] = { .6f, .6f, .6f, 1f }; // light gray: reflective float mtlShininess = 100f; // 0=no shine, 127=max shine /** * Main function just creates and runs the application. */ public static void main(String args[]) { circles5 app = new circles5(); app.run(); } /** * Initialize the app, then sit in a render loop until done==true. */ public void run() { try { init(); while (!done) { mainloop(); render(); Display.update(); } cleanup(); } catch (Exception e) { e.printStackTrace(); System.exit(0); } } /** * Initialize the environment * @throws Exception */ private void init() throws Exception { initDisplay(); initGL(); startTime = currentTime = getTimeInMillis(); // allocate a texture big enough to hold screen image // the texure will be square, the dimensions will be some power of two, as // large or larger than the width of the screen. screenTextureHandle = makeTextureForScreen(displayMode.getWidth()); // capture the screen now to initialize the texture image // It's a good idea to call glClear() before capturing the screen for the first time. frameSave(screenTextureHandle); } /** * Create an OpenGL display, in this case a fullscreen window. * @throws Exception */ private void initDisplay() throws Exception { // set to full screen, no chrome Display.setFullscreen(false); // get all possible display resolutions DisplayMode d[] = Display.getAvailableDisplayModes(); // find a resolution we like for (int i = 0; i < d.length; i++) { if (d[i].getWidth() == 800 && d[i].getHeight() == 600 && d[i].getBitsPerPixel() == 32) { displayMode = d[i]; break; } } Display.setVSyncEnabled(true); Display.setFullscreen(false); // set the display to the resolution we picked Display.setDisplayMode(displayMode); Display.setTitle(windowTitle); // create the window Display.create(); } /** * Initialize OpenGL * */ private void initGL() { // make sure OpenGL correctly layers objects GL11.glEnable(GL11.GL_DEPTH_TEST); // OpenGL won't draw backward facing triangles ("back faces") GL11.glEnable(GL11.GL_CULL_FACE); // set the background color GL11.glClearColor(0f, 0f, .07f, 1); // blending GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // Force normals to length 1 GL11.glEnable(GL11.GL_NORMALIZE); GL11.glEnable(GL11.GL_LIGHTING); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); setLight( GL11.GL_LIGHT0, lightDiffuse, lightAmbient, lightSpecular, lightPosition ); // need textures on for frameDraw() to work GL11.glEnable(GL11.GL_TEXTURE_2D); } /** * Handle keyboard input. Just check for escape key or user * clicking to close the window. */ private void mainloop() { if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { // Escape is pressed done = true; } if(Display.isCloseRequested()) { // Window is closed done = true; } if(Keyboard.isKeyDown(Keyboard.KEY_S)){ square = true; flat = false; ball = false; } if(Keyboard.isKeyDown(Keyboard.KEY_F)){ flat = true; square = false; ball = false; } if(Keyboard.isKeyDown(Keyboard.KEY_B)){ ball = true; square = false; flat = false; } } // float backZ=1, frontZ=0; /** * Render the scene. */ private void render() { // NOTE: This switches matrix mode to PROJECTION frameDraw(screenTextureHandle); // Select the Projection Matrix (controls perspective) GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); // Reset The Projection Matrix // Define perspective GLU.gluPerspective( 45.0f, // Field Of View (float)displayMode.getWidth() / (float)displayMode.getHeight(), // aspect ratio 0.1f, // near Z clipping plane 100.0f); // far Z clipping plane // Reset The Model view Matrix GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glLoadIdentity(); // Where is the 'eye' GLU.gluLookAt( 0f, 0, 10, // eye position 0, 0f, 0f, // target to look at 0f, 1f, 0f); // which way is up GL11.glMatrixMode(GL11.GL_MODELVIEW); // Clear screen and depth buffer GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT); currentTime = getTimeInMillis(); if(currentTime - startTime > 100){ if(ball) drawCircles(); else if(square) drawSquares(); else if (flat) drawFlat(); startTime = currentTime; } // save the screen image to a texture // do this after you've drawn everything you want to save frameSave(screenTextureHandle); } private void drawFlat() { //System.out.println(x+" "+ y +" "+z); switch(randx){ case 0: x -=.2f; break; case 1: x = 0; break; case 2: x += .2f; break; case 3: x -=.4f; break; case 4: x += .3f; break; case 5: x += .4f; break; } switch(randy){ case 0: y += .2f; break; case 1: y = 0; break; case 2: y -= .2f; break; case 3: y -=.4f; break; case 4: y += .3f; break; case 5: y += .4f; break; } switch(randz){ case 0: z -= .2f; break; case 1: z = 0; break; case 2: z += .2f; break; case 3: z -=.4f; break; case 4: z += .3; break; case 5: z += .4f; break; } switch(randr){ case 0: r -= .05f; break; case 1: break; case 2: r += .05f; break; } switch(randg){ case 0: g -= .05f; break; case 1: break; case 2: g += .05f; break; } switch(randb){ case 0: b -= .05f; break; case 1: break; case 2: b += .05f; break; } if(r <0) r =0; if(r>1) r =1; if(g<0) g =0; if(g>1) g =1; if(b<0) b =0; if(b>1) b =1; /* if(x>200) x=200; if(x<-200) x=-200; if(y>200) y=200; if(y<-200) y=-200; if(z>90) z=90; if(z<1) z=1;*/ GL11.glDisable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_BLEND); GL11.glTranslatef(x, y, z); GL11.glColor4f(r, g, b, .02f); renderSphere(); randx = rn.nextInt(6); randy = rn.nextInt(6); randz = rn.nextInt(6); randr = rn.nextInt(3); randg = rn.nextInt(3); randb = rn.nextInt(3); } private void drawCircles() { //System.out.println(x+" "+ y +" "+z); mtlDiffuse[0] = r; mtlDiffuse[1] = g; mtlDiffuse [2] = b; mtlDiffuse [3] = .1f; mtlAmbient[0] = r/4; mtlAmbient[1] = g/4; mtlAmbient[2] = b/4; mtlAmbient [3] = 1f; // "planet" material settings material.setSurfaceColorLit(mtlDiffuse); material.setSurfaceColorShadow(mtlAmbient); material.setReflectionColor(mtlSpecular); material.setShininess(mtlShininess); material.apply(); switch(randx){ case 0: x -=.2f; break; case 1: x = 0; break; case 2: x += .2f; break; case 3: x -=.4f; break; case 4: x += .3f; break; case 5: x += .4f; break; } switch(randy){ case 0: y += .2f; break; case 1: y = 0; break; case 2: y -= .2f; break; case 3: y -=.4f; break; case 4: y += .3f; break; case 5: y += .4f; break; } switch(randz){ case 0: z -= .2f; break; case 1: z = 0; break; case 2: z += .2f; break; case 3: z -=.4f; break; case 4: z += .3; break; case 5: z += .4f; break; } switch(randr){ case 0: r -= .05f; break; case 1: break; case 2: r += .05f; break; } switch(randg){ case 0: g -= .05f; break; case 1: break; case 2: g += .05f; break; } switch(randb){ case 0: b -= .05f; break; case 1: break; case 2: b += .05f; break; } if(r< .1f) r =.1f; if(r>1) r =1; if(g< .1f) g =.1f; if(g>1) g =1; if(b<0) b =0; if(b>1) b =1; GL11.glEnable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_LIGHTING); GL11.glTranslatef(x, y, z); renderSphere(); randx = rn.nextInt(6); randy = rn.nextInt(6); randz = rn.nextInt(6); randr = rn.nextInt(3); randg = rn.nextInt(3); randb = rn.nextInt(3); } private void drawSquares() { //System.out.println(x+" "+ y +" "+z); switch(randx){ case 0: x -=.2f; break; case 1: x = 0; break; case 2: x += .2f; break; case 3: x -=.4f; break; case 4: x += .3f; break; case 5: x += .4f; break; } switch(randy){ case 0: y += .2f; break; case 1: y = 0; break; case 2: y -= .2f; break; case 3: y -=.4f; break; case 4: y += .3f; break; case 5: y += .4f; break; } switch(randz){ case 0: z -= .2f; break; case 1: z = 0; break; case 2: z += .2f; break; case 3: z -=.4f; break; case 4: z += .3; break; case 5: z += .4f; break; } switch(randr){ case 0: r -= .05f; break; case 1: break; case 2: r += .05f; break; } switch(randg){ case 0: g -= .05f; break; case 1: break; case 2: g += .05f; break; } switch(randb){ case 0: b -= .05f; break; case 1: break; case 2: b += .05f; break; } if(r
<0) r =0; if(r>1) r =1; if(g<0) g =0; if(g>1) g =1; if(b<0) b =0; if(b>1) b =1; /* if(x>200) x=200; if(x<-200) x=-200; if(y>200) y=200; if(y<-200) y=-200; if(z>90) z=90; if(z<1) z=1;*/ GL11.glDisable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_BLEND); GL11.glTranslatef(x, y, z); GL11.glColor4f(r, g, b, .02f); drawQuad(); randx = rn.nextInt(6); randy = rn.nextInt(6); randz = rn.nextInt(6); randr = rn.nextInt(3); randg = rn.nextInt(3); randb = rn.nextInt(3); } /** * Cleanup all the resources. * */ private void cleanup() { Display.destroy(); } public void drawQuad() { GL11.glBegin(GL11.GL_QUADS); { GL11.glTexCoord2f(0, 0); GL11.glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left GL11.glTexCoord2f(1, 0); GL11.glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right GL11.glTexCoord2f(1, 1); GL11.glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right GL11.glTexCoord2f(0, 1); GL11.glVertex3f(-1.0f, 1.0f, 0.0f); // Top left } GL11.glEnd(); } /** * Simple way to setup a light. Uses same color for direct light (diffuse), * reflected highlight (specular) and scattered light (ambient). Ambient * color is darkened to 1/4 of the light color. * @param GLLightHandle * @param color * @param position */ public static void setLight(int GLLightHandle, float[] color, float[] position ) { float[] ambientLight = {color[0]/4f, color[1]/4f, color[2]/4f, color[3]/4f}; FloatBuffer lightColor = allocFloats(color); FloatBuffer ambientColor = allocFloats(ambientLight); FloatBuffer ltPosition = allocFloats(position); GL11.glLight(GLLightHandle, GL11.GL_DIFFUSE, lightColor); // color of the direct illumination GL11.glLight(GLLightHandle, GL11.GL_SPECULAR, lightColor); // color of the highlight (same as direct light) GL11.glLight(GLLightHandle, GL11.GL_AMBIENT, ambientColor); // color of the scattered light (darker) GL11.glLight(GLLightHandle, GL11.GL_POSITION, ltPosition); GL11.glEnable(GLLightHandle); // Enable the light (GL_LIGHT1 - 7) } /** * Set the color of a 'positional' light (a light that has a specific * position within the scene).
*
* Params:
* an OpenGL light number (GL11.GL_LIGHT1),
* 'Diffuse': color of direct light from this source,
* 'Ambient': color of scattered light from this source
* 'Specular': color of this light reflected off a surface,
* position.
*/ public static void setLight( int GLLightHandle, float[] diffuseLightColor, float[] ambientLightColor, float[] specularLightColor, float[] position ) { FloatBuffer ltDiffuse = allocFloats(diffuseLightColor); FloatBuffer ltAmbient = allocFloats(ambientLightColor); FloatBuffer ltSpecular = allocFloats(specularLightColor); FloatBuffer ltPosition = allocFloats(position); GL11.glLight(GLLightHandle, GL11.GL_DIFFUSE, ltDiffuse); // color of the direct illumination GL11.glLight(GLLightHandle, GL11.GL_AMBIENT, ltAmbient); // color of the reflected light GL11.glLight(GLLightHandle, GL11.GL_SPECULAR, ltSpecular); // color of the highlight (same as direct light) GL11.glLight(GLLightHandle, GL11.GL_POSITION, ltPosition); GL11.glEnable(GLLightHandle); // Enable the light (GL_LIGHT1 - 7) //GL11.glLightf(GLLightHandle, GL11.GL_QUADRATIC_ATTENUATION, .005F); // how light beam drops off } /** * Set the color of the Global Ambient Light. Affects all objects in * scene regardless of their placement. */ public static void setAmbientLight(float[] ambientLightColor) { FloatBuffer ltAmbient = allocFloats(ambientLightColor); GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, ltAmbient); } public static final int SIZE_FLOAT = 4; public static FloatBuffer allocFloats(int howmany) { return ByteBuffer.allocateDirect(howmany * SIZE_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); } public static FloatBuffer allocFloats(float[] floatarray) { FloatBuffer fb = ByteBuffer.allocateDirect(floatarray.length * SIZE_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); fb.put(floatarray).flip(); return fb; } /** * call the LWJGL Sphere class to create sphere geometry, * with normals */ public static void renderSphere() { Sphere s = new Sphere(); // an LWJGL class for drawing sphere s.setOrientation(GLU.GLU_OUTSIDE); // normals point outwards s.setTextureFlag(true); // generate texture coords s.draw(1, 48, 48); // run GL commands to draw sphere } /** * Create a texture from the given image. */ public static int makeTexture(GLImage textureImg) { if ( textureImg == null ) { return 0; } else { return makeTexture(textureImg.pixelBuffer, textureImg.w, textureImg.h); } } /** * Create a texture from the given pixels in RGBA format. Set the texture * to repeat in both directions and use LINEAR for magnification. * @return the texture handle */ public static int makeTexture(ByteBuffer pixels, int w, int h) { // get a new empty texture int textureHandle = allocateTexture(); // 'select' the new texture by it's handle GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle); // set texture parameters GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); //GL11.GL_NEAREST); // Create the texture from pixels GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, w, h, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels); return textureHandle; } public static final int SIZE_INT = 4; public static IntBuffer allocInts(int howmany) { return ByteBuffer.allocateDirect(howmany * SIZE_INT).order(ByteOrder.nativeOrder()).asIntBuffer(); } public float getZdepth(float x, float y, float z) { Vector3D projectedPoint = projectPoint(x,y,z); return projectedPoint.z(); } // in screen space, Z is a number from 0-1 (not same as geometry Z) public Vector3D projectPoint(float x, float y, float z) { float[] projectedXYZ = new float[3]; float[][] modelMatrix = getModelviewMatrixA(); float[][] projectionMatrix = getProjectionMatrixA(); int[] viewport = getViewportA(); Vector3D projectedPoint; // project point to screen space and return x,y,z GLU.gluProject(x, y, z, modelMatrix, projectionMatrix, viewport, projectedXYZ); projectedPoint = new Vector3D(projectedXYZ[0], // screen x projectedXYZ[1], // screen y projectedXYZ[2]); // z depth value is 0.0 - 1.0 return projectedPoint; } public static FloatBuffer getModelviewMatrix() { FloatBuffer bufferModelviewMatrix = allocFloats(16); bufferModelviewMatrix.clear(); GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, bufferModelviewMatrix); return bufferModelviewMatrix; } public static FloatBuffer getProjectionMatrix() { FloatBuffer bufferProjectionMatrix = allocFloats(16); bufferProjectionMatrix.clear(); GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, bufferProjectionMatrix); return bufferProjectionMatrix; } public static IntBuffer getViewport() { IntBuffer bufferViewport = allocInts(16); bufferViewport.clear(); GL11.glGetInteger(GL11.GL_VIEWPORT, bufferViewport); return bufferViewport; } /** * Copy a FloatBuffer matrix to a 4x4 float array. The 4x4 float array * is passed in, not allocated inside the function, to reduce garbage * collection needs. * * @param fb source FloatBuffer containing 16 values of 4x4 matrix * @param fa target float[4][4] array will hold the matrix */ public static /*float[][]*/ void getMatrixAsArray(FloatBuffer fb , float[][] fa) { //float[][] fa = new float[4][4]; fa[0][0] = fb.get(); fa[0][1] = fb.get(); fa[0][2] = fb.get(); fa[0][3] = fb.get(); fa[1][0] = fb.get(); fa[1][1] = fb.get(); fa[1][2] = fb.get(); fa[1][3] = fb.get(); fa[2][0] = fb.get(); fa[2][1] = fb.get(); fa[2][2] = fb.get(); fa[2][3] = fb.get(); fa[3][0] = fb.get(); fa[3][1] = fb.get(); fa[3][2] = fb.get(); fa[3][3] = fb.get(); //return fa; } // Arrays to hold commonly used matrices // For memory efficiency, instantiate these once and reuse. // see getModelviewMatrixA(), getMatrixAsArray() and project(). public static float[][] modelViewMatrix = new float[4][4]; public static float[][] projectionMatrix = new float[4][4]; public static int[] viewport = new int[4]; /** * Return the modelview matrix as a 4x4 float array */ public static float[][] getModelviewMatrixA() { FloatBuffer b = getModelviewMatrix(); // get matrix in FloatBuffer getMatrixAsArray(b,modelViewMatrix); // copy into array return modelViewMatrix; // return the array } /** * Return the projection matrix as a 4x4 float array */ public static float[][] getProjectionMatrixA() { FloatBuffer b = getProjectionMatrix(); getMatrixAsArray(b,projectionMatrix); return projectionMatrix; } /** * Return the Viewport data as array of 4 floats */ public static int[] getViewportA() { IntBuffer ib = getViewport(); int[] viewport = new int[4]; viewport[0] = ib.get(0); viewport[1] = ib.get(1); viewport[2] = ib.get(2); viewport[3] = ib.get(3); return viewport; } public static long ticksPerSecond = 0; // used to calculate time public static double getTimeInSeconds() { if (ticksPerSecond == 0) { // initialize ticksPerSecond ticksPerSecond = Sys.getTimerResolution(); } return (((double)Sys.getTime())/(double)ticksPerSecond); } /** * Convenience function returns time in milliseconds. Calls * getTimeInSeconds(). */ public static double getTimeInMillis() { return (double) (getTimeInSeconds() * 1000.0); } /** * Allocate a texture (glGenTextures) and return the handle to it. */ public static int allocateTexture() { IntBuffer textureHandle = allocInts(1); GL11.glGenTextures(textureHandle); return textureHandle.get(0); } public static final int SIZE_BYTE = 4; public static ByteBuffer allocBytes(int howmany) { return ByteBuffer.allocateDirect(howmany * SIZE_BYTE).order(ByteOrder.nativeOrder()); } public int makeTextureForScreen(int screenSize) { // get a texture size big enough to hold screen (512, 1024, 2048 etc.) screenTextureSize = getPowerOfTwoBiggerThan(screenSize); System.out.println("GLApp.makeTextureForScreen(): made texture for screen with size " + screenTextureSize); // get a new empty texture int textureHandle = allocateTexture(); ByteBuffer pixels = allocBytes(screenTextureSize*screenTextureSize*SIZE_INT); // 'select' the new texture by it's handle GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle); // set texture parameters GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); // use GL_NEAREST to prevent blurring during frequent screen restores GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); // Create the texture from pixels: use GL_RGBA8 to insure exact color copy GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, screenTextureSize, screenTextureSize, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels); return textureHandle; } /** * Find a power of two big enough to hold the given dimension. Ie. * to make a texture big enough to hold a screen image for an 800x600 * screen getPowerOfTwoBiggerThan(800) will return 1024. *

* @see makeTextureForScreen() * @param dimension * @return a power of two bigger than the given dimension */ public static int getPowerOfTwoBiggerThan(int dimension) { for (int exp=1; exp <= 32; exp++) { if (dimension <= Math.pow(2, exp)) { return (int)Math.pow(2, exp); } } return 0; } /** * Save entire screen image to a texture. Will copy entire screen even * if a viewport is in use. Texture param must be large enough to hold * screen image (see makeTextureForScreen()). * * @param txtrHandle texture where screen image will be stored * @see frameDraw() * @see makeTextureForScreen() */ public void frameSave(int txtrHandle) { GL11.glColor4f(1,1,1,1); // turn off alpha and color tints GL11.glReadBuffer(GL11.GL_BACK); GL11.glBindTexture(GL11.GL_TEXTURE_2D,txtrHandle); // Copy screen to texture GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0,0, 0,0, displayMode.getWidth(),displayMode.getHeight()); //!!! whole frame } /** * Draw the screen-sized image over entire screen area. The screen image * is stored in the given texture at 0,0 (see frameSave()) and has the * same dimensions as the current display mode (DM.getWidth(), DM.getHeight()). *

* Reset the viewport and ortho mode to full screen (viewport may be * different proportion than screen if custom aspectRatio is set). Draw the * quad the same size as texture so no stretching or compression of image. * * @param txtrHandle */ public void frameDraw(int txtrHandle) { // keep it opaque, be sure texturing is enabled GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); // set viewport to full screen (need to handle custom shaped viewport) //GL11.glViewport(0, 0,displayMode.getWidth(), displayMode.getHeight()); // set ortho view to full screen and draw quad GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glPushMatrix(); // preserve current projection { GL11.glLoadIdentity(); // clear the projection matrix GL11.glOrtho(0, displayMode.getWidth(), 0, displayMode.getHeight(), -1, 1); // turn on 2D mode full screen GL11.glColor4f(1,1,1,1); drawQuad(txtrHandle, 0, 0, screenTextureSize, screenTextureSize); // draw the full screen image } GL11.glPopMatrix(); // restore projection view // put these settings back on GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_BLEND); } /** * Draw arbitrary sized quad at given xy coords, Apple the given texture. */ public static void drawQuad(int textureHandle, int x, int y, float w, float h) { GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle); // draw textured quad GL11.glBegin(GL11.GL_QUADS); GL11.glTexCoord2f(0f, 0f); GL11.glVertex3f( (float)x, (float)y, (float)0); GL11.glTexCoord2f(1f, 0f); GL11.glVertex3f( (float)x+w, (float)y, (float)0); GL11.glTexCoord2f(1f, 1f); GL11.glVertex3f( (float)x+w, (float)y+h, (float)0); GL11.glTexCoord2f(0f, 1f); GL11.glVertex3f( (float)x, (float)y+h, (float)0); GL11.glEnd(); } }