content: /*
   * Copyright 2014 Google Inc. All rights reserved.
   *
   * 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.fadcam.opengl.grafika;
  
  import java.nio.FloatBuffer;
  
  /**
   * Base class for stuff we like to draw.
   */
  public class Drawable2d {
      private static final int SIZEOF_FLOAT = 4;
  
      /**
       * Simple triangle (vertices).
       */
      private static final float TRIANGLE_COORDS[] = {
           0.0f,  0.577350269f,   // top
          -0.5f, -0.288675135f,   // bottom left
           0.5f, -0.288675135f    // bottom right
      };
      private static final float TRIANGLE_TEX_COORDS[] = {
          0.5f, 0.0f,     // top
          0.0f, 1.0f,     // bottom left
          1.0f, 1.0f      // bottom right
      };
      private static final FloatBuffer TRIANGLE_BUF =
              GlUtil.createFloatBuffer(TRIANGLE_COORDS);
      private static final FloatBuffer TRIANGLE_TEX_BUF =
              GlUtil.createFloatBuffer(TRIANGLE_TEX_COORDS);
  
      /**
       * Simple square, specified as a triangle strip.  The specified original is flipped vertically.
       */
      private static final float RECTANGLE_COORDS[] = {
          -1.0f, -1.0f,   // 0 bottom left
           1.0f, -1.0f,   // 1 bottom right
          -1.0f,  1.0f,   // 2 top left
           1.0f,  1.0f,   // 3 top right
      };
      private static final float RECTANGLE_TEX_COORDS[] = {
          0.0f, 1.0f,     // 2 top left
          1.0f, 1.0f,     // 3 top right
          0.0f, 0.0f,     // 0 bottom left
          1.0f, 0.0f      // 1 bottom right
      };
      private static final FloatBuffer RECTANGLE_BUF =
              GlUtil.createFloatBuffer(RECTANGLE_COORDS);
      private static final FloatBuffer RECTANGLE_TEX_BUF =
              GlUtil.createFloatBuffer(RECTANGLE_TEX_COORDS);
  
      /**
       * A "full" square, extending from -1 to +1 in both dimensions.  When the model/view/projection
       * matrix is identity, this will exactly cover the viewport.
       *
       * The texture coordinates are Y-inverted relative to RECTANGLE.  (This seems to work out
       * right with external textures from SurfaceTexture.)
       */
      private static final float FULL_RECTANGLE_COORDS[] = {
          -1.0f, -1.0f,   // bottom left
           1.0f, -1.0f,   // bottom right
          -1.0f,  1.0f,   // top left
           1.0f,  1.0f,   // top right
      };
      private static final float FULL_RECTANGLE_TEX_COORDS[] = {
          0.0f, 0.0f,     // bottom left
          1.0f, 0.0f,     // bottom right
          0.0f, 1.0f,     // top left
          1.0f, 1.0f      // top right
      };
      private static final FloatBuffer FULL_RECTANGLE_BUF =
              GlUtil.createFloatBuffer(FULL_RECTANGLE_COORDS);
      private static final FloatBuffer FULL_RECTANGLE_TEX_BUF =
              GlUtil.createFloatBuffer(FULL_RECTANGLE_TEX_COORDS);
  
  
      private FloatBuffer mVertexArray;
      private FloatBuffer mTexCoordArray;
      private int mVertexCount;
      private int mCoordsPerVertex;
      private int mVertexStride;
      private int mTexCoordStride;
      private Prefab mPrefab;
  
      /**
       * Enum values for constructor.
       */
      public enum Prefab {
          TRIANGLE, RECTANGLE, FULL_RECTANGLE
      }
  
      /**
       * Prepares a drawable from a "pre-fabricated" shape definition.
       * <p>
       * Does no EGL/GL operations, so this can be done at any time.
       */
      public Drawable2d(Prefab shape) {
          switch (shape) {
              case TRIANGLE:
                  mVertexArray = TRIANGLE_BUF;
                  mTexCoordArray = TRIANGLE_TEX_BUF;
                  mCoordsPerVertex = 2;
                  mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
                  mVertexCount = 3;
                  break;
              case RECTANGLE:
                  mVertexArray = RECTANGLE_BUF;
                  mTexCoordArray = RECTANGLE_TEX_BUF;
                  mCoordsPerVertex = 2;
                  mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
                  mVertexCount = 4;
                  break;
              case FULL_RECTANGLE:
                  mVertexArray = FULL_RECTANGLE_BUF;
                  mTexCoordArray = FULL_RECTANGLE_TEX_BUF;
                  mCoordsPerVertex = 2;
                  mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
                  mVertexCount = 4;
                  break;
              default:
                  throw new RuntimeException("Unknown shape " + shape);
          }
          mTexCoordStride = 2 * SIZEOF_FLOAT;
          mPrefab = shape;
      }
  
      /**
       * Returns the array of vertices.
       * <p>
       * To avoid allocations, this returns internal state.  The caller must not modify it.
       */
      public FloatBuffer getVertexArray() {
          return mVertexArray;
      }
  
      /**
       * Returns the array of texture coordinates.
       * <p>
       * To avoid allocations, this returns internal state.  The caller must not modify it.
       */
      public FloatBuffer getTexCoordArray() {
          return mTexCoordArray;
      }
  
      /**
       * Returns the number of vertices in the shape.
       */
      public int getVertexCount() {
          return mVertexCount;
      }
  
      /**
       * Returns the number of position coordinates per vertex.  This will be 2 or 3.
       */
      public int getCoordsPerVertex() {
          return mCoordsPerVertex;
      }
  
      /**
       * Returns the width, in bytes, of the data for each vertex.
       */
      public int getVertexStride() {
          return mVertexStride;
      }
  
      /**
       * Returns the width, in bytes, of the data for each texture coordinate.
       */
      public int getTexCoordStride() {
          return mTexCoordStride;
      }
  
      @Override
      public String toString() {
          if (mPrefab != null) {
              return "[Drawable2d: " + mPrefab + "]";
          } else {
              return "[Drawable2d: ...]";
          }
      }
  } 