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

Postby renegadeandy » Sun Apr 25, 2010 11:19 pm

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


Syntax: [ Download ] [ Hide ]
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.039 seconds, using GeSHi 1.0.8.4
renegadeandy
Freshman
Freshman
 
Posts: 6
Joined: Mon Jun 22, 2009 7:29 pm

Top

Postby MichaelEGR » Mon Apr 26, 2010 12:36 am

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.

Syntax: [ Download ] [ Hide ]
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.035 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
User avatar
MichaelEGR
Senior Developer
Senior Developer
 
Posts: 147
Joined: Thu Jan 21, 2010 5:30 am
Location: San Francisco, CA

Postby zorro » Mon Apr 26, 2010 2:41 pm

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.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Top

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests