Android Open Source - android-plotter Base Mesh






From Project

Back to project page android-plotter.

License

The source code is released under:

Apache License

If you think the Android project android-plotter listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.solovyev.android.plotter.meshes;
//w  ww .j  a v a2s .c o  m
import org.solovyev.android.plotter.Check;
import org.solovyev.android.plotter.Color;
import org.solovyev.android.plotter.MeshConfig;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public abstract class BaseMesh implements Mesh {

  private static final int NULL = 0xDEADC0DE;

  /**
   * Note that all properties of this class must be accessed from the GL thread if not stated otherwise
   */

  /**
   * OpenGL instance associated with this mesh. This must be a instance which is used for drawing.
   */
  protected GL11 gl;
  protected MeshConfig config;

  private FloatBuffer vertices;
  private int verticesCount = -1;

  private ShortBuffer indices;
  private int indicesCount = -1;
  @Nonnull
  private IndicesOrder indicesOrder = IndicesOrder.TRIANGLES;

  private FloatBuffer colors;
  private int colorsCount = -1;

  /**
   * Vertex buffer objects
   */
  protected boolean useVbo;
  private int verticesVbo = NULL;
  private int indicesVbo = NULL;
  private int colorsVbo = NULL;

  // can be set from any thread
  @Nonnull
  private volatile Color color = Color.WHITE;

  // can be accessed/changed from any thread
  @Nonnull
  private final StateHolder state = new StateHolder();

  private static boolean supportsVbo(@Nonnull GL11 gl) {
    final String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
    return extensions.contains("vertex_buffer_object");
  }

  @Nonnull
  public Color getColor() {
    return color;
  }

  @Nonnull
  public final State getState() {
    return state.get();
  }

  protected final void setDirty() {
    state.setDirty();
  }

  @Override
  public final boolean init() {
    Check.isNotMainThread();
    if (!state.setIf(State.INITIALIZING, State.DIRTY)) {
      return false;
    }
    onInit();
    return state.set(State.INIT);
  }

  /**
   * Method initializes mesh. Note that this method might be called on background thread
   */
  protected void onInit() {
  }

  @Override
  public final boolean initGl(@Nonnull GL11 gl, @Nonnull MeshConfig config) {
    Check.isGlThread();

    if (this.gl == null || !this.gl.equals(gl)) {
      state.setIf(State.INIT, State.INIT_GL);
    }
    if (!state.setIf(State.INITIALIZING_GL, State.INIT)) {
      return false;
    }

    this.gl = gl;
    this.config = config;

    final boolean usedVbo = useVbo;
    useVbo = this.config.useVbo && supportsVbo(gl);
    if (usedVbo) {
      gl.glDeleteBuffers(3, new int[]{verticesVbo, colorsVbo, indicesVbo}, 0);
    }

    if (useVbo) {
      final int[] out = new int[3];
      gl.glGenBuffers(3, out, 0);
      verticesVbo = out[0];
      colorsVbo = out[1];
      indicesVbo = out[2];
    } else {
      verticesVbo = NULL;
      colorsVbo = NULL;
      indicesVbo = NULL;
    }
    onInitGl(gl, config);
    return state.set(State.INIT_GL);
  }

  /**
   * Method initializes mesh on the GL thread
   *
   * @param gl     gl instance
   * @param config configuration
   */
  protected void onInitGl(@Nonnull GL11 gl, @Nonnull MeshConfig config) {
  }

  public final void draw(@Nonnull GL11 gl) {
    Check.isGlThread();

    if (getState() != State.INIT_GL) {
      return;
    }
    final boolean hasColors = colorsCount >= 0;

    // counter-clockwise winding
    gl.glFrontFace(GL10.GL_CCW);

    if (config.cullFace) {
      gl.glEnable(GL10.GL_CULL_FACE);
      gl.glCullFace(GL10.GL_BACK);
    }

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    if (hasColors) {
      gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    }

    if (!hasColors) {
      gl.glColor4f(color.red, color.green, color.blue, color.alpha);
    }

    onPreDraw(gl);
    if (useVbo) {
      gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, verticesVbo);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);

      if (hasColors) {
        gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, colorsVbo);
        gl.glColorPointer(Color.COMPONENTS, GL10.GL_FLOAT, 0, 0);
      }

      gl.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indicesVbo);
      gl.glDrawElements(indicesOrder.glMode, indicesCount, GL10.GL_UNSIGNED_SHORT, 0);
      gl.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
    } else {
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);

      if (hasColors) {
        gl.glColorPointer(Color.COMPONENTS, GL10.GL_FLOAT, 0, colors);
      }

      gl.glDrawElements(indicesOrder.glMode, indicesCount, GL10.GL_UNSIGNED_SHORT, indices);
    }
    onPostDraw(gl);

    if (hasColors) {
      gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
    }
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    if (config.cullFace) {
      gl.glDisable(GL10.GL_CULL_FACE);
    }
  }

  protected void onPostDraw(@Nonnull GL11 gl) {
  }

  protected void onPreDraw(@Nonnull GL11 gl) {
  }

  @Nonnull
  @Override
  public final BaseMesh copy() {
    final BaseMesh copy = makeCopy();
    copy.color = this.color;
    return copy;
  }

  @Nonnull
  protected abstract BaseMesh makeCopy();

  protected void setVertices(float[] vertices) {
    setVertices(Meshes.allocateOrPutBuffer(vertices, this.vertices));
  }

  protected final void setVertices(@Nonnull FloatBuffer vertices) {
    Check.isGlThread();
    this.vertices = vertices;
    this.verticesCount = vertices.capacity() / 3;

    if (useVbo) {
      bindVboBuffer(this.vertices, verticesVbo, GL11.GL_ARRAY_BUFFER);
      this.vertices = null;
    }
  }

  private void bindVboBuffer(@Nonnull FloatBuffer source, int destination, int type) {
    bindVboBuffer(source, source.capacity() * Meshes.BYTES_IN_FLOAT, destination, type);
  }

  private void bindVboBuffer(@Nonnull ShortBuffer source, int destination, int type) {
    bindVboBuffer(source, source.capacity() * Meshes.BYTES_IN_SHORT, destination, type);
  }

  private void bindVboBuffer(@Nonnull Buffer source, int sourceBytes, int destination, int type) {
    gl.glBindBuffer(type, destination);
    gl.glBufferData(type, sourceBytes, source, GL11.GL_STATIC_DRAW);
    gl.glBindBuffer(type, 0);
  }

  protected final void setIndices(short[] indices, @Nonnull IndicesOrder order) {
    setIndices(Meshes.allocateOrPutBuffer(indices, this.indices), order);
  }

  protected final void setIndices(@Nonnull ShortBuffer indices, @Nonnull IndicesOrder order) {
    Check.isGlThread();
    this.indices = indices;
    this.indicesCount = indices.capacity();
    this.indicesOrder = order;

    if (useVbo) {
      bindVboBuffer(this.indices, indicesVbo, GL11.GL_ELEMENT_ARRAY_BUFFER);
      this.indices = null;
    }
  }

  @Nonnull
  public final BaseMesh withColor(int color) {
    setColor(color);
    return this;
  }

  @Nonnull
  public final BaseMesh withColor(@Nonnull Color color) {
    setColor(color);
    return this;
  }

  public final void setColor(int color) {
    setColor(Color.create(color));
  }

  public final void setColor(@Nonnull Color color) {
    // todo serso: we must null colors here and call setDirty if they were not null
    this.color = color;
  }

  protected void setColors(@Nonnull float[] colors) {
    Check.isGlThread();
    if (verticesCount <= 0) {
      throw new IllegalStateException("Vertices must be set before setting the color");
    }
    if (verticesCount != colors.length / Color.COMPONENTS) {
      throw new IllegalStateException("Colors length must be the same as vertices length");
    }

    this.colors = Meshes.allocateBuffer(colors);
    this.colorsCount = colors.length / Color.COMPONENTS;

    if (useVbo) {
      bindVboBuffer(this.colors, colorsVbo, GL11.GL_ARRAY_BUFFER);
      this.colors = null;
    }
  }

  private static final class StateHolder {
    @GuardedBy("this")
    @Nonnull
    private State state = State.DIRTY;

    @GuardedBy("this")
    @Nullable
    private State delayedState;

    @Nonnull
    public State get() {
      synchronized (this) {
        return delayedState != null ? delayedState : state;
      }
    }

    private boolean setIf(@Nonnull State newState, @Nonnull State oldState) {
      synchronized (this) {
        if (state != oldState) {
          return false;
        }
        state = newState;
      }
      return true;
    }

    public void setDirty() {
      synchronized (this) {
        if (state == State.INITIALIZING || state == State.INITIALIZING_GL) {
          // if we are in the middle of initialization process we should postpone setting dirty state until
          // the process is done
          delayedState = State.DIRTY;
        } else {
          state = State.DIRTY;
        }
      }
    }

    public boolean set(@Nonnull State newState) {
      synchronized (this) {
        if (delayedState != null) {
          state = delayedState;
          delayedState = null;
          return false;
        } else {
          state = newState;
          return true;
        }
      }
    }
  }

  static class Swapper<M extends BaseMesh> implements DoubleBufferMesh.Swapper<M> {
    @Override
    public void swap(@Nonnull M current, @Nonnull M next) {
      next.setColor(((BaseMesh) current).color);
    }
  }
}




