3

我的代码和网站上的代码几乎一模一样,只是变量名有一些变化:

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 手机上测试它时它确实起作用(尽管投影和相机视图仍然不起作用)。

4

0 回答 0