我的代码和网站上的代码几乎一模一样,只是变量名有一些变化:
package com.example.opengltraining;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
public class MyGL20Renderer implements GLSurfaceView.Renderer{
private Triangle triangle1;
private final float[] mProjMatrix = new float[16];
private final float[] mVMatrix = new float[16];
private final float[] mMVPMatrix = new float[16];
private final float[] mRotationMatrix = new float[16];
public static int loadShader(int type, String shaderCode){
//create vertex shader type
//or fragment shader type
int shader = GLES20.glCreateShader(type);
//add source code to shader and compile
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
public void redrawTriangle(float[]triangleCoords){
triangle1.changeTriangle(triangleCoords);
}
public void onSurfaceCreated(GL10 unused, EGLConfig config){
//set background fram color
GLES20.glClearColor(1f,0.5f, 0.25f, .5f);
triangle1 = new Triangle();
}
public void onDrawFrame(GL10 unused) {
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
// Draw triangle
triangle1.draw(mMVPMatrix);
}
public void onSurfaceChanged(GL10 unused, int width, int height){
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
//applies projection matrix to object coordinates
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7);
}
}
class Triangle{
//shaders - vertex
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
//shaders - fragment
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private FloatBuffer vertexBuffer;
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 triangleCoords[] = { // in counterclockwise order:
0.0f, 0.5f, 0.0f, // top
-0.5f, -0.25f, 0.0f, // bottom left
0.5f, -0.25f, 0.0f // bottom right
};
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4;
//color of triangle
float color[] = { 0f, 1f, 0f, 1.0f };
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");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
public void changeTriangle(float [] newTriangleCoords){
ByteBuffer bb = ByteBuffer.allocateDirect(newTriangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(newTriangleCoords);
vertexBuffer.position(0);
}
public Triangle(){
//init vertex buffer for shape cordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
//number of cord vals * 4 bytes per float
triangleCoords.length * 4);
//use hardware's native byte order
bb.order(ByteOrder.nativeOrder());
//create floating point buffer
vertexBuffer = bb.asFloatBuffer();
//add coords to floatbuffer
vertexBuffer.put(triangleCoords);
//set buffer to read first coord
vertexBuffer.position(0);
int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
//creates program for the triangle to go in.,
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glLinkProgram(mProgram);
}
}
我已经测试了这段代码与没有添加投影和相机视图的原始代码,两者之间没有区别。此外,由于某种原因,当我在模拟器上测试它时它不起作用,但当我在实际的 android 手机上测试它时它确实起作用(尽管投影和相机视图仍然不起作用)。