001 package rendering; 002 003 import java.io.IOException; 004 import java.net.URL; 005 import java.util.HashMap; 006 import java.util.Map; 007 008 import javax.media.opengl.GL; 009 import javax.media.opengl.GLAutoDrawable; 010 import javax.media.opengl.GLEventListener; 011 012 import physics3d.Angle; 013 import physics3d.GameConstants; 014 import physics3d.PhysicsShape; 015 import physics3d.Vect3; 016 import swingui.MainGUI; 017 018 import com.sun.opengl.util.texture.Texture; 019 import com.sun.opengl.util.texture.TextureIO; 020 import components.GameObject; 021 import components.GameObjectClassification; 022 import components.GameSpace; 023 024 /** 025 * Renderer is an immutable object that Renders the GameSpace. 026 * 027 *@specfield gs : GameSpace // The GameSpace that Renderer renders 028 */ 029 030 /* 031 * Abstraction Function 032 * AF(r) = RE, a renderer such that 033 * RE.gs = r.gs 034 */ 035 036 /* 037 * Rep Invariant 038 * gs != null 039 */ 040 041 public class Renderer extends ShapeRenderer implements GLEventListener { 042 043 private GameSpace gs; 044 private boolean playMode; 045 046 private Map<GameObjectClassification, Texture> texMap; 047 048 /** 049 * @effects constructs a new rendering instance. 050 */ 051 public Renderer(GameSpace gs) { 052 super(); 053 this.gs = gs; 054 playMode = true; 055 texMap = new HashMap<GameObjectClassification, Texture>(); 056 } 057 058 public void setPlayMode(boolean pm) { 059 playMode = pm; 060 } 061 062 /** performs one-time OpenGL initalization 063 * (non-Javadoc) 064 * @see javax.media.opengl.GLEventListener#init(javax.media.opengl.GLAutoDrawable) 065 */ 066 public void init(GLAutoDrawable gld) { 067 GL gl = gld.getGL(); 068 069 gl.glClear(GL.GL_COLOR_BUFFER_BIT); 070 gl.glEnable(GL.GL_DEPTH_TEST); 071 // gl.glEnable(GL.GL_TEXTURE_2D); 072 073 setView(gld); 074 addLight(gld); 075 // loadTextures(); 076 } 077 078 // configures the light source for the scene 079 private void addLight(GLAutoDrawable drawable) { 080 GL gl = drawable.getGL(); 081 gl.glEnable(GL.GL_DEPTH_TEST); 082 083 float[] diffuseLight = {0.8f, 0.8f, 0.8f, 0.0f}; 084 float[] ambientLight = {0.5f, 0.5f, 0.5f, 0.0f}; 085 float[] lightPosition= {50f, 50f, -500f, 1f}; 086 087 //Ambient light component 088 gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambientLight, 0); 089 //Diffuse light component 090 gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuseLight, 0); 091 //Light position 092 gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); 093 094 //Enable the first light and the lighting mode 095 gl.glEnable(GL.GL_LIGHT0); 096 gl.glEnable(GL.GL_LIGHTING); 097 } 098 099 private void setView(GLAutoDrawable gld) { 100 GL gl = gld.getGL(); 101 102 gl.glMatrixMode(GL.GL_PROJECTION); 103 gl.glLoadIdentity(); 104 glu.gluPerspective(90, gld.getWidth() / gld.getHeight(), 50, 100); 105 106 gl.glMatrixMode(GL.GL_MODELVIEW); 107 gl.glLoadIdentity(); 108 // glu.gluLookAt(50, -50, 50, 50, 50, 0, 0, 0, -1); 109 glu.gluLookAt(50, 50, -50, 110 50, 50, 0, 111 0, -1, 0); 112 113 114 } 115 116 private void loadTextures() { 117 if (texMap.isEmpty()) { 118 Map<GameObjectClassification, String> tl = gs.getTexLocations(); 119 for(GameObjectClassification goc : tl.keySet()) { 120 Texture t = loadTexture(tl.get(goc)); 121 texMap.put(goc, t); 122 } 123 } 124 } 125 126 private Texture loadTexture(String fileName) { 127 Texture tex = null; 128 try { 129 URL u = MainGUI.getFile("."); 130 System.err.println("u="+u); 131 u = MainGUI.getFile(fileName); 132 System.err.println("u="+u); 133 tex = TextureIO.newTexture(u, false, ""); 134 tex.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); 135 tex.setTexParameterf(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); 136 } 137 catch (IOException ex) { 138 //System.out.println("error loading texture = " + ex.getMessage()); 139 } 140 return tex; 141 } 142 143 /** 144 * @modifies texMap 145 * @effects clears the Textures stored in texMap 146 */ 147 public void clearTextures() { 148 texMap.clear(); 149 } 150 151 /** 152 * Renders all displayable objects 153 * @see javax.media.opengl.GLEventListener#display(javax.media.opengl.GLAutoDrawable) 154 */ 155 public void display(GLAutoDrawable drawable) { 156 GL gl = drawable.getGL(); 157 158 gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); 159 160 //draws the grid if in build mode 161 if (!playMode) { 162 drawGrid(drawable, 0); 163 } else { 164 //draws the box if in play mode 165 drawBox(drawable); 166 } 167 168 loadTextures(); 169 170 //draws GameObjects 171 for (GameObject go : gs.getObjects()) { 172 if (!go.isVisible()) 173 continue; 174 Vect3 center = go.getCenter().times(GameConstants.L); 175 ////System.out.println(go.getName() + " " + center.toString()); 176 Vect3 ov = go.getOrientVector(); 177 Angle oa = go.getOrientAngle(); 178 Texture t = texMap.get(go.getGOClassification()); 179 if (go.isSelected()) { 180 t = texMap.get(GameObjectClassification.SELECTED); 181 } 182 for (PhysicsShape ps : go.getShape().getParts()) { 183 switch (ps.getShapeClassification()) { 184 case LATERAL_CYLINDER: 185 drawLateralCylinder(drawable, center, ov, oa, ps, t); 186 break; 187 case PLANE_CIRCLE: 188 drawPlaneCircle(drawable, center, ov, oa, ps, t); 189 break; 190 case PLANE_POLYGON: 191 drawPlanePolygon(drawable, center, ov, oa, ps, t); 192 break; 193 case SPHERE: 194 // //System.out.println(center + " renderer"); 195 drawSphere(drawable, center, ov, oa, ps, t); 196 break; 197 case TORUS: 198 break; 199 } 200 } 201 202 } 203 } 204 205 private void drawGrid(GLAutoDrawable drawable, double z) { 206 GL gl = drawable.getGL(); 207 gl.glLineWidth(1); 208 gl.glBegin(GL.GL_LINES); 209 for (int i = 0; i <= 100; i += GameConstants.L) { 210 //vertical lines 211 gl.glVertex3d(i, 0, z); 212 gl.glVertex3d(i, 100, z); 213 //horizontal lines 214 gl.glVertex3d(0, i, z); 215 gl.glVertex3d(100, i, z); 216 } 217 gl.glEnd(); 218 } 219 220 221 private void drawBox(GLAutoDrawable drawable) { 222 GL gl = drawable.getGL(); 223 224 gl.glBegin(GL.GL_LINES); 225 //inner box top lines 226 gl.glVertex3d(0, 0, 50); 227 gl.glVertex3d(100, 0, 50); 228 gl.glVertex3d(0, 0, 0); 229 gl.glVertex3d(0, 0, 50); 230 231 //right line 232 gl.glVertex3d(100, 0, 50); 233 gl.glVertex3d(100, 100, 50); 234 gl.glVertex3d(100, 0, 0); 235 gl.glVertex3d(100, 0, 50); 236 237 //bottom line 238 gl.glVertex3d(100, 100, 50); 239 gl.glVertex3d(0, 100, 50); 240 gl.glVertex3d(100, 100, 0); 241 gl.glVertex3d(100, 100, 50); 242 243 //left line 244 gl.glVertex3d(0, 100, 50); 245 gl.glVertex3d(0, 0, 50); 246 gl.glVertex3d(0, 100, 0); 247 gl.glVertex3d(0, 100, 50); 248 249 gl.glEnd(); 250 } 251 252 /** 253 * @requires ps (instance of Torus) 254 */ 255 /* 256 private void drawTorus(GLAutoDrawable drawable, Vect3 center, PhysicsShape ps) { 257 throw new RuntimeException("Method not implemented"); 258 } 259 */ 260 261 /** 262 * method required by GLEventListener interface 263 */ 264 public void reshape(GLAutoDrawable drawable, int x, int y, int width, 265 int height) { 266 } 267 268 /** 269 * method required by GLEventListener interface 270 */ 271 public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, 272 boolean deviceChanged) { 273 } 274 275 /** 276 * @return the GameSpace that this Renderer renders 277 */ 278 public GameSpace getGameSpace() { 279 return gs; 280 } 281 282 /** 283 * @requires g != null 284 * @modifies gs 285 * @effects sets gs to g 286 */ 287 public void setGameSpace(GameSpace g) { 288 gs = g; 289 } 290 291 }