Java Source Code List

com.android.texample.GLText.java
com.android.texample.SpriteBatch.java
com.android.texample.TexampleRenderer.java
com.android.texample.TextureRegion.java
com.android.texample.Vertices.java
org.solovyev.android.plotter.Angle.java
org.solovyev.android.plotter.AxisStyle.java
org.solovyev.android.plotter.Check.java
org.solovyev.android.plotter.Color.java
org.solovyev.android.plotter.DefaultPlotter.java
org.solovyev.android.plotter.Dimensions.java
org.solovyev.android.plotter.Frustum.java
org.solovyev.android.plotter.Function0.java
org.solovyev.android.plotter.Function1.java
org.solovyev.android.plotter.Function2.java
org.solovyev.android.plotter.Function.java
org.solovyev.android.plotter.LineStyle.java
org.solovyev.android.plotter.MeshConfig.java
org.solovyev.android.plotter.MultisampleConfigChooser.java
org.solovyev.android.plotter.PinchZoomTracker.java
org.solovyev.android.plotter.PlotData.java
org.solovyev.android.plotter.PlotFunction.java
org.solovyev.android.plotter.PlotRenderer.java
org.solovyev.android.plotter.PlotView.java
org.solovyev.android.plotter.Plot.java
org.solovyev.android.plotter.Plotter.java
org.solovyev.android.plotter.PlottingView.java
org.solovyev.android.plotter.Spf.java
org.solovyev.android.plotter.SuperFunction.java
org.solovyev.android.plotter.TouchHandler.java
org.solovyev.android.plotter.ZoomLevels.java
org.solovyev.android.plotter.Zoomer.java
org.solovyev.android.plotter.app.MainActivity.java
org.solovyev.android.plotter.app.PlotterApplication.java
org.solovyev.android.plotter.meshes.Arrays.java
org.solovyev.android.plotter.meshes.AxisGrid.java
org.solovyev.android.plotter.meshes.Axis.java
org.solovyev.android.plotter.meshes.BaseCube.java
org.solovyev.android.plotter.meshes.BaseCurve.java
org.solovyev.android.plotter.meshes.BaseMesh.java
org.solovyev.android.plotter.meshes.BaseSurface.java
org.solovyev.android.plotter.meshes.DimensionsAwareSwapper.java
org.solovyev.android.plotter.meshes.DimensionsAware.java
org.solovyev.android.plotter.meshes.DoubleBufferGroup.java
org.solovyev.android.plotter.meshes.DoubleBufferMesh.java
org.solovyev.android.plotter.meshes.FunctionGraph2d.java
org.solovyev.android.plotter.meshes.FunctionGraph3d.java
org.solovyev.android.plotter.meshes.FunctionGraphSwapper.java
org.solovyev.android.plotter.meshes.FunctionGraph.java
org.solovyev.android.plotter.meshes.Graph.java
org.solovyev.android.plotter.meshes.Group.java
org.solovyev.android.plotter.meshes.IndicesOrder.java
org.solovyev.android.plotter.meshes.ListGroup.java
org.solovyev.android.plotter.meshes.ListPool.java
org.solovyev.android.plotter.meshes.Mesh.java
org.solovyev.android.plotter.meshes.Meshes.java
org.solovyev.android.plotter.meshes.Pool.java
org.solovyev.android.plotter.meshes.Scene.java
org.solovyev.android.plotter.meshes.SolidCube.java
org.solovyev.android.plotter.meshes.SurfaceInitializer.java
org.solovyev.android.plotter.meshes.WireFrameCube.java