com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer10.java Source code

Java tutorial

Introduction

Here is the source code for com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer10.java

Source

/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.graphics.glutils;

import java.nio.FloatBuffer;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.BufferUtils;
import com.badlogic.gdx.utils.GdxRuntimeException;

/** An ImmediateModeRenderer allows you to perform immediate mode rendering as you were accustomed to in your desktop OpenGL
 * environment. In order to draw something you first have to call {@link ImmediateModeRenderer10#begin(int)} with the primitive
 * type you want to render. Next you specify as many vertices as you want by first defining the vertex color, normal and texture
 * coordinates followed by the vertex position which finalizes the definition of a single vertex. When you are done specifying the
 * geometry you have to call {@link ImmediateModeRenderer10#end()} to make the renderer render the geometry. Internally the
 * renderer uses vertex arrays to render the provided geometry. This is not the best performing way to do this so use this class
 * only for non performance critical low vertex count geometries while debugging.
 * 
 * Note that this class of course only works with OpenGL ES 1.x.
 * 
 * @author mzechner */
public class ImmediateModeRenderer10 implements ImmediateModeRenderer {
    /** the primitive type **/
    private int primitiveType;

    /** the vertex position array and buffer **/
    private float[] positions;
    private FloatBuffer positionsBuffer;

    /** the vertex color array and buffer **/
    private float[] colors;
    private FloatBuffer colorsBuffer;

    /** the vertex normal array and buffer **/
    private float[] normals;
    private FloatBuffer normalsBuffer;

    /** the texture coordinate array and buffer **/
    private float[] texCoords;
    private FloatBuffer texCoordsBuffer;

    /** the current vertex attribute indices **/
    private int idxPos = 0;
    private int idxCols = 0;
    private int idxNors = 0;
    private int idxTexCoords = 0;

    private boolean hasCols;
    private boolean hasNors;
    private boolean hasTexCoords;

    private final int maxVertices;
    private int numVertices;

    /** Constructs a new ImmediateModeRenderer */
    public ImmediateModeRenderer10() {
        this(2000);
    }

    /** Constructs a new ImmediateModeRenderer */
    public ImmediateModeRenderer10(int maxVertices) {
        this.maxVertices = maxVertices;
        if (Gdx.graphics.isGL20Available())
            throw new GdxRuntimeException("ImmediateModeRenderer can only be used with OpenGL ES 1.0/1.1");

        this.positions = new float[3 * maxVertices];
        this.positionsBuffer = BufferUtils.newFloatBuffer(3 * maxVertices);
        this.colors = new float[4 * maxVertices];
        this.colorsBuffer = BufferUtils.newFloatBuffer(4 * maxVertices);
        this.normals = new float[3 * maxVertices];
        this.normalsBuffer = BufferUtils.newFloatBuffer(3 * maxVertices);
        this.texCoords = new float[2 * maxVertices];
        this.texCoordsBuffer = BufferUtils.newFloatBuffer(2 * maxVertices);
    }

    public void begin(Matrix4 projModelView, int primitiveType) {
        GL10 gl = Gdx.gl10;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadMatrixf(projModelView.val, 0);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        begin(primitiveType);
    }

    /** Starts a new list of primitives. The primitiveType specifies which primitives to draw. Can be any of GL10.GL_TRIANGLES,
     * GL10.GL_LINES and so on. A maximum of 6000 vertices can be drawn at once.
     * 
     * @param primitiveType the primitive type. */
    public void begin(int primitiveType) {
        this.primitiveType = primitiveType;
        numVertices = 0;
        idxPos = 0;
        idxCols = 0;
        idxNors = 0;
        idxTexCoords = 0;
        hasCols = false;
        hasNors = false;
        hasTexCoords = false;
    }

    /** Specifies the color of the current vertex
     * @param r the red component
     * @param g the green component
     * @param b the blue component
     * @param a the alpha component */
    public void color(float r, float g, float b, float a) {
        colors[idxCols] = r;
        colors[idxCols + 1] = g;
        colors[idxCols + 2] = b;
        colors[idxCols + 3] = a;
        hasCols = true;
    }

    /** Specifies the normal of the current vertex
     * @param x the x component
     * @param y the y component
     * @param z the z component */
    public void normal(float x, float y, float z) {
        normals[idxNors] = x;
        normals[idxNors + 1] = y;
        normals[idxNors + 2] = z;
        hasNors = true;
    }

    /** Specifies the texture coordinates of the current vertex
     * @param u the u coordinate
     * @param v the v coordinate */
    public void texCoord(float u, float v) {
        texCoords[idxTexCoords] = u;
        texCoords[idxTexCoords + 1] = v;
        hasTexCoords = true;
    }

    /** Specifies the position of the current vertex and finalizes it. After a call to this method you will effectively define a new
     * vertex afterwards.
     * 
     * @param x the x component
     * @param y the y component
     * @param z the z component */
    public void vertex(float x, float y, float z) {
        positions[idxPos++] = x;
        positions[idxPos++] = y;
        positions[idxPos++] = z;

        if (hasCols)
            idxCols += 4;
        if (hasNors)
            idxNors += 3;
        if (hasTexCoords)
            idxTexCoords += 2;
        numVertices++;
    }

    public int getNumVertices() {
        return numVertices;
    }

    public int getMaxVertices() {
        return maxVertices;
    }

    /** Renders the primitives just defined. */
    public void end() {
        if (idxPos == 0)
            return;

        GL10 gl = Gdx.gl10;
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        positionsBuffer.clear();
        BufferUtils.copy(positions, positionsBuffer, idxPos, 0);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, positionsBuffer);

        if (hasCols) {
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
            colorsBuffer.clear();
            BufferUtils.copy(colors, colorsBuffer, idxCols, 0);
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorsBuffer);
        }

        if (hasNors) {
            gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
            normalsBuffer.clear();
            BufferUtils.copy(normals, normalsBuffer, idxNors, 0);
            gl.glNormalPointer(GL10.GL_FLOAT, 0, normalsBuffer);
        }

        if (hasTexCoords) {
            gl.glClientActiveTexture(GL10.GL_TEXTURE0);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
            texCoordsBuffer.clear();
            BufferUtils.copy(texCoords, texCoordsBuffer, idxTexCoords, 0);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordsBuffer);
        }

        gl.glDrawArrays(primitiveType, 0, idxPos / 3);

        if (hasCols)
            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        if (hasNors)
            gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
        if (hasTexCoords)
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    public void vertex(Vector3 point) {
        vertex(point.x, point.y, point.z);
    }

    @Override
    public void dispose() {
    }
}