Android OpenGL анимация - PullRequest
       19

Android OpenGL анимация

0 голосов
/ 12 октября 2018

Я нахожусь в начале OpenGL 2.0, и я усовершенствовал руководство Google по рисованию квадрата и треугольника.Очевидно, это работает отлично:)

Теперь я пытаюсь добавить движение (перевод квадрата по вертикали).Проблема в том, что квадрат движется, но только один раз.Кто-то сказал мне, что цикла нет, но я думаю, что цикл выполняется методом "onDrawFrame", не так ли?

Может кто-нибудь помочь мне понять, где мои ошибки?

Спасибо за ваше время.

MainActivity:

public class MainActivity extends Activity {

private GLSurfaceView mGLView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a GLSurfaceView instance and set it
    // as the ContentView for this Activity
    mGLView = new MyGLSurfaceView(this);
    setContentView(mGLView);
}

@Override
protected void onPause() {
    super.onPause();
    mGLView.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    mGLView.onResume();
}
}

MyGLSurfaceView класс:

public class MyGLSurfaceView extends GLSurfaceView {

private final MyGLRenderer mRenderer;

public MyGLSurfaceView(Context context) {
    super(context);

    // Create an OpenGL ES 2.0 context.
    setEGLContextClientVersion(2);

    // Set the Renderer for drawing on the GLSurfaceView
    mRenderer = new MyGLRenderer();
    setRenderer(mRenderer);

    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

}

Класс рендерера:

<code>public class MyGLRenderer implements GLSurfaceView.Renderer {

private static final String TAG = "MyGLRenderer";
private Triangle mTriangle;
private Square   mSquare;
float i;
int direction;

// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];


@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {

   i = 0;
   direction = 1;

    // Set the background frame color
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    mTriangle = new Triangle();
    mSquare   = new Square();
}

@Override
public void onDrawFrame(GL10 unused) {
    float[] triangleScratch = new float[16];
    float[] squareScratch = new float[16];

    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -7, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);



//        Separate the square and the triangle
    Matrix.transposeM(squareScratch, 0, mMVPMatrix, 0);
    Matrix.transposeM(triangleScratch, 0, mMVPMatrix, 0);

    if(i>1) {direction = -1;}
    if(i<-1) {direction = 1;}
    i += 0.1 * direction;

    //Introduce a translation
    Matrix.translateM(squareScratch, 0, 0.0f, i, 0.0f);

    // Draw square
    mSquare.draw(squareScratch);




    // Draw triangle
    mTriangle.draw(triangleScratch);
}

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    // Adjust the viewport based on geometry changes,
    // such as screen rotation
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

}

/**
 * Utility method for compiling a OpenGL shader.
 *
 * <p><strong>Note:</strong> When developing shaders, use the checkGlError()
 * method to debug shader coding errors.</p>
 *
 * @param type - Vertex or fragment shader type.
 * @param shaderCode - String containing the shader code.
 * @return - Returns an id for the shader.
 */
public static int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

/**
 * Utility method for debugging OpenGL calls. Provide the name of the call
 * just after making it:
 *
 * <pre>
 * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
 * MyGLRenderer.checkGlError("glGetUniformLocation");
* * Еслиоперация не удалась, проверка выдает ошибку.* * @param glOperation - Имя вызова OpenGL для проверки.* / public static void checkGlError (String glOperation) {int error;while ((error = GLES20.glGetError ())! = GLES20.GL_NO_ERROR) {Log.e (TAG, glOperation + ": glError" + error);генерировать новое RuntimeException (glOperation + ": glError" + ошибка);}}}

Класс площади:

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;

// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float squareCoords[] = {
        0.0f, 1.0f, 0.0f,   // top left
        0.0f, 0.0f, 0.0f,   // bottom left
        1.0f, 0.0f, 0.0f,   // bottom right
        1.0f, 1.0f, 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[] = { 0.2f, 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);

    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
}

/**
 * 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);
}

}

Весь код находится здесь:

Ссылка на репозиторий кода

Спасибо всем, у кого есть терпение взглянуть на это.

1 Ответ

0 голосов
/ 16 октября 2018

Спасибо всем, кто взглянул на это.Решение состоит в том, чтобы закомментировать следующую строку в MyGLSurfaceView.java:

setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

Спасибо

...