我试图找出如何创建顶点缓冲区以在屏幕上绘制彩色方块网格。大小为108 x 192(屏幕分辨率)。我试着查看this code获取GLES32并重新制作Square类以生成多色网格,但没有成功。
有人能给我一个例子,我可以学习如何用GLES32.glDrawArrays创建一个位置+颜色顶点来创建网格吗?
最终目标是创建一个使用VSync(无混合)的多色方格网格,最重要的是,我可以使用特定的rgb值在每次扫描时更新,所以它看起来像这样:
我非常感谢任何帮助。
这是我到目前为止基于this thread:
import android.opengl.GLES32;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
/**
* A two-dimensional square for use as a drawn object in OpenGL ES 2.0.
*/
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() {" +
// The matrix must be included as a modifier of gl_Position.
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" 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;
private static int GRID_ROWS = 108;
private static int GRID_COLS = 192;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
private float[] mVertices;
private short[] mIndices;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
float color[] = { 0.2f, 0.709803922f, 0.898039216f, 1.0f };
void makePlane(int rows, int columns) {
mVertices = new float[rows*columns*COORDS_PER_VERTEX*2];
mIndices = new short[rows*columns*COORDS_PER_VERTEX*2];
// Set up mVertices
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns; ++c) {
int index = r*columns + c;
mVertices[3*index + 0] = (float) c;
mVertices[3*index + 1] = (float) r;
mVertices[3*index + 2] = 0.0f;
}
}
// Set up mIndices
int i = 0;
for (int r = 0; r < rows - 1; ++r) {
mIndices[i++] = (short) (r * columns);
for (int c = 0; c < columns; ++c) {
mIndices[i++] = (short) (r * columns + c);
mIndices[i++] = (short) ((r + 1) * columns + c);
}
mIndices[i++] = (short) ((r + 1) * columns + (columns - 1));
}
}
/**
* Sets up the drawing object data for use in an OpenGL ES context.
*/
public Square() {
// Prepare vertices and indices
makePlane(GRID_ROWS, GRID_COLS);
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
mVertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(mVertices);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
mIndices.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(mIndices);
drawListBuffer.position(0);
// prepare shaders and OpenGL program
int vertexShader = MyGLRenderer.loadShader(
GLES32.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES32.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES32.glCreateProgram(); // create empty OpenGL Program
GLES32.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES32.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES32.glLinkProgram(mProgram); // create OpenGL program executables
}
/**
* 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
GLES32.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES32.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle mVertices
GLES32.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES32.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES32.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
// mColorHandle = GLES32.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES32.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES32.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES32.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES32.glDrawElements(
GLES32.GL_TRIANGLES, mIndices.length,
GLES32.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES32.glDisableVertexAttribArray(mPositionHandle);
}
}
不幸的是,它会产生以下错误:
at edu.cs4730.helloopengles32.MyGLRenderer.checkGlError(MyGLRenderer.java:147)
at edu.cs4730.helloopengles32.Square.draw(Square.java:167)
at edu.cs4730.helloopengles32.MyGLRenderer.onDrawFrame(MyGLRenderer.java:73)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)