// started from https://github.com/google/grafika/blob/f3c8c3dee60153f471312e21acac8b3a3cddd7dc/src/com/android/grafika/gles/Drawable2d.java
/*
* 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 io.cine.android.streaming.gles;
import java.nio.FloatBuffer;
/**
* Base class for stuff we like to draw.
*/
public class Drawable2d {
private static final int SIZEOF_FLOAT = 4;
/**
* Simple equilateral triangle (1.0 per side). Centered on (0,0).
*/
private static final float TRIANGLE_COORDS[] = {
0.0f, 0.577350269f, // 0 top
-0.5f, -0.288675135f, // 1 bottom left
0.5f, -0.288675135f // 2 bottom right
};
private static final FloatBuffer TRIANGLE_BUF =
GlUtil.createFloatBuffer(TRIANGLE_COORDS);
private static final float TRIANGLE_TEX_COORDS[] = {
0.5f, 0.0f, // 0 top center
0.0f, 1.0f, // 1 bottom left
1.0f, 1.0f, // 2 bottom right
};
private static final FloatBuffer TRIANGLE_TEX_BUF =
GlUtil.createFloatBuffer(TRIANGLE_TEX_COORDS);
/**
* Simple square, specified as a triangle strip. The square is centered on (0,0) and has
* a size of 1x1.
* <p/>
* Triangles are 0-1-2 and 2-1-3 (counter-clockwise winding).
*/
private static final float RECTANGLE_COORDS[] = {
-0.5f, -0.5f, // 0 bottom left
0.5f, -0.5f, // 1 bottom right
-0.5f, 0.5f, // 2 top left
0.5f, 0.5f, // 3 top right
};
private static final FloatBuffer RECTANGLE_BUF =
GlUtil.createFloatBuffer(RECTANGLE_COORDS);
private static final float RECTANGLE_TEX_COORDS[] = {
0.0f, 1.0f, // 0 bottom left
1.0f, 1.0f, // 1 bottom right
0.0f, 0.0f, // 2 top left
1.0f, 0.0f // 3 top right
};
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.
* <p/>
* 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, // 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 FloatBuffer FULL_RECTANGLE_BUF =
GlUtil.createFloatBuffer(FULL_RECTANGLE_COORDS);
private static final float FULL_RECTANGLE_TEX_COORDS[] = {
0.0f, 0.0f, // 0 bottom left
1.0f, 0.0f, // 1 bottom right
0.0f, 1.0f, // 2 top left
1.0f, 1.0f // 3 top right
};
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;
/**
* 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 = TRIANGLE_COORDS.length / mCoordsPerVertex;
break;
case RECTANGLE:
mVertexArray = RECTANGLE_BUF;
mTexCoordArray = RECTANGLE_TEX_BUF;
mCoordsPerVertex = 2;
mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
mVertexCount = RECTANGLE_COORDS.length / mCoordsPerVertex;
break;
case FULL_RECTANGLE:
mVertexArray = FULL_RECTANGLE_BUF;
mTexCoordArray = FULL_RECTANGLE_TEX_BUF;
mCoordsPerVertex = 2;
mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
mVertexCount = FULL_RECTANGLE_COORDS.length / mCoordsPerVertex;
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 stored in the vertex array.
*/
public int getVertexCount() {
return mVertexCount;
}
/**
* 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;
}
/**
* Returns the number of position coordinates per vertex. This will be 2 or 3.
*/
public int getCoordsPerVertex() {
return mCoordsPerVertex;
}
@Override
public String toString() {
if (mPrefab != null) {
return "[Drawable2d: " + mPrefab + "]";
} else {
return "[Drawable2d: ...]";
}
}
/**
* Enum values for constructor.
*/
public enum Prefab {
TRIANGLE, RECTANGLE, FULL_RECTANGLE
}
}