source: java/client_3D/src/com/framsticks/net/client3D/Renderer.java @ 65

Last change on this file since 65 was 65, checked in by Maciej Komosinski, 13 years ago

added sources of the 3D client for the Framsticks server

File size: 14.6 KB
Line 
1package com.framsticks.net.client3D;
2
3import javax.media.opengl.GL;
4import javax.media.opengl.GLAutoDrawable;
5import javax.media.opengl.GLEventListener;
6import javax.media.opengl.glu.GLU;
7
8import pl.vorg.mowa.core.graphics.BoundingBox;
9import pl.vorg.mowa.core.graphics.SkyBox;
10import pl.vorg.mowa.core.graphics.Vec3;
11
12import com.sun.opengl.util.FPSAnimator;
13
14/**
15 * Class responsible for rendering of framsticks and the world.
16 *
17 * @author vorg
18 */
19public class Renderer implements GLEventListener {
20        public static final float AUTO_ROTATION_STEP = 0.5f;
21        private float rotationY = 0;
22        private float rotationX = 0;
23        private float translation = -1.0f;
24        private FPSAnimator animator;
25        private World world;
26        private Creature[] creatures;
27        private Creature.ModelType modelType = Creature.ModelType.MechParts;
28        private cgfxEffect style;
29        private SkyBox skyBox;
30
31        public SkyBox getSkyBox() {
32                return skyBox;
33        }
34
35        public void setSkyBox(SkyBox box) {
36                skyBox = box;
37        }
38
39        public cgfxEffect getStyle() {
40                return style;
41        }
42
43        /**
44         * Sets the currently used framstick rendering style.
45         *
46         * @param style
47         */
48        public void setStyle(cgfxEffect style) {
49                this.style = style;
50        }
51
52        public Creature[] getCreatures() {
53                return creatures;
54        }
55
56        /**
57         * Sets the number of creatures to display. To display a single creature in
58         * a zoomed view pass a single element array and set the modelType to
59         * Creature.ModelType.Parts.
60         *
61         * @param creatures
62         */
63        public void setCreatures(Creature[] creatures) {
64                this.creatures = creatures;
65        }
66
67        public World getWorld() {
68                return world;
69        }
70
71        /**
72         * Sets the world to be displayed.
73         *
74         * @param world
75         */
76        public void setWorld(World world) {
77                this.world = world;
78        }
79
80        public Creature.ModelType getModelType() {
81                return modelType;
82        }
83
84        /**
85         * Sets how the framsticks should be rendered.
86         *
87         * @param modelType
88         *            Creature.ModelType.Parts - the way they were created,
89         *            Creature.ModelType.MechParts - the way they currently look in
90         *            their world (in accordance with physics)
91         */
92        public void setModelType(Creature.ModelType modelType) {
93                this.modelType = modelType;
94        }
95
96        public float getTranslation() {
97                return translation;
98        }
99
100        public void setTranslation(float t) {
101                translation = t;
102                if (translation < 0.1)
103                        translation = 0.1f;
104        }
105
106        public void resetTranslation() {
107                translation = -1.0f;
108        }
109
110        public float getRotationX() {
111                return rotationX;
112        }
113
114        public float getRotationY() {
115                return rotationY;
116        }
117
118        public void setRotationX(float rotation) {
119                this.rotationX = rotation;
120                if (this.rotationX > 85.0)
121                        this.rotationX = 85.0f;
122                else if (this.rotationX < 0)
123                        this.rotationX = 0.0f;
124        }
125
126        public void setRotationY(float rotation) {
127                this.rotationY = rotation;
128        }
129
130        public void display(GLAutoDrawable drawable) {
131                style.setSkyBox(skyBox);
132                GL gl = drawable.getGL();
133
134                gl.glLoadIdentity();
135                gl.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT);
136
137                if ((creatures != null) && (creatures.length == 1)
138                                && (modelType == Creature.ModelType.Parts)) {
139                        // renderowanie pojedynczego framsticka
140
141                        drawCreature(gl);
142                } else {
143                        // renderowanie calaego swiata wraz z framstickami z nim zyjacymi
144                        drawWorld(gl);
145                }
146                gl.glFlush();
147        }
148
149        public void drawWorld(GL gl) {
150
151                // szescian otaczajacy swiat
152                // wyliczamy go po to aby ustawic kamere tak aby byla w stanie objac
153                // wszystko
154                BoundingBox bbox;
155                if ((world != null) && (world.getGeometry() != null)) {
156                        bbox = world.getGeometry().getBoundingBox();
157
158                } else {
159                        bbox = new BoundingBox();
160                        if (creatures != null) {
161                                for (Creature c : creatures) {
162                                        bbox.add(c.getBoundingBox(Creature.ModelType.MechParts));
163                                }
164                        }
165                }
166
167                Vec3 bboxSize = bbox.getSize();
168                Vec3 bboxCenter = Vec3
169                                .mul(0.5f, Vec3.add(bbox.getMax(), bbox.getMin()));
170
171                if (translation < 0 || translation > 100000000.0f) {
172                        translation = (float) Math.sqrt(bboxSize.getX() * bboxSize.getX()
173                                        / 4 + bboxSize.getZ() * bboxSize.getZ() / 4) * 1.5f;
174                }
175
176                gl.glTranslatef(0, 0, -1.0f * translation);
177                // gl.glRotatef(30, 1, 0, 0);
178
179                gl.glRotatef(rotationX, 1, 0, 0);
180                gl.glRotatef(rotationY, 0, 1, 0);
181                gl.glTranslatef(-bboxCenter.getX(), -bboxCenter.getY() - 2, -bboxCenter
182                                .getZ());
183                if (skyBox != null)
184                        skyBox.Draw(gl, 1000.0f, new Vec3(rotationX, rotationY, 0));
185                // renderowanie swiata
186                if ((world != null) && (world.getGeometry() != null)
187                                && !world.getGeometry().getBoundingBox().isEmpty()) {
188                        BoundingBox wrldBox = world.getGeometry().getBoundingBox();
189                        Vec3 wmin = wrldBox.getMin();
190                        Vec3 wmax = wrldBox.getMax();
191
192                        drawWorldGeometry(gl);
193                        drawWater(gl, wmin, wmax);
194                        if (world.getBoundaries() == 0) {
195                                drawWorldNoBounduaries(gl, wmin, wmax);
196                        } else if (world.getBoundaries() == 1) {
197                                drawWorldFence(gl, wmin, wmax);
198                        } else if (world.getBoundaries() == 2) {
199                                drawWorldTeleports(gl, wmin, wmax);
200                        }
201
202                }
203
204                // renderowanie stworow
205                if ((creatures != null) && (style != null)) {
206                        if (!style.isInitialized()) {
207                                style.Init();
208                                if (!style.isInitialized()) {
209                                        setStyle(null);
210                                        return;
211                                }
212                        }
213                        style.render(gl, creatures, Creature.ModelType.MechParts);
214                }
215        }
216
217        /**
218         * Rendering of the world surface.
219         *
220         * @param gl
221         */
222        private void drawWorldGeometry(GL gl) {
223                gl.glEnable(GL.GL_LIGHTING);
224                gl.glEnable(GL.GL_LIGHT0);
225                gl.glColor4f(0.9f, 0.8f, 0.2f, 0.0f);
226                gl.glEnable(GL.GL_COLOR_MATERIAL);
227                gl.glDisable(GL.GL_BLEND);
228                world.getGeometry().display(gl);
229                gl.glDisable(GL.GL_COLOR_MATERIAL);
230                gl.glDisable(GL.GL_LIGHTING);
231                // gl.glEnable(GL.GL_CULL_FACE);
232
233                gl.glColor4f(0.7f, 0.7f, 0.7f, 0.1f);
234                gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
235                gl.glEnable(GL.GL_LINE_SMOOTH);
236                gl.glEnable(GL.GL_BLEND);
237
238                // gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
239                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_DST_COLOR);
240                gl.glHint(GL.GL_LINE_SMOOTH_HINT, GL.GL_DONT_CARE);
241                gl.glLineWidth(2.5f);
242                world.getGeometry().display(gl);
243                gl.glDisable(GL.GL_BLEND);
244                gl.glDisable(GL.GL_LINE_SMOOTH);
245                gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
246        }
247
248        /**
249         * Rendering of the world boundaries which consist of teleports (you get in
250         * on one side of the world and get out on the opposite side).
251         *
252         * @param gl
253         * @param wmin
254         * @param wmax
255         */
256        private void drawWorldTeleports(GL gl, Vec3 wmin, Vec3 wmax) {
257                gl.glEnable(GL.GL_BLEND);
258                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
259                gl.glColor4f(0.0f, 0.4f, 0.9f, 0.5f);
260                gl.glBegin(GL.GL_TRIANGLES);
261                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
262                        gl.glVertex3f(wmin.getX(), 0, z);
263                        gl.glVertex3f(wmin.getX(), 0, z + 1);
264                        gl.glVertex3f(wmin.getX(), 1, z + 0.5f);
265                }
266                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
267                        gl.glVertex3f(wmax.getX(), 0, z);
268                        gl.glVertex3f(wmax.getX(), 0, z + 1);
269                        gl.glVertex3f(wmax.getX(), 1, z + 0.5f);
270                }
271                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
272                        gl.glVertex3f(x, 0, wmin.getZ());
273                        gl.glVertex3f(x + 1, 0, wmin.getZ());
274                        gl.glVertex3f(x + 0.5f, 1, wmin.getZ());
275                }
276                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
277                        gl.glVertex3f(x, 0, wmax.getZ());
278                        gl.glVertex3f(x + 1, 0, wmax.getZ());
279                        gl.glVertex3f(x + 0.5f, 1, wmax.getZ());
280                }
281                gl.glEnd();
282                gl.glDisable(GL.GL_BLEND);
283        }
284
285        /**
286         * Rendering of the world boundaries which consist of a fence.
287         *
288         * @param gl
289         * @param wmin
290         * @param wmax
291         */
292        private void drawWorldFence(GL gl, Vec3 wmin, Vec3 wmax) {
293                gl.glEnable(GL.GL_BLEND);
294                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
295                gl.glColor4f(1.0f, 0.2f, 0.0f, 0.5f);
296                gl.glBegin(GL.GL_QUADS);
297                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
298                        gl.glVertex3f(wmin.getX(), 0, z);
299                        gl.glVertex3f(wmin.getX(), 0, z + 1);
300                        gl.glVertex3f(wmin.getX(), 1, z + 1);
301                        gl.glVertex3f(wmin.getX(), 1, z);
302                }
303                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
304                        gl.glVertex3f(wmax.getX(), 0, z);
305                        gl.glVertex3f(wmax.getX(), 0, z + 1);
306                        gl.glVertex3f(wmax.getX(), 1, z + 1);
307                        gl.glVertex3f(wmax.getX(), 1, z);
308                }
309                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
310                        gl.glVertex3f(x, 0, wmin.getZ());
311                        gl.glVertex3f(x + 1, 0, wmin.getZ());
312                        gl.glVertex3f(x + 1, 1, wmin.getZ());
313                        gl.glVertex3f(x, 1, wmin.getZ());
314                }
315                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
316                        gl.glVertex3f(x, 0, wmax.getZ());
317                        gl.glVertex3f(x + 1, 0, wmax.getZ());
318                        gl.glVertex3f(x + 1, 1, wmax.getZ());
319                        gl.glVertex3f(x, 1, wmax.getZ());
320                }
321                gl.glEnd();
322                gl.glDisable(GL.GL_BLEND);
323        }
324
325        /**
326         * Rendering of the unbounded world boundaries.
327         *
328         * @param gl
329         * @param wmin
330         * @param wmax
331         */
332        private void drawWorldNoBounduaries(GL gl, Vec3 wmin, Vec3 wmax) {
333                gl.glEnable(GL.GL_BLEND);
334                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
335                gl.glBegin(GL.GL_QUADS);
336                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
337                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
338                        gl.glVertex3f(wmin.getX(), 0, z);
339                        gl.glVertex3f(wmin.getX(), 0, z + 1);
340                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
341                        gl.glVertex3f(wmin.getX() - 2, 0, z + 1);
342                        gl.glVertex3f(wmin.getX() - 2, 0, z);
343                }
344                for (float z = -wmin.getZ(); z < wmax.getZ(); z += 1) {
345                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
346                        gl.glVertex3f(wmax.getX(), 0, z);
347                        gl.glVertex3f(wmax.getX(), 0, z + 1);
348                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
349                        gl.glVertex3f(wmax.getX() + 2, 0, z + 1);
350                        gl.glVertex3f(wmax.getX() + 2, 0, z);
351                }
352                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
353                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
354                        gl.glVertex3f(x, 0, wmin.getZ());
355                        gl.glVertex3f(x + 1, 0, wmin.getZ());
356                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
357                        gl.glVertex3f(x + 1, 0, wmin.getZ() - 2);
358                        gl.glVertex3f(x, 0, wmin.getZ() - 2);
359                }
360                for (float x = -wmin.getX(); x < wmax.getX(); x += 1) {
361                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
362                        gl.glVertex3f(x, 0, wmax.getZ());
363                        gl.glVertex3f(x + 1, 0, wmax.getZ());
364                        gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
365                        gl.glVertex3f(x + 1, 0, wmax.getZ() + 2);
366                        gl.glVertex3f(x, 0, wmax.getZ() + 2);
367                }
368                gl.glEnd();
369
370                gl.glBegin(GL.GL_TRIANGLES);
371
372                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
373                gl.glVertex3f(wmin.getX(), 0, wmin.getX());
374                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
375                gl.glVertex3f(wmin.getX(), 0, wmin.getX() - 2);
376                gl.glVertex3f(wmin.getX() - 2, 0, wmin.getX());
377
378                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
379                gl.glVertex3f(wmax.getX(), 0, wmin.getX());
380                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
381                gl.glVertex3f(wmax.getX(), 0, wmin.getX() - 2);
382                gl.glVertex3f(wmax.getX() + 2, 0, wmin.getX());
383
384                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
385                gl.glVertex3f(wmax.getX(), 0, wmax.getX());
386                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
387                gl.glVertex3f(wmax.getX(), 0, wmax.getX() + 2);
388                gl.glVertex3f(wmax.getX() + 2, 0, wmax.getX());
389
390                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.5f);
391                gl.glVertex3f(wmin.getX(), 0, wmax.getX());
392                gl.glColor4f(1.0f, 0.8f, 0.0f, 0.0f);
393                gl.glVertex3f(wmin.getX(), 0, wmax.getX() + 2);
394                gl.glVertex3f(wmin.getX() - 2, 0, wmax.getX());
395
396                gl.glEnd();
397                gl.glDisable(GL.GL_BLEND);
398        }
399
400        /**
401         * Rendering of the water surface.
402         *
403         * @param gl
404         * @param wmin
405         * @param wmax
406         */
407        private void drawWater(GL gl, Vec3 wmin, Vec3 wmax) {
408                float wlev = world.getWaterLevel();
409                gl.glEnable(GL.GL_BLEND);
410                gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
411                gl.glBegin(GL.GL_QUADS);
412                gl.glColor4f(0.1f, 0.5f, 0.9f, 0.3f);
413                gl.glVertex3f(wmin.getX() - 5, wlev - 0.02f, wmin.getZ() - 5);
414                gl.glColor4f(0.1f, 0.8f, 0.9f, 0.3f);
415                gl.glVertex3f(wmin.getX() - 5, wlev - 0.02f, wmax.getZ() + 5);
416                gl.glColor4f(0.1f, 0.5f, 0.9f, 0.3f);
417                gl.glVertex3f(wmax.getX() + 5, wlev - 0.02f, wmax.getZ() + 5);
418                gl.glColor4f(0.1f, 0.8f, 0.9f, 0.3f);
419                gl.glVertex3f(wmax.getX() + 5, wlev - 0.02f, wmin.getZ() - 5);
420
421                gl.glColor4f(0.0f, 0.0f, 0.0f, 0.2f);
422                gl.glVertex3f(wmin.getX() - 0.5f, wlev - 0.01f, wmin.getZ() - 0.5f);
423                gl.glVertex3f(wmin.getX() - 0.5f, wlev - 0.01f, wmax.getZ() + 0.5f);
424                gl.glVertex3f(wmax.getX() + 0.5f, wlev - 0.01f, wmax.getZ() + 0.5f);
425                gl.glVertex3f(wmax.getX() + 0.5f, wlev - 0.01f, wmin.getZ() - 0.5f);
426                gl.glEnd();
427                gl.glDisable(GL.GL_BLEND);
428        }
429
430        /**
431         * Rendering of a single creature.
432         *
433         * @param gl
434         */
435        private void drawCreature(GL gl) {
436                BoundingBox bbox = creatures[0]
437                                .getBoundingBox(Creature.ModelType.Parts);
438
439                Vec3 bboxSize = bbox.getSize();
440                Vec3 bboxCenter = Vec3
441                                .mul(0.5f, Vec3.add(bbox.getMax(), bbox.getMin()));
442
443                if (translation < 0) {
444                        translation = (float) Math.sqrt(bboxSize.getX() * bboxSize.getX()
445                                        / 4 + bboxSize.getZ() * bboxSize.getZ() / 4);
446                }
447
448                gl.glTranslatef(0, 0, -1.0f * translation - 1);
449                // gl.glRotatef(30, 1, 0, 0);
450                gl.glRotatef(rotationX, 1, 0, 0);
451                gl.glRotatef(rotationY, 0, 1, 0);
452                gl.glTranslatef(-bboxCenter.getX(), -bboxCenter.getY(), -bboxCenter
453                                .getZ());
454                if (skyBox != null)
455                        skyBox.Draw(gl, 1000.0f, new Vec3(rotationX, rotationY, 0));
456
457                if (style != null) {
458                        if (!style.isInitialized()) {
459                                style.Init();
460                                if (!style.isInitialized()) {
461                                        setStyle(null);
462                                        return;
463                                }
464                        }
465
466                        // effect.render(gl, creatures, Creature.ModelType.Parts);
467                        style.render(gl, creatures, Creature.ModelType.Parts);
468                }
469        }
470
471        public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
472                        boolean deviceChanged) {
473        }
474
475        public void init(GLAutoDrawable drawable) {
476                Log.getInstance().log("dbg", "Renderer.init");
477                Log.getInstance().log("dbg", "Renderer.init creating animator");
478                animator = new FPSAnimator(30);
479                animator.add(drawable);
480                animator.start();
481                animator.setRunAsFastAsPossible(false);
482                rotationX = 30.0f;
483                rotationY = 0.0f;
484                Log.getInstance().log("dbg", "Renderer.init initializing opengl");
485                GL gl = drawable.getGL();
486                gl.glLoadIdentity();
487                gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
488                gl.glColor3f(1.0f, 1.0f, 1.0f);
489                gl.glClearDepth(1.0);
490                gl.glEnable(GL.GL_DEPTH_TEST);
491                gl.glDepthFunc(GL.GL_LEQUAL);
492                skyBox = new SkyBox();
493                skyBox.Init(gl);
494                // style.Init();
495                Log.getInstance().log("dbg", "Renderer.init done");
496        }
497
498        /**
499         * Adjust the view to the application's window size.
500         */
501        public void reshape(GLAutoDrawable drawable, int x, int y, int width,
502                        int height) {
503                GL gl = drawable.getGL();
504                GLU glu = new GLU();
505                gl.glMatrixMode(GL.GL_PROJECTION);
506                gl.glLoadIdentity();
507                glu.gluPerspective(90, (float) width / (float) height, 0.015, 1000);
508                gl.glMatrixMode(GL.GL_MODELVIEW);
509        }
510}
Note: See TracBrowser for help on using the repository browser.