## Vertices3 Storing 3D Positions

Let's write a new class called Vertices3 to handle 3D vertices based on our original Vertices class. Listing 10-1 shows the code.

Listing 10-1. Vertices3.java, Now with More Coordinates package com.badlogic.androidgames.framework.gl;

import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import com.badlogic.androidgames.framework.impl.GLGraphics;

public class Vertices3 {

final GLGraphics glGraphics; final boolean hasColor; final boolean hasTexCoords; final int vertexSize; final IntBuffer vertices; final int[] tmpBuffer; final ShortBuffer indices;

public Vertices3(GLGraphics glGraphics, int maxVertices, int maxIndices, boolean hasColor, boolean hasTexCoords) { this.glGraphics = glGraphics; this.hasColor = hasColor; this.hasTexCoords = hasTexCoords;

this.vertexSize = (3 + (hasColor ? 4 : 0) + (hasTexCoords ? 2 : 0)) * 4; this.tmpBuffer = new int[maxVertices * vertexSize / 4];

ByteBuffer buffer = ByteBuffer.allocateDirect(maxVertices * vertexSize); buffer.order(ByteOrder.nativeOrder()); vertices = buffer.asIntBuffer();

buffer = ByteBuffer.aIIocateDirect(maxIndices * Short.SIZE / 8); buffer.order(ByteOrder.nativeOrder()); indices = buffer.asShortBuffer(); } else {

indices = null;

public void setVertices(float[] vertices, int offset, int length) { this.vertices.clear(); int len = offset + length; for (int i = offset, j = 0; i < len; i++, j++)

tmpBuffer[j] = Float. floatToRawIntBits(vertices[i]); this.vertices.put(tmpBuffer, 0, length); this.vertices.flip();

public void setIndices(short[] indices, int offset, int length) { this.indices.clear();

this.indices.put(indices, offset, length); this.indices.flip();

public void bind() {

GL10 gl = glGraphics.getGL();

gl.glEnableClientState(GL10. GL_VERTEX_ARRAY); vertices.position(0);

gl.glVertexPointer(3, GL10.GL_FLOAT, vertexSize, vertices);

gl.glEnableClientState(GL10.GL_COLOR_ARRAY); vertices.position(3);

gl.glColorPointer(4, GL10.GL_FLOAT, vertexSize, vertices);

if (hasTexCoords) {

gl.glEnableClientState(GL10. GL_TEXTURE_COORD_ARRAY); vertices.position(hasColor ? 7 : 3);

gl.glTexCoordPointer(2, GL10.GL_FLOAT, vertexSize, vertices);

public void draw(int primitiveType, int offset, int numVertices) { GL10 gl = glGraphics.getGL();

indices.position(offset); gl.glDrawElements(primitiveType, numVertices, GL10.GL_UNSIGNED_SHORT, indices);

gl.glDrawArrays(primitiveType, offset, numVertices);

public void unbind() {

GL10 gl = glGraphics.getGL(); if (hasTexCoords)

gl.glDisableClientState(GL10. GL_TEXTURE_COORD_ARRAY);

if (hasColor)

gl.glDisableClientState(GL10. GL_COLOR_ARRAY);

Everything stays the same compared to Vertices except for four little things. In the constructor we calculate vertexSize differently, since the vertex position takes three instead of two floats now.

In the bind() method we tell OpenGL ES that our vertices have three instead of two coordinates in the call to glVertexPointer() (first argument). We also have to adjust the offsets we set in the calls to vertices.position() for the optional color and texture coordinate components.

That's all we need to do. Using the Vertices3 class, we now have to specify the x-, y-, and z-coordinates for each vertex when we call the Vertices3.setVertices() method. Everything else stays the same usage-wise. We can have per-vertex colors, texture coordinates, indices, and so on.

0 0