From 880653d31a8f1ff8384fdbc75b84934bceecfdb8 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 18 Nov 2000 06:43:49 +0000 Subject: Initial revision --- demos/RonsDemos/steam.java | 791 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 791 insertions(+) create mode 100644 demos/RonsDemos/steam.java (limited to 'demos/RonsDemos/steam.java') diff --git a/demos/RonsDemos/steam.java b/demos/RonsDemos/steam.java new file mode 100644 index 0000000..3f19f7e --- /dev/null +++ b/demos/RonsDemos/steam.java @@ -0,0 +1,791 @@ +/** + * @(#) steam.java + * @(#) author: Troy Robinette (converted to Java by Ron Cemer) + */ + +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.*; +import java.util.*; +import java.io.*; +import java.util.*; +import gl4java.GLContext; +import gl4java.awt.GLAnimCanvas; +import gl4java.applet.SimpleGLAnimApplet1; + +/** + Description: Interactive 3D graphics, Assignment #1 + Miniature Steam Engine Simulation. + Author: Troy Robinette + Date: 29/9/95 + Email: troyr@yallara.cs.rmit.edu.au + Notes: - Transparence doesn't quite work. The color of the + underlying object doesn't show through. + - Also only the front side of the transparent objects are + transparent. +**/ + +public class steam extends SimpleGLAnimApplet1 +{ + private static final float boxnormals[][] = + { + {-1.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {1.0f, 0.0f, 0.0f}, + {0.0f, -1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + {0.0f, 0.0f, -1.0f} + }; + private static final int boxfaces[][] = + { + {0, 1, 2, 3}, + {3, 2, 6, 7}, + {7, 6, 5, 4}, + {4, 5, 1, 0}, + {5, 6, 2, 1}, + {7, 4, 0, 3} + }; + + /* Initialize the applet */ + + + public void init() + { + super.init(); + Dimension d = getSize(); + canvas = new steamCanvas(d.width, d.height); + canvas.requestFocus(); + add("Center", canvas); + } + + + /* Local GLAnimCanvas extension class */ + + + private class steamCanvas extends GLAnimCanvas + implements MouseListener, ActionListener, KeyListener + { + /* Dimensions of texture image. */ + private final int IMAGE_WIDTH = 64; + private final int IMAGE_HEIGHT = 64; + /* Step to be taken for each rotation. */ + private final int ANGLE_STEP = 10; + /* Magic numbers for relationship b/w cylinder head and crankshaft. */ + private final float MAGNITUDE = 120.0f; + private final float PHASE = 270.112f; + private final float FREQ_DIV = 58.0f; + private final float ARC_LENGTH = 2.7f; + private final float ARC_RADIUS = 0.15f; + /* Rotation angles */ + private float view_h = 270.0f, view_v = 0.0f; + private float head_angle = 0.0f; + private int crank_angle = 0; + /* Crank rotation step. */ + private float crank_step = 5.0f; + /* Toggles */ + private boolean filled = true; + private boolean textured = false, transparent = false; + /* Storage for the angle look up table and the texture map */ + private float head_look_up_table[] = new float[360]; + private byte image[] = new byte[IMAGE_WIDTH*IMAGE_HEIGHT*3]; + /* Indentifiers for each Display list */ + private int list_piston_filled = 1; + private int list_piston_texture = 2; + private int list_flywheel_filled = 4; + private int list_flywheel_texture = 8; + /* Variable used in the creaton of glu objects */ + int obj; // (GLU quadric object) + + private PopupMenu menu = null; + private boolean menu_showing = false; + private boolean save_suspended = false; + + private final String MENU_FILLED = "Filled"; + private final String MENU_WIREFRAME = "Wireframe"; + private final String MENU_TEXTURED = "Textured"; + private final String MENU_UNTEXTURED = "Untextured"; + private final String MENU_TRANSPARENT = "Transparent"; + private final String MENU_OPAQUE = "Opaque"; + private final String MENU_RIGHT_LIGHT_ON = "Right light on"; + private final String MENU_RIGHT_LIGHT_OFF = "Right light off"; + private final String MENU_LEFT_LIGHT_ON = "Left light on"; + private final String MENU_LEFT_LIGHT_OFF = "Left light off"; + private final String MENU_PAUSE = "Pause (use a and z to step)"; + private final String MENU_RESUME = "Resume animation"; + private final String MENU_SPEED_UP = "Speed up (+)"; + private final String MENU_SLOW_DOWN = "Slow down (-)"; + + public steamCanvas(int w, int h) + { + super(w, h); + GLContext.gljNativeDebug = false; + GLContext.gljClassDebug = false; + setAnimateFps(30.0); + } + + public void preInit() + { + doubleBuffer = true; + stereoView = false; + } + + public void init() + { + System.out.println("init(): " + this); + reshape(getSize().width, getSize().height); + + float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; + float mat_shininess[] = {50.0f}; + float light_position0[] = {1.0f, 1.0f, 1.0f, 0.0f}; + float light_position1[] = {-1.0f, 1.0f, 1.0f, 0.0f}; + float light_diffuse1[] = {1.0f,1.0f,1.0f,1.0f}; + float light_specular1[] = {1.0f,1.0f,1.0f,1.0f}; + + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + obj = glu.gluNewQuadric(); + make_table(); + make_image(); + + /* Set up Texturing */ + gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + gl.glTexImage2D + (GL_TEXTURE_2D, + 0, + 3, + IMAGE_WIDTH, + IMAGE_HEIGHT, + 0, + GL_RGB, + GL_UNSIGNED_BYTE, + image); + gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + /* Set up Lighting */ + gl.glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + gl.glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + gl.glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + gl.glLightfv(GL_LIGHT1, GL_POSITION, light_position1); + gl.glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1); + gl.glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1); + + /* Initial render mode is with full shading and LIGHT 0 + enabled. */ + gl.glEnable(GL_LIGHTING); + gl.glEnable(GL_LIGHT0); + gl.glDisable(GL_LIGHT1); + gl.glDepthFunc(GL_LEQUAL); + gl.glEnable(GL_DEPTH_TEST); + gl.glDisable(GL_ALPHA_TEST); + + gl.glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + gl.glEnable(GL_COLOR_MATERIAL); + gl.glShadeModel(GL_SMOOTH); + + /* Initialise display lists */ + gl.glNewList(list_piston_filled, GL_COMPILE); + draw_piston(); + gl.glEndList(); + gl.glNewList(list_flywheel_filled, GL_COMPILE); + draw_flywheel(); + gl.glEndList(); + + glu.gluQuadricTexture(obj, true); + gl.glNewList(list_piston_texture, GL_COMPILE); + draw_piston(); + gl.glEndList(); + gl.glNewList(list_flywheel_texture, GL_COMPILE); + draw_flywheel(); + gl.glEndList(); + glu.gluQuadricTexture(obj, false); + + glj.gljCheckGL(); + + menu = new PopupMenu("Options"); + menu.add(MENU_FILLED); + menu.add(MENU_WIREFRAME); + menu.add(MENU_TEXTURED); + menu.add(MENU_UNTEXTURED); + menu.add(MENU_TRANSPARENT); + menu.add(MENU_OPAQUE); + menu.add(MENU_RIGHT_LIGHT_ON); + menu.add(MENU_RIGHT_LIGHT_OFF); + menu.add(MENU_LEFT_LIGHT_ON); + menu.add(MENU_LEFT_LIGHT_OFF); + menu.add(MENU_PAUSE); + menu.add(MENU_RESUME); + menu.add(MENU_SPEED_UP); + menu.add(MENU_SLOW_DOWN); + menu.addActionListener(this); + add(menu); + + addMouseListener(this); + addKeyListener(this); + } + + public void doCleanup() + { + System.out.println("destroy(): " + this); + removeMouseListener(this); + menu.removeActionListener(this); + removeKeyListener(this); + } + + public void reshape(int width, int height) + { + gl.glViewport(0,0,width,height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluPerspective(65.0f, (float)width/(float)height, 1.0f, 20.0f); + gl.glMatrixMode(GL_MODELVIEW); + gl.glLoadIdentity(); + gl.glTranslatef(0.0f, 0.0f, -5.0f); /* viewing transform */ + gl.glScalef(1.5f, 1.5f, 1.5f); + } + + public void display() + { + if (glj.gljMakeCurrent() == false) return; + + if (!isSuspended()) + { + crank_angle += crank_step; + while (crank_angle >= 360) crank_angle -= 360; + while (crank_angle < 0) crank_angle += 360; + head_angle = head_look_up_table[crank_angle]; + } + + /* Main display code. Clears the drawing buffer and if + transparency is set, displays the model twice, 1st time + accepting those fragments with an ALPHA value of 1 only, + then with DEPTH_BUFFER writing disabled for those with + other values. */ + + int pass; + gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + gl.glPushMatrix(); + if (transparent) + { + gl.glEnable(GL_ALPHA_TEST); + pass = 2; + } + else + { + gl.glDisable(GL_ALPHA_TEST); + pass = 0; + } + + /* Rotate the whole model */ + gl.glRotatef(view_h, 0.0f, 1.0f, 0.0f); + gl.glRotatef(view_v, 1.0f, 0.0f, 0.0f); + + do + { + if (pass == 2) + { + gl.glAlphaFunc(GL_EQUAL, 1); + gl.glDepthMask(true); + pass = 1; + } + else if (pass != 0) + { + gl.glAlphaFunc(GL_NOTEQUAL, 1); + gl.glDepthMask(false); + pass = 0; + } + + draw_engine_pole(); + + gl.glPushMatrix(); + gl.glTranslatef(0.5f, 1.4f, 0.0f); + draw_cylinder_head(); + gl.glPopMatrix(); + + gl.glPushMatrix(); + gl.glTranslatef(0.0f, -0.8f, 0.0f); + draw_crank(); + gl.glPopMatrix(); + } while (pass > 0); + + gl.glDepthMask(true); + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + + //if (!isSuspended()) repaint(); // Animate at full speed. + } + + // Methods required for the implementation of MouseListener + public void mouseEntered( MouseEvent evt ) + { + Component comp = evt.getComponent(); + if( comp.equals(this ) ) + { + requestFocus(); + } + } + + public void mouseClicked( MouseEvent evt ) + { + Component comp = evt.getComponent(); + if( comp.equals(this ) ) + { + requestFocus(); + } + } + + public void mouseExited(MouseEvent evt) + { + } + + public void mousePressed(MouseEvent evt) + { + // If user presses right mouse button within canvas area, + // suspend animation and pop up menu. + // If menu was already popped up and user presses either + // mouse button within canvas area, resume animation + // because the menu will have been removed automatically. + if (!menu_showing) + { + if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0) + { + menu_showing = true; + save_suspended = isSuspended(); + if (!save_suspended) + { + setSuspended(true); + repaint(100); + try + { + Thread.currentThread().sleep(200); + } + catch (Exception e) + { } + } + menu.show(this,evt.getX(),evt.getY()); + } + } + else + { + menu_showing = false; + setSuspended(save_suspended); + } + } + + public void mouseReleased(MouseEvent evt) + { + } + + // Method required for the implementation of ActionListener + public void actionPerformed(ActionEvent evt) + { + if (glj.gljMakeCurrent() == false) return; + boolean dorepaint = false; + String c = evt.getActionCommand(); + if (c.equals(MENU_FILLED)) + { + filled = true; + gl.glShadeModel(GL_SMOOTH); + gl.glEnable(GL_LIGHTING); + gl.glEnable(GL_DEPTH_TEST); + gl.glEnable(GL_COLOR_MATERIAL); + glu.gluQuadricNormals(obj, GLU_SMOOTH); + glu.gluQuadricDrawStyle(obj, GLU_FILL); + // Conditionally re-enable texturing. + if (textured) + { + gl.glEnable(GL_TEXTURE_2D); + glu.gluQuadricTexture(obj, true); + } + dorepaint = true; + } + else if (c.equals(MENU_WIREFRAME)) + { + filled = false; + gl.glShadeModel(GL_FLAT); + gl.glDisable(GL_LIGHTING); + gl.glDisable(GL_DEPTH_TEST); + gl.glDisable(GL_COLOR_MATERIAL); + glu.gluQuadricNormals(obj, GLU_NONE); + glu.gluQuadricDrawStyle(obj, GLU_LINE); + glu.gluQuadricTexture(obj, false); + // Be sure texturing is disabled. + gl.glDisable(GL_TEXTURE_2D); + glu.gluQuadricTexture(obj, false); + dorepaint = true; + } + else if (c.equals(MENU_TEXTURED)) + { + textured = true; + if (filled) + { + gl.glEnable(GL_TEXTURE_2D); + glu.gluQuadricTexture(obj, true); + dorepaint = true; + } + } + else if (c.equals(MENU_UNTEXTURED)) + { + textured = false; + gl.glDisable(GL_TEXTURE_2D); + glu.gluQuadricTexture(obj, false); + dorepaint = true; + } + else if (c.equals(MENU_TRANSPARENT)) + { + transparent = true; + dorepaint = true; + } + else if (c.equals(MENU_OPAQUE)) + { + transparent = false; + dorepaint = true; + } + else if (c.equals(MENU_RIGHT_LIGHT_ON)) + { + gl.glEnable(GL_LIGHT0); + dorepaint = true; + } + else if (c.equals(MENU_RIGHT_LIGHT_OFF)) + { + gl.glDisable(GL_LIGHT0); + dorepaint = true; + } + else if (c.equals(MENU_LEFT_LIGHT_ON)) + { + gl.glEnable(GL_LIGHT1); + dorepaint = true; + } + else if (c.equals(MENU_LEFT_LIGHT_OFF)) + { + gl.glDisable(GL_LIGHT1); + dorepaint = true; + } + else if (c.equals(MENU_PAUSE)) + { + if (menu_showing) + save_suspended = true; + else + setSuspended(true); + } + else if (c.equals(MENU_RESUME)) + { + if (menu_showing) + save_suspended = false; + else + setSuspended(false); + } + else if (c.equals(MENU_SPEED_UP)) + { + crank_step++; + if (crank_step > 45) crank_step = 45; + } + else if (c.equals(MENU_SLOW_DOWN)) + { + crank_step--; + if (crank_step < 1) crank_step = 1; + } + if (menu_showing) + { + menu_showing = false; + setSuspended(save_suspended); + } + glj.gljFree(); + if (dorepaint) repaint(); + } + + // Methods required for the implementation of KeyListener + public void keyPressed(KeyEvent e) + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_LEFT: + view_h -= ANGLE_STEP; + while (view_h < 0) view_h += 360; + repaint(); + break; + case KeyEvent.VK_RIGHT: + view_h += ANGLE_STEP; + while (view_h >= 360) view_h -= 360; + repaint(); + break; + case KeyEvent.VK_UP: + view_v += ANGLE_STEP; + while (view_v >= 360) view_v -= 360; + repaint(); + break; + case KeyEvent.VK_DOWN: + view_v -= ANGLE_STEP; + while (view_v < 0) view_v += 360; + repaint(); + break; + } + } + + public void keyReleased(KeyEvent e) + { + } + + public void keyTyped(KeyEvent e) + { + if (glj.gljMakeCurrent() == false) return; + boolean dorepaint = false; + switch ((char)e.getKeyChar()) + { + case 'a': + case 'A': + if (!isSuspended()) break; + crank_angle += crank_step; + while (crank_angle >= 360) crank_angle -= 360; + head_angle = head_look_up_table[crank_angle]; + dorepaint = true; + break; + case 'z': + case 'Z': + if (!isSuspended()) break; + crank_angle -= crank_step; + while (crank_angle < 0) crank_angle += 360; + head_angle = head_look_up_table[crank_angle]; + dorepaint = true; + break; + case '+': + crank_step++; + if (crank_step > 45) crank_step = 45; + break; + case '-': + crank_step--; + if (crank_step < 1) crank_step = 1; + break; + } + glj.gljFree(); + if (dorepaint) repaint(); + } + + /* Draws a box by scaling a glut cube of size 1. + Also checks the filled toggle to see which rendering + style to use. NB Texture doesn't work correctly due + to the cube being scaled. */ + private void myBox(float x, float y, float z) + { + gl.glPushMatrix(); + gl.glScalef(x, y, z); + if (filled) + glutSolidCube(1); + else + glutWireCube(1); + gl.glPopMatrix(); + } + + /* Draws a cylinder using glu function, drawing flat discs + at each end, to give the appearence of it being solid. */ + private void myCylinder + (int object, float outerRadius, float innerRadius, float length) + { + gl.glPushMatrix(); + glu.gluCylinder(object, outerRadius, outerRadius, length, 20, 1); + gl.glPushMatrix(); + gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + glu.gluDisk(object, innerRadius, outerRadius, 20, 1); + gl.glPopMatrix(); + gl.glTranslatef(0.0f, 0.0f, length); + glu.gluDisk(object, innerRadius, outerRadius, 20, 1); + gl.glPopMatrix(); + } + + /* Draws a piston. */ + private void draw_piston() + { + gl.glPushMatrix(); + gl.glColor4f(0.3f, 0.6f, 0.9f, 1.0f); + gl.glPushMatrix(); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + gl.glTranslatef(0.0f, 0.0f, -0.07f); + myCylinder(obj, 0.125f, 0.06f, 0.12f); + gl.glPopMatrix(); + gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + gl.glTranslatef(0.0f, 0.0f, 0.05f); + myCylinder(obj, 0.06f, 0.0f, 0.6f); + gl.glTranslatef(0.0f, 0.0f, 0.6f); + myCylinder(obj, 0.2f, 0.0f, 0.5f); + gl.glPopMatrix(); + } + + /* Draws the engine pole and the + pivot pole for the cylinder head. */ + private void draw_engine_pole() + { + gl.glPushMatrix(); + gl.glColor4f(0.9f, 0.9f, 0.9f, 1.0f); + myBox(0.5f, 3.0f, 0.5f); + gl.glColor3f(0.5f, 0.1f, 0.5f); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + gl.glTranslatef(0.0f, 0.9f, -0.4f); + myCylinder(obj, 0.1f, 0.0f, 2); + gl.glPopMatrix(); + } + + /* Draws the cylinder head at the appropreate angle, doing + the necessary translations for the rotation. */ + private void draw_cylinder_head() + { + gl.glPushMatrix(); + gl.glColor4f(0.5f, 1.0f, 0.5f, 0.1f); + gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + gl.glTranslatef(0.0f, 0.0f, 0.4f); + gl.glRotatef(head_angle, 1.0f, 0.0f, 0.0f); + gl.glTranslatef(0.0f, 0.0f, -0.4f); + myCylinder(obj, 0.23f, 0.21f, 1.6f); + gl.glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + glu.gluDisk(obj, 0.0f, 0.23f, 20, 1); + gl.glPopMatrix(); + } + + /* Draws the flywheel. */ + private void draw_flywheel() + { + gl.glPushMatrix(); + gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + myCylinder(obj, 0.625f, 0.08f, 0.5f); + gl.glPopMatrix(); + } + +/* Draws the crank bell, and the pivot pin for the piston. Also calls the + appropreate display list of a piston doing the nesacary rotations before + hand. */ + private void draw_crankbell() + { + gl.glPushMatrix(); + gl.glColor4f(1.0f, 0.5f, 0.5f, 1.0f); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + myCylinder(obj, 0.3f, 0.08f, 0.12f); + + gl.glColor4f(0.5f, 0.1f, 0.5f, 1.0f); + gl.glTranslatef(0.0f, 0.2f, 0.0f); + myCylinder(obj, 0.06f, 0.0f, 0.34f); + + gl.glTranslatef(0.0f, 0.0f, 0.22f); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + gl.glRotatef(((float)crank_angle)-head_angle, 1.0f, 0.0f, 0.0f); + if (filled) + { + if (textured) + gl.glCallList(list_piston_texture); + else + gl.glCallList(list_piston_filled); + } + else + draw_piston(); + gl.glPopMatrix(); + } + + /* Draws the complete crank. Piston also gets drawn through + the crank bell function. */ + private void draw_crank() + { + gl.glPushMatrix(); + gl.glRotatef(crank_angle, 1.0f, 0.0f, 0.0f); + + gl.glPushMatrix(); + gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + gl.glTranslatef(0.0f, 0.0f, -1.0f); + myCylinder(obj, 0.08f, 0.0f, 1.4f); + gl.glPopMatrix(); + + gl.glPushMatrix(); + gl.glTranslatef(0.28f, 0.0f, 0.0f); + draw_crankbell(); + gl.glPopMatrix(); + + gl.glPushMatrix(); + gl.glTranslatef(-0.77f, 0.0f, 0.0f); + if (filled) + { + if (textured) + gl.glCallList(list_flywheel_texture); + else + gl.glCallList(list_flywheel_filled); + } + else + draw_flywheel(); + gl.glPopMatrix(); + gl.glPopMatrix(); + } + + /* Makes a simple checkered pattern image. (Copied from the + redbook example "checker.c".) */ + private void make_image() + { + int c, idx = 0; + for (int i = 0; i < IMAGE_WIDTH; i++) + { + for (int j = 0; j < IMAGE_HEIGHT; j++) + { + c = ((((i & 0x8) == 0) ^ ((j & 0x8)) == 0)) ? 255 : 0; + image[idx++] = (byte)c; + image[idx++] = (byte)c; + image[idx++] = (byte)c; + } + } + } + + /* Makes the head lookup table for all possible crank angles. */ + private void make_table() + { + for (int i = 0; i < 360; i++) + { + float rads = PHASE-(((float)i)/FREQ_DIV); + head_look_up_table[i] = + MAGNITUDE * + (float)Math.atan + ((ARC_RADIUS*Math.sin(rads)) / + (ARC_LENGTH-(ARC_RADIUS*Math.cos(rads)))); + } + } + + // Imported from glut. + private void glutWireCube(float size) + { + drawBox(size, GL_LINE_LOOP); + } + + // Imported from glut. + private void glutSolidCube(float size) + { + drawBox(size, GL_QUADS); + } + + // Imported from glut. + private void drawBox(float size, int type) + { + float v[][] = new float[8][3]; + int i; + + v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2; + v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2; + v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2; + v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2; + v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2; + v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2; + + for (i = 5; i >= 0; i--) + { + gl.glBegin(type); + gl.glNormal3fv(boxnormals[i]); + gl.glVertex3fv(v[boxfaces[i][0]]); + gl.glVertex3fv(v[boxfaces[i][1]]); + gl.glVertex3fv(v[boxfaces[i][2]]); + gl.glVertex3fv(v[boxfaces[i][3]]); + gl.glEnd(); + } + } + } +} -- cgit v1.2.3