问题
I've recently started using OpenGL ES 2 for android. I followed their examples for drawing shapes, and I went further and created a cube. I'm now trying to achieve a nice color effect(each face a different color). I ve defined a colorBuffer which has a color for each vertex, but when I'm drawing the shape the image is black.
If I use only one color, instead of the buffer the shape is fine.
I tried to adapt my colorBuffer from the positionBuffer, but I'm doing something wrong.
Here is my code:
public class Cube {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private final FloatBuffer colorsBuffer;
private static final int COORDS_PER_VERTEX = 3;
private static final int COORDS_PER_COLOR = 4;
private ShortBuffer drawListBuffer;
private int mColorHandle;
// float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
private float colors[] ={
// FRONT
1.0f, 0.5f, 0.0f, 1.0f,
1.0f, 0.5f, 0.0f, 1.0f,
1.0f, 0.5f, 0.0f, 1.0f,
1.0f, 0.5f, 0.0f, 1.0f,
//RIGHT
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
//RIGHT
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
//RIGHT
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
//RIGHT
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
//RIGHT
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f,
};
short[] drawOrder = {
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
8, 9, 10, 8, 10, 11,
12, 13, 14, 12, 14, 15,
16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23,
};
private float cubeCoords[] = {
// FRONT
-1.0f, 1.0f, 1.0f, // 0. top-left-front
-1.0f, -1.0f, 1.0f, // 1. bottom-left-front
1.0f, -1.0f, 1.0f, // 2. bottom-right-front
1.0f, 1.0f, 1.0f, // 3. top-right-front
// RIGHT
1.0f, 1.0f, 1.0f, // 3. top-right-front
1.0f, -1.0f, 1.0f, // 2. bottom-right-front
1.0f, -1.0f, -1.0f, // 4. right-top-front
1.0f, 1.0f, -1.0f, // 5. right-top-back
// BACK
1.0f, 1.0f, -1.0f, // 5. right-top-back
1.0f, -1.0f, -1.0f, // 4. right-top-front
-1.0f, -1.0f, -1.0f, // 6. right-top-back
-1.0f, 1.0f, -1.0f, // 7. left-top-back
// LEFT
-1.0f, 1.0f, -1.0f, // 7. left-top-back
-1.0f, -1.0f, -1.0f, // 6. right-top-back
-1.0f, -1.0f, 1.0f, // 1. bottom-left-front
-1.0f, 1.0f, 1.0f, // 0. top-left-front
// BOTTOM
-1.0f, -1.0f, 1.0f, // 1. bottom-left-front
1.0f, -1.0f, 1.0f, // 2. bottom-right-front
1.0f, -1.0f, -1.0f, // 4. right-top-front
-1.0f, -1.0f, -1.0f, // 6. right-top-back
// TOP
-1.0f, 1.0f, 1.0f, // 0. top-left-front
1.0f, 1.0f, 1.0f, // 3. top-right-front
1.0f, 1.0f, -1.0f, // 5. right-top-back
-1.0f, 1.0f, -1.0f, // 7. left-top-back
};
private final String vertexShaderCode =
"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 int MVPMatrixHandle;
private int mPositionHandle;
private int colorHandle;
private final int mProgram;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
private final int colorStride = COORDS_PER_COLOR * 4;
private final int vertexCount = cubeCoords.length / COORDS_PER_VERTEX;
// Constructor - Set up the buffers
public Cube() {
Log.d("TAG","vertexCount: "+vertexCount);
// Setup vertex-array buffer. Vertices in float. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(cubeCoords.length * 4);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
vertexBuffer.put(cubeCoords); // Copy data into buffer
vertexBuffer.position(0); // Rewind
// 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);
colorsBuffer = ByteBuffer.allocateDirect(colors.length * 4).order(ByteOrder.nativeOrder())
.asFloatBuffer();
colorsBuffer.put(colors);
colorsBuffer.position(0);
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glLinkProgram(mProgram);
}
// Draw the shape
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(mProgram);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
MVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
// 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);
GLES20.glEnableVertexAttribArray(mColorHandle);
GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_COLOR, GLES20.GL_FLOAT, false,
colorStride, colorsBuffer);
GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
回答1:
You're not doing anything with the color data in your shader programs, so you're uploading the data and not doing anything with it.
You need to add handling code for the new vertex attribute to your shaders; something like this:
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute mediump vec4 vColor;" +
"varying mediump vec4 vaColor;" +
"void main() {" +
" vaColor = vColor;" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"varying mediump vec4 vaColor;" +
"void main() {" +
" gl_FragColor = vaColor;" +
"}";
来源:https://stackoverflow.com/questions/40261651/opengl-es-2-color-buffer-not-working