(1)四角形を表示するだけ。
塗りつぶし色はuniform変数で指定している。
(2)三角形
頂点カラー
サンプル(EGLのSurfaceを利用)
https://1drv.ms/u/s!ApO4wsxFJBbVuUr4rbo3RkWkdF_b?e=vmgUss
これはGLSurfaceViewのversion
https://1drv.ms/u/s!ApO4wsxFJBbVuUs1oL5qN6Zflebi?e=pjxOUU
◆attribute 変数の index の指定
attribute 変数 position には, アプリケーションプログラム側から頂点情報 (位置) を与えなければならないので, この変数の index を獲得します. これには, 以下の二つの方法があります.
1)index の決定をシェーダのリンカ glLinkProgram() に任せて, リンク後に glGetAttribLocation() でそれを調べる方法
2)リンク前に glBindAttribLocation() を使って index を明示的に指定する方法
Androidのjava層のopenglesは(2)しか使えない?
native/c++で昔触ったときは制約なかったと思う。
package com.ore.blackv2;
//package com.example.android.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.opengl.GLES20;
import android.util.Log;
import static android.opengl.GLES20.GL_FALSE;
import static android.opengl.GLES20.GL_LINK_STATUS;
import static android.opengl.GLES20.glDeleteProgram;
import static android.opengl.GLES20.glGetProgramInfoLog;
import static android.opengl.GLES20.glGetProgramiv;
public class Square {
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private final FloatBuffer vertexBuffer;
private final ShortBuffer drawListBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float squareCoords[] = {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
float color[] = { 1.0f, 0.709803922f, 0.898039216f, 1.0f };
/**
* Sets up the drawing object data for use in an OpenGL ES context.
*/
public Square() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// prepare shaders and OpenGL program
// int vertexShader = MyGLRenderer.loadShader( GLES20.GL_VERTEX_SHADER, vertexShaderCode);
// int fragmentShader = MyGLRenderer.loadShader( GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
int vertexShader = GLESUtils.createShader( GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = GLESUtils.createShader( GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
int[] status = new int[1];
glGetProgramiv(mProgram, GL_LINK_STATUS, status, 0);
if (status[0] == GL_FALSE) {
//Log.e(TAG, glGetProgramInfoLog(mProgram));
glDeleteProgram(mProgram);
}
}
/**
* Encapsulates the OpenGL ES instructions for drawing this shape.
*
* @param mvpMatrix - The Model View Project matrix in which to draw
* this shape.
*/
public void draw(float[] mvpMatrix) {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//MyGLRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
//MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
public class Triangle {
public final String vertexShaderCode =
"attribute vec4 vPosition;" +
"attribute vec4 vColor;" +
"varying mediump vec4 varColor;"+
"void main() {" +
" varColor = vColor;"+
" gl_Position = vPosition;" +
"}";
public final String fragmentShaderCode =
"precision mediump float;" +
"varying mediump vec4 varColor;"+
"void main() {" +
" gl_FragColor = varColor;" +
"}";
private int loadShader(int type, String shaderCode){
int err = 0;
int shader = GLES20.glCreateShader(type);
err = EGL14.eglGetError();
if (err != EGL14.EGL_SUCCESS) return 0;
GLES20.glShaderSource(shader, shaderCode);
if (EGL14.eglGetError() != EGL14.EGL_SUCCESS) return 0;
GLES20.glCompileShader(shader);
return shader;
}
private int shaderProgram;
public Triangle() {
}
public int Init(){
int err = 0;
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return err;
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return err;
int[] status = new int[1];
glGetProgramiv(shaderProgram, GL_LINK_STATUS, status, 0);
if (status[0] == GL_FALSE) {
String msz = glGetProgramInfoLog(shaderProgram);
Log.e("sample", glGetProgramInfoLog(shaderProgram));
glDeleteProgram(shaderProgram);
}
return GLES20.GL_NO_ERROR;
}
public void draw(){
int err = 0;
//if( shaderProgram == 0 ) return;
GLES20.glUseProgram(shaderProgram);
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return ;
int positionAttrib = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
GLES20.glEnableVertexAttribArray(positionAttrib);
if( true ) {
// xyz, rgba,
float vertices[] = {
0.0f, 0.4f, 0.0f, 1.0f,
-0.3f, -0.3f, 0.0f, 1.0f,
0.5f, -0.3f, 0.0f, 1.0f,
};
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
int stride = 0;
GLES20.glVertexAttribPointer(positionAttrib, 4, GLES20.GL_FLOAT, false, stride, vertexBuffer);
}
boolean enableColor = true;
int colorAttrib = 0;
if( enableColor ) {
float colors[] = {
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
colorAttrib = GLES20.glGetAttribLocation(shaderProgram, "vColor");
GLES20.glEnableVertexAttribArray(colorAttrib);
ByteBuffer bb2 = ByteBuffer.allocateDirect(colors.length * 4);
bb2.order(ByteOrder.nativeOrder());
FloatBuffer colorBuffer = bb2.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
int stride = 0;
GLES20.glVertexAttribPointer(colorAttrib, 4, GLES20.GL_FLOAT, false, stride, colorBuffer);
}
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
GLES20.glDisableVertexAttribArray(positionAttrib);
if( enableColor ) {
GLES20.glDisableVertexAttribArray(colorAttrib);
}
}
package com.ore.egltest4;
import java.nio.*;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.EGL14;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;
import static android.opengl.GLES20.GL_FALSE;
import static android.opengl.GLES20.GL_LINK_STATUS;
import static android.opengl.GLES20.glDeleteProgram;
import static android.opengl.GLES20.glGetProgramInfoLog;
import static android.opengl.GLES20.glGetProgramiv;
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_ELEMENT_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_STATIC_DRAW;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glViewport;
import static android.opengl.GLES20.GL_TRIANGLES;
import static android.opengl.GLES20.GL_UNSIGNED_INT;
import static android.opengl.GLES20.glAttachShader;
import static android.opengl.GLES20.glBufferData;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glCompileShader;
import static android.opengl.GLES20.glCreateProgram;
import static android.opengl.GLES20.glCreateShader;
import static android.opengl.GLES20.glDeleteShader;
import static android.opengl.GLES20.glDrawElements;
import static android.opengl.GLES20.glGenBuffers;
import static android.opengl.GLES20.glGetProgramInfoLog;
import static android.opengl.GLES20.glGetProgramiv;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glLinkProgram;
import static android.opengl.GLES20.glShaderSource;
import static android.opengl.GLES20.glViewport;
import static android.opengl.GLES20.glGetShaderiv;
import static android.opengl.GLES20.glBindAttribLocation;
import static android.opengl.GLES20.glGenTextures;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glTexImage2D;
import static android.opengl.GLES20.glTexParameterf;
import static android.opengl.GLES20.glGetIntegerv;
import static android.opengl.GLES20.glGenFramebuffers;
import static android.opengl.GLES20.glBindFramebuffer;
import static android.opengl.GLES20.glFramebufferTexture2D;
import static android.opengl.GLES20.glCheckFramebufferStatus;
import static android.opengl.GLES20.glGetError;
import static android.opengl.GLES20.glBindBuffer;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glActiveTexture;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glDisableVertexAttribArray;
import static android.opengl.GLES20.glTexParameteri;
import static android.opengl.GLES20.glVertexAttribPointer;
import android.opengl.GLES11Ext;
import static android.opengl.EGL14.eglGetError;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_RGBA;
import static android.opengl.GLES20.GL_UNSIGNED_BYTE;
import static android.opengl.GLES20.GL_LINEAR;
import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
import static android.opengl.GLES20.GL_FRAMEBUFFER_BINDING;
import static android.opengl.GLES20.GL_TEXTURE_WRAP_S;
import static android.opengl.GLES20.GL_CLAMP_TO_EDGE;
import static android.opengl.GLES20.GL_TEXTURE_WRAP_T;
import static android.opengl.GLES20.GL_FRAMEBUFFER;
import static android.opengl.GLES20.GL_COLOR_ATTACHMENT0;
import static android.opengl.GLES20.GL_DEPTH_ATTACHMENT;
import static android.opengl.GLES20.GL_RENDERBUFFER;
import static android.opengl.GLES20.GL_FRAMEBUFFER_COMPLETE;
import static android.opengl.GLES20.GL_TEXTURE0;
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
import static android.opengl.GLES20.GL_COMPILE_STATUS;
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_ELEMENT_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_FALSE;
import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
import static android.opengl.GLES20.GL_LINK_STATUS;
import static android.opengl.GLES20.GL_NO_ERROR;
import static android.opengl.GLES20.GL_STATIC_DRAW;
import static android.opengl.GLES20.GL_VERTEX_SHADER;
/*
* public final String vertexShaderCode =
"attribute vec4 vPosition;" +
"attribute vec4 vColor;" +
"attribute vec2 vUV;" +
"varying mediump vec2 varUV;"+
"varying mediump vec4 varColor;"+
"void main() {" +
" varColor = vColor;"+
" gl_Position = vPosition;" +
" varUV = vUV.st;"+
"}";
public final String fragmentShaderCode =
"precision mediump float;" +
"uniform sampler2D sampler2d;"+
"varying mediump vec2 varUV;"+
"varying mediump vec4 varColor;"+
"void main() {" +
" gl_FragColor = varColor;" +
" gl_FragColor = texture2D(sampler2d,varUV);"+
"}";
* */
public class Triangle {
public final String vertexShaderCode =
"attribute vec4 vPosition;" +
"attribute vec4 vColor;" +
"attribute vec2 vUV;" +
"varying mediump vec2 varUV;"+
"varying mediump vec4 varColor;"+
"void main() {" +
" varColor = vColor;"+
" varUV = vUV.st;"+
" gl_Position = vPosition;" +
"}";
public final String fragmentShaderCode =
"precision mediump float;" +
"uniform sampler2D sampler2d;"+
"varying mediump vec2 varUV;"+
"varying mediump vec4 varColor;"+
"void main() {" +
" gl_FragColor = texture2D(sampler2d,varUV);"+
"}";
private int loadShader(int type, String shaderCode){
int err = 0;
int shader = GLES20.glCreateShader(type);
err = EGL14.eglGetError();
if (err != EGL14.EGL_SUCCESS) return 0;
GLES20.glShaderSource(shader, shaderCode);
if (EGL14.eglGetError() != EGL14.EGL_SUCCESS) return 0;
GLES20.glCompileShader(shader);
return shader;
}
private static String LOGTAG = "ORE";
public static void checkError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(LOGTAG, op + ": glError 0x" + Integer.toHexString(error));
}
}
private int shaderProgram;
public Triangle() {
}
int[] m_nIchimatsuTexture = new int[1];
int[] m_nHogeTexture = new int[1];
public void loadGLTexture(Context context){
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.texaxis);
//Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.r1);
Bitmap bitmap01 = Bitmap.createScaledBitmap(bitmap, 512, 512, false);
try {
bitmap = bitmap01;
} finally {
}
glGenTextures(1, m_nHogeTexture, 0);
glBindTexture(GL_TEXTURE_2D, m_nHogeTexture[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
}
//やり方がわからない。
/*
void init_texture()
{
final int TEX_SIZE = 256;
byte[] pTexData = new byte[TEX_SIZE*TEX_SIZE*4];
for (int i = 0; i < TEX_SIZE; i++) {
for (int j = 0; j < TEX_SIZE; j++) {
// Fills the data with a fancy pattern
//int col = (255 << 24) + ((255 - j * 2) << 16) + ((255 - i) << 8) + (255 - i * 2);
int col1 = 255;
int col2 = (255 - j * 2);
int col3 = (255 - i);
int col4 = (255 - i * 2);
if(( ((i * j) / 8) % 2) != 0){
// col = (int) (255 << 24) + (255 << 16) + (0 << 8) + (255);
col1 = 255;
col2 = 255;
col3 = 0;
col4 = 255;
}
//pTexData[j * TEX_SIZE + i] = col;
int index = (i*TEX_SIZE + j)*4;
pTexData[index + 3] = (byte)col1;
pTexData[index + 2] = (byte)col2;
pTexData[index + 1] = (byte)col3;
pTexData[index + 0] = (byte)col4;
}
}
//for (int i = 0; i < TEX_SIZE*TEX_SIZE*4; i++) pTexData[i] = (byte)0xff;
GLES20.glGenTextures(1, m_nIchimatsuTexture,0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, m_nIchimatsuTexture[0]);
GLES20.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLES20.glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
checkError("glTexParameterf");
{
Bitmap bitmap = BitmapFactory.decodeByteArray(pTexData, 0, pTexData.length);
Bitmap bitmap01 = Bitmap.createScaledBitmap(bitmap, TEX_SIZE, TEX_SIZE, false);
try {
bitmap = bitmap01;
} catch (Exception e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.allocate(TEX_SIZE * TEX_SIZE);
bb.wrap(pTexData);
GLES20.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, bb);
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
checkError("glTexImage2D");
}
}*/
public int Init(){
int err = 0;
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return err;
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return err;
int[] status = new int[1];
glGetProgramiv(shaderProgram, GL_LINK_STATUS, status, 0);
if (status[0] == GL_FALSE) {
String msz = glGetProgramInfoLog(shaderProgram);
Log.e("sample", glGetProgramInfoLog(shaderProgram));
glDeleteProgram(shaderProgram);
}
// init_texture();
return GLES20.GL_NO_ERROR;
}
public void draw(){
int err = 0;
//if( shaderProgram == 0 ) return;
GLES20.glUseProgram(shaderProgram);
err = GLES20.glGetError();
if (err != GLES20.GL_NO_ERROR) return ;
glBindTexture(GL_TEXTURE_2D, m_nHogeTexture[0]);
glActiveTexture((m_nHogeTexture[0]));
glUniform1i(glGetUniformLocation(shaderProgram, "sampler2d"), 0);
int positionAttrib = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
GLES20.glEnableVertexAttribArray(positionAttrib);
if( true ) {
// xyz, rgba,
float vertices[] = {
-0.6f, -0.4f, 0.0f, 1.0f,
0.6f, -0.4f, 0.0f, 1.0f,
-0.6f, 0.4f, 0.0f, 1.0f,
0.6f, 0.4f, 0.0f, 1.0f,
};
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
int stride = 0;
GLES20.glVertexAttribPointer(positionAttrib, 4, GLES20.GL_FLOAT, false, stride, vertexBuffer);
}
boolean enableColor = true;
int colorAttrib = 0;
if( enableColor ) {
float colors[] = {
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
colorAttrib = GLES20.glGetAttribLocation(shaderProgram, "vColor");
GLES20.glEnableVertexAttribArray(colorAttrib);
ByteBuffer bb2 = ByteBuffer.allocateDirect(colors.length * 4);
bb2.order(ByteOrder.nativeOrder());
FloatBuffer colorBuffer = bb2.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
int stride = 0;
glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, false, stride, colorBuffer);
}
boolean enableTexture = true;
int uvAttrib = 0;
if( enableTexture ) {
float uvs[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
uvAttrib = GLES20.glGetAttribLocation(shaderProgram, "vUV");
GLES20.glEnableVertexAttribArray(uvAttrib);
checkError("glEnableVertexAttribArray");
ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer uvBuffer = bb.asFloatBuffer();
uvBuffer.put(uvs);
uvBuffer.position(0);
int stride = 0;
glVertexAttribPointer(uvAttrib, 2, GL_FLOAT, false, stride, uvBuffer);
checkError("glVertexAttribPointer");
}
//GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
checkError("glDrawArrays");
GLES20.glDisableVertexAttribArray(positionAttrib);
if( enableColor ) GLES20.glDisableVertexAttribArray(colorAttrib);
if( enableTexture ) GLES20.glDisableVertexAttribArray(uvAttrib);
checkError("glDisableVertexAttribArray");
}
}