## Rectangle positioning abstraction

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

### Rectangle positioning abstraction

Hi guys.

I have written a game using the Android 2d graphics stuff - like canvas.drawRect() using the 2d shapes from ShapeDrawable package. However this runs VERY slowly - so wanted to transfer it over to OpenGL.

I have written a demo which draws a square to the screen - but I cannot work out how to position it - and how to set its dimensions. Using the android ShapeDrawable, i would do set size - setPosition - but obviously OpenGL is much lower level than this.

Taking this into account - here is my "SuperBlock" - open gl Square. Can anybody suggest to me any code I could add to this class in order to achieve setting different sizes - positions on screen.

Thanks

Using java Syntax Highlighting
1.
2. package com.andy.td.GameMechanics;
3.
4.
5.
6. import java.nio.ByteBuffer;
7.
8. import java.nio.ByteOrder;
9.
10. import java.nio.FloatBuffer;
11.
12. import java.nio.ShortBuffer;
13.
14.
15.
16. import javax.microedition.khronos.opengles.GL10;
17.
18.
19.
20. public class SuperBlock {
21.
22.         // Our vertices.
23.
24.         private float vertices[] = {
25.
26.                       -1.0f,  1.0f, 0.0f,  // 0, Top Left
27.
28.                       -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
29.
30.                        1.0f, -1.0f, 0.0f,  // 2, Bottom Right
31.
32.                        1.0f,  1.0f, 0.0f,  // 3, Top Right
33.
34.                 };
35.
36.
37.
38.         // The order we like to connect them.
39.
40.         private short[] indices = { 0, 1, 2, 0, 2, 3 };
41.
42.
43.
44.         // Our vertex buffer.
45.
46.         private FloatBuffer vertexBuffer;
47.
48.
49.
50.         // Our index buffer.
51.
52.         private ShortBuffer indexBuffer;
53.
54.
55.
56.         public SuperBlock() {
57.
58.                 // a float is 4 bytes, therefore we multiply the number if
59.
60.                 // vertices with 4.
61.
62.                 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
63.
64.                 vbb.order(ByteOrder.nativeOrder());
65.
66.                 vertexBuffer = vbb.asFloatBuffer();
67.
68.                 vertexBuffer.put(vertices);
69.
70.                 vertexBuffer.position(0);
71.
72.
73.
74.                 // short is 2 bytes, therefore we multiply the number if
75.
76.                 // vertices with 2.
77.
78.                 ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
79.
80.                 ibb.order(ByteOrder.nativeOrder());
81.
82.                 indexBuffer = ibb.asShortBuffer();
83.
84.                 indexBuffer.put(indices);
85.
86.                 indexBuffer.position(0);
87.
88.         }
89.
90.
91.
92.         /**
93.
94.          * This function draws our square on screen.
95.
96.          * @param gl
97.
98.          */
99.
100.         public void draw(GL10 gl) {
101.
102.                 // Counter-clockwise winding.
103.
104.                 gl.glFrontFace(GL10.GL_CCW);
105.
106.                 // Enable face culling.
107.
108.                 gl.glEnable(GL10.GL_CULL_FACE);
109.
110.                 // What faces to remove with the face culling.
111.
112.                 gl.glCullFace(GL10.GL_BACK);
113.
114.
115.
116.                 // Enabled the vertices buffer for writing and to be used during
117.
118.                 // rendering.
119.
120.                 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
121.
122.                 // Specifies the location and data format of an array of vertex
123.
124.                 // coordinates to use when rendering.
125.
126.                 gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
127.
128.
129.
130.                 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
131.
132.                                 GL10.GL_UNSIGNED_SHORT, indexBuffer);
133.
134.
135.
136.                 // Disable the vertices buffer.
137.
138.                 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
139.
140.                 // Disable face culling.
141.
142.                 gl.glDisable(GL10.GL_CULL_FACE);
143.
144.         }
145.
146.
147.
148. }
149.
150.
Parsed in 0.016 seconds, using GeSHi 1.0.8.4
Freshman

Posts: 6
Joined: Mon Jun 22, 2009 7:29 pm

Unfortunately I don't have a bunch of time to reply, but here are a few things to consider.

If you are doing a 2D game then investigate setting up an orthographic projection. Here is code that I use to do so.

Using java Syntax Highlighting
1.
2.
3.
4.    public void resetOrtho()
5.
6.    {
7.
8.       gl.glMatrixMode(GL_PROJECTION);                 // Select Projection
9.
10.       gl.glPopMatrix();                                                             // Pop The Matrix
11.
12.       gl.glMatrixMode(GL_MODELVIEW);                                       // Select Modelview
13.
14.       gl.glPopMatrix();                                                             // Pop The Matrix
15.
16.    }
17.
18.
19.
20.    public void setOrtho(int width, int height)
21.
22.    {
23.
24.       gl.glMatrixMode(GL_PROJECTION);                                      // Select Projection
25.
26.       gl.glPushMatrix();                                                                 // Push The Matrix
27.
28.       gl.glLoadIdentity();                                                          // Reset The Matrix
29.
30.       gl.glOrthof( 0, width, height, 0, -1, 1 );                // Select Ortho Mode
31.
32.       gl.glMatrixMode(GL_MODELVIEW);                                       // Select Modelview Matrix
33.
34.       gl.glPushMatrix();                                                                 // Push The Matrix
35.
36.       gl.glLoadIdentity();                                                          // Reset The Matrix
37.
38.    }
39.
40.
Parsed in 0.011 seconds, using GeSHi 1.0.8.4

Do a Google search on "opengl orthographic projection" and you'll find a lot of info.. Essentially it creates a top down projection suitable for using with exact width/height dimensions usually set to screen / display dimensions. This way you can specify vertex data in screen dimensions.

Also if you want to move or rotate a shape look at the glTranslatef and glRotatef methods. You can define your shape w/ vertex data around the origin (0, 0) and translate or rotate it accordingly to it's actual position. Take note that order of operations matters so you usually want to rotate (around origin) before translating.

You are almost there, so keep at it and good luck. Quite likely you may not have been doing things in the most efficient manner regarding the Android 2D API, but if you've got the time to learn OpenGL ES that will be the most solid direction to pursue.
Founder & Principal Architect; EGR Software LLC
http://www.typhonrt.org
http://www.egrsoftware.com

MichaelEGR
Senior Developer

Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

The most common problem with porting a java/canvas game to OpenGL is that the developer usually takes a function of DrawQuad from an internet tutorial, then replaces all the canvas quads with the new function. But the problem is that the game will still run very slow and the developer remains puzzled, because now he uses opengl and everything should go very fast.

A few advices when porting from j2me/canvas to opengl:
- Create texture atlases and put there all the sprites
- Group the atlases by game states (menu, game, levels, etc) so at a given moment you will use as fewer atlasses as possible
- Use vertex arrays and the bigger the better. If you have a maze for example, do not draw each cell with a different call, instead create an array and put there all the cells with colors, transparency, etc, so at the end you will draw the whole maze with a single render call, which is very efficient.

So get rid of that drawquad stuff, it's useful to draw single quads like full screen backgrounds, nothing more.

zorro
Experienced Developer

Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania