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 */ public class circles { 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; Sphere s = new Sphere(); float cameraX = 0; float cameraZ = 10; float cameraY = 0; /** * Main function just creates and runs the application. */ public static void main(String args[]) { circles app = new circles(); 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(); } /** * 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.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } /** * 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; } } // float backZ=1, frontZ=0; /** * Render the scene. */ private void render() { if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){ cameraX += .1; } if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){ cameraX -= .1; } if(Keyboard.isKeyDown(Keyboard.KEY_UP)){ cameraZ -= .1; } if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){ cameraZ += .1; } if(Keyboard.isKeyDown(Keyboard.KEY_A)){ cameraY -= .1; } if(Keyboard.isKeyDown(Keyboard.KEY_S)){ cameraY += .1; } // 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 // Where is the 'eye' GLU.gluLookAt( 0f, cameraY, cameraZ, // eye position cameraX, 0f, 0f, // target to look at 0f, 1f, 0f); // which way is up GL11.glMatrixMode(GL11.GL_MODELVIEW); // System.out.println(cameraX); // Clear screen and depth buffer // GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT); currentTime = getTimeInMillis(); if(currentTime - startTime > 100){ drawCircles(); // drawSun(); // drawGlare(); startTime = currentTime;} } private void drawCircles() { float x = 0, y = 0, z = 0; switch(randx){ case 0: x = -.2f; break; case 1: x = 0; break; case 2: x = .2f; break; } switch(randy){ case 0: y = -.2f; break; case 1: y = 0; break; case 2: y = .2f; break; } switch(randz){ case 0: z = -.2f; break; case 1: z = 0; break; case 2: z = .2f; 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; GL11.glEnable(GL11.GL_BLEND); GL11.glTranslatef(x, y, z); GL11.glColor4f(r, g, b, .02f); renderSphere(); randx = rn.nextInt(3); randy = rn.nextInt(3); randz = rn.nextInt(3); randr = rn.nextInt(3); randg = rn.nextInt(3); randb = rn.nextInt(3); } /** * Cleanup all the resources. * */ private void cleanup() { Display.destroy(); } /** * 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; } /** * 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_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); } }