| page.title=Defining Shapes |
| parent.title=Displaying Graphics with OpenGL ES |
| parent.link=index.html |
| |
| trainingnavtop=true |
| previous.title=Building an OpenGL ES Environment |
| previous.link=environment.html |
| next.title=Drawing Shapes |
| next.link=draw.html |
| |
| @jd:body |
| |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| |
| <h2>This lesson teaches you to</h2> |
| <ol> |
| <li><a href="#triangle">Define a Triangle</a></li> |
| <li><a href="#square">Define a Square</a></li> |
| </ol> |
| |
| <h2>You should also read</h2> |
| <ul> |
| <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li> |
| </ul> |
| |
| <div class="download-box"> |
| <a href="{@docRoot}shareables/training/OpenGLES.zip" |
| class="button">Download the sample</a> |
| <p class="filename">OpenGLES.zip</p> |
| </div> |
| |
| </div> |
| </div> |
| |
| <p>Being able to define shapes to be drawn in the context of an OpenGL ES view is the first step in |
| creating your high-end graphics masterpiece. Drawing with OpenGL ES can be a little tricky without |
| knowing a few basic things about how OpenGL ES expects you to define graphic objects.</p> |
| |
| <p>This lesson explains the OpenGL ES coordinate system relative to an Android device screen, the |
| basics of defining a shape, shape faces, as well as defining a triangle and a square.</p> |
| |
| |
| <h2 id="triangle">Define a Triangle</h2> |
| |
| <p>OpenGL ES allows you to define drawn objects using coordinates in three-dimensional space. So, |
| before you can draw a triangle, you must define its coordinates. In OpenGL, the typical way to do |
| this is to define a vertex array of floating point numbers for the coordinates. For maximum |
| efficiency, you write these coordinates into a {@link java.nio.ByteBuffer}, that is passed into the |
| OpenGL ES graphics pipeline for processing.</p> |
| |
| <pre> |
| public class Triangle { |
| |
| private FloatBuffer vertexBuffer; |
| |
| // number of coordinates per vertex in this array |
| static final int COORDS_PER_VERTEX = 3; |
| static float triangleCoords[] = { // in counterclockwise order: |
| 0.0f, 0.622008459f, 0.0f, // top |
| -0.5f, -0.311004243f, 0.0f, // bottom left |
| 0.5f, -0.311004243f, 0.0f // bottom right |
| }; |
| |
| // Set color with red, green, blue and alpha (opacity) values |
| float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; |
| |
| public Triangle() { |
| // initialize vertex byte buffer for shape coordinates |
| ByteBuffer bb = ByteBuffer.allocateDirect( |
| // (number of coordinate values * 4 bytes per float) |
| triangleCoords.length * 4); |
| // use the device hardware's native byte order |
| bb.order(ByteOrder.nativeOrder()); |
| |
| // create a floating point buffer from the ByteBuffer |
| vertexBuffer = bb.asFloatBuffer(); |
| // add the coordinates to the FloatBuffer |
| vertexBuffer.put(triangleCoords); |
| // set the buffer to read the first coordinate |
| vertexBuffer.position(0); |
| } |
| } |
| </pre> |
| |
| <p>By default, OpenGL ES assumes a coordinate system where [0,0,0] (X,Y,Z) specifies the center of |
| the {@link android.opengl.GLSurfaceView} frame, [1,1,0] is the top right corner of the frame and |
| [-1,-1,0] is bottom left corner of the frame. For an illustration of this coordinate system, see the |
| <a href="{@docRoot}guide/topics/graphics/opengl.html#coordinate-mapping">OpenGL ES</a> developer |
| guide.</p> |
| |
| <p>Note that the coordinates of this shape are defined in a counterclockwise order. The drawing |
| order is important because it defines which side is the front face of the shape, which you typically |
| want to have drawn, and the back face, which you can choose to not draw using the OpenGL ES cull |
| face feature. For more information about faces and culling, see the <a |
| href="{@docRoot}guide/topics/graphics/opengl.html#faces-winding">OpenGL ES</a> developer guide.</p> |
| |
| |
| <h2 id="square">Define a Square</h2> |
| |
| <p>Defining triangles is pretty easy in OpenGL, but what if you want to get a just a little more |
| complex? Say, a square? There are a number of ways to do this, but a typical path to drawing such a |
| shape in OpenGL ES is to use two triangles drawn together:</p> |
| |
| <img src="{@docRoot}images/opengl/ccw-square.png"> |
| <p class="img-caption"> |
| <strong>Figure 1.</strong> Drawing a square using two triangles.</p> |
| |
| <p>Again, you should define the vertices in a counterclockwise order for both triangles that |
| represent this shape, and put the values in a {@link java.nio.ByteBuffer}. In order to avoid |
| defining the two coordinates shared by each triangle twice, use a drawing list to tell the |
| OpenGL ES graphics pipeline how to draw these vertices. Here’s the code for this shape:</p> |
| |
| <pre> |
| public class Square { |
| |
| private FloatBuffer vertexBuffer; |
| private ShortBuffer drawListBuffer; |
| |
| // number of coordinates per vertex in this array |
| static final int COORDS_PER_VERTEX = 3; |
| static float squareCoords[] = { |
| -0.5f, 0.5f, 0.0f, // top left |
| -0.5f, -0.5f, 0.0f, // bottom left |
| 0.5f, -0.5f, 0.0f, // bottom right |
| 0.5f, 0.5f, 0.0f }; // top right |
| |
| private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices |
| |
| public Square() { |
| // initialize vertex byte buffer for shape coordinates |
| ByteBuffer bb = ByteBuffer.allocateDirect( |
| // (# of coordinate values * 4 bytes per float) |
| squareCoords.length * 4); |
| bb.order(ByteOrder.nativeOrder()); |
| vertexBuffer = bb.asFloatBuffer(); |
| vertexBuffer.put(squareCoords); |
| vertexBuffer.position(0); |
| |
| // initialize byte buffer for the draw list |
| ByteBuffer dlb = ByteBuffer.allocateDirect( |
| // (# of coordinate values * 2 bytes per short) |
| drawOrder.length * 2); |
| dlb.order(ByteOrder.nativeOrder()); |
| drawListBuffer = dlb.asShortBuffer(); |
| drawListBuffer.put(drawOrder); |
| drawListBuffer.position(0); |
| } |
| } |
| </pre> |
| |
| <p>This example gives you a peek at what it takes to create more complex shapes with OpenGL. In |
| general, you use collections of triangles to draw objects. In the next lesson, you learn how to draw |
| these shapes on screen.</p> |