import org.lwjgl.opengl.*; import org.lwjgl.util.glu.*; import org.lwjgl.input.Keyboard; /** * Flowers drawn with a fake shadow. Uses glColor() to set vert * colors, no lighting, shadow is fudged by drawing flowers * in a darker color below the full color flower. */ public class GLART_5_flowers { private boolean done = false; private final String windowTitle = "Flowers with fudged shadow"; private DisplayMode displayMode; float rotation = 0f; int[] randomX = new int[20]; int[] randomY = new int[20]; float[] randomS = new float[20]; /** * Main function just creates and runs the application. */ public static void main(String args[]) { GLART_5_flowers app = new GLART_5_flowers(); 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(); // update video display } cleanup(); } catch (Exception e) { e.printStackTrace(); System.exit(0); } } /** * Initialize the environment * @throws Exception */ private void init() throws Exception { initDisplay(); initGL(); randomX = randomInts(randomX, displayMode.getWidth()); randomY = randomInts(randomY, displayMode.getHeight()); randomS = randomFloats(randomS, 1); } /** * 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; } } // set the display to the resolution we picked Display.setDisplayMode(displayMode); Display.setTitle(windowTitle); // Synchronize display updates with the video refresh rate. // Graphics cards usually refresh video screen about // 60 times per second. If opengl tries to update screen // faster than 60 x per sec, then you'll see "tearing" on // the screen (two animation frames overlapping) on screen. Display.setVSyncEnabled(true); // create the window Display.create(new PixelFormat(0, 24, 0)); } /** * Initialize OpenGL * */ private void initGL() { // Select the Projection Matrix (controls perspective) GL11.glMatrixMode(GL11.GL_PROJECTION); // Reset The Projection Matrix GL11.glLoadIdentity(); // Define perspective GLU.gluPerspective( 45.0f, // Field Of View (float)displayMode.getWidth() / (float)displayMode.getHeight(), // aspect ratio 0.1f, // near Z clipping plane 10000.0f); // far Z clipping plane // Select The Modelview Matrix (controls model orientation) GL11.glMatrixMode(GL11.GL_MODELVIEW); // turn depth testing on GL11.glEnable(GL11.GL_DEPTH_TEST); // green background GL11.glClearColor(.1f,.4f,0f,1f); } /** * 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; } } /** * Render the scene. */ private void render() { int w = displayMode.getWidth(); int h = displayMode.getHeight(); rotation += .05f; // Clear screen and depth buffer GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Reset the Modelview matrix // this resets the coordinate system to center of screen GL11.glLoadIdentity(); // Where is the 'eye' GLU.gluLookAt( 0f, -600f, 600f, // eye position 0f, -100f, 0f, // target to look at 0f, 1f, 0f); // which way is up // rotate scene GL11.glRotatef(rotation, 0, 0, 1); // draw a bunch of flowers for (int i=0; i < randomX.length; i++) { // preserve the current coordinate system GL11.glPushMatrix(); { // shift to a random x,y position GL11.glTranslatef(randomX[i]-400, randomY[i]-300, randomS[i]); // scale up a random amount GL11.glScalef(.6f+randomS[i], .6f+randomS[i], .6f+randomS[i]); // draw dark flower below GL11.glPushMatrix(); { GL11.glTranslatef(25,40,-130); drawFlowerShadow(250,2,2); } GL11.glPopMatrix(); // draw flower in color above drawFlower(250,2,2); } GL11.glPopMatrix(); // glPopMatrix will return to previous coord system // in effect clearing the translate we did above. } } //============================================================ public float random(float upperbound) { return (float)Math.random()*((float)upperbound); } //Draws a flower centered at 0,0. Use translate() to place circle at desired coords. //r radius of flower petals, nodes*2 number of petals, stepSize definition public void drawFlower(float r, int nodes, int stepSize) { int s = 0; int e = 360; float ts, tc, rs, rc; float x, y, z; //Draw Center of Flower s = 0; e = 360; GL11.glBegin(GL11.GL_QUAD_STRIP); { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glColor3f(1f,1f,0f); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); GL11.glColor3f(.8f,.7f,0f); GL11.glVertex3f(0, 0, 1f); while ( (s = ( (s + stepSize) / stepSize) * stepSize) < e) { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glColor3f(1f,1f,0f); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); GL11.glColor3f(.8f,.7f,0f); GL11.glVertex3f(0, 0, 1f); } ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glColor3f(1f,1f,0f); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); GL11.glColor3f(.8f,.7f,0f); GL11.glVertex3f(0, 0, 1f); } GL11.glEnd(); //Draw Petals s = 0; e = 360; r /= 2f; GL11.glColor3f(1f,1f,1f); GL11.glBegin(GL11.GL_POLYGON); { while ( (s = ( (s + stepSize) / stepSize) * stepSize) < e) { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); rs = (float) Math.sin(Math.toRadians(s*nodes)); rc = (float) Math.cos(Math.toRadians(s*nodes)); x = tc*(rc*rs)*r; y = ts*(rc*rs)*r; z = (float)Math.abs((x*y)*.01f); GL11.glColor3f(z, z, 1f); GL11.glVertex3f(x, y, -z); } } GL11.glEnd(); }//END DrawFlower public void drawFlowerShadow(float r, int nodes, int stepSize) { int s = 0; int e = 360; float ts, tc, rs, rc; float x, y, z; GL11.glColor3f(.10f,.28f,.13f); //Draw Center of Flower s = 0; e = 360; GL11.glBegin(GL11.GL_POLYGON); { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); while ( (s = ( (s + stepSize) / stepSize) * stepSize) < e) { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); } ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); GL11.glVertex3f(tc*r*.1f, ts*r*.08f, 1f); } GL11.glEnd(); //Draw Petals s = 0; e = 360; r /= 2f; GL11.glBegin(GL11.GL_POLYGON); { while ( (s = ( (s + stepSize) / stepSize) * stepSize) < e) { ts = (float) Math.sin(Math.toRadians(s)); tc = (float) Math.cos(Math.toRadians(s)); rs = (float) Math.sin(Math.toRadians(s*nodes)); rc = (float) Math.cos(Math.toRadians(s*nodes)); x = tc*(rc*rs)*r; y = ts*(rc*rs)*r; GL11.glVertex3f(x, y, 0); } } GL11.glEnd(); }//END DrawFlower public int[] randomInts(int[] array, int upperBound) { for (int i=0; i