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 }