OpenGL渲染随机变化?

时间:2013-06-12 20:30:56

标签: java android opengl-es

对不起特定问题,但我找不到任何解释我的问题。我几乎可以肯定这是我忽略的一个愚蠢的错误。

我只想在屏幕上绘制一个基本的多色矩形。它工作正常,我甚至得到了模型 - 视图 - 投影矩阵的代码工作。但是,我发现当我尝试重新分配我用作MVP矩阵的统一值时,程序在渲染几百次后会突然失败。虽然最初几分钟我完全得到了我想要的东西,但在300次调用统一更新方法之后,我得到了一个完全不同的屏幕,其中有一个我从未要求的奇怪形状和颜色。

我尝试将代码减少到最低限度。我的片段着色器:

precision mediump float;

varying vec4 v_Color;

void main() {
    gl_FragColor = v_Color;
}

我的顶点着色器:

uniform mat4 u_MVP;

attribute vec4 a_Position;
attribute vec4 a_Color;

varying vec4 v_Color;

void main() {
    v_Color = a_Color;
    gl_Position = u_MVP * a_Position;
}

调用它的Java:

package com.ulyssecarion.openglsandbox;

import static android.opengl.GLES20.*;

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.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.util.Log;

import com.ulyssecarion.openglsandbox.util.ShaderHelper;
import com.ulyssecarion.openglsandbox.util.TextResourceReader;

public class OpenGLSandboxRenderer implements Renderer {
    private static final String TAG = "SandboxRenderer";

    private static final int POSITION_COMPONENT_COUNT = 2;
    private static final int COLOR_COMPONENT_COUNT = 3;
    private static final int BYTES_PER_FLOAT = 4;

    private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT)
            * BYTES_PER_FLOAT;

    private static final String U_MVP = "u_MVP";
    private static final String A_COLOR = "a_Color";
    private static final String A_POSITION = "a_Position";

    private float[] mvp;

    private float time;
    private int width;
    private int height;

    private int uMVP;
    private int aColor;
    private int aPosition;

    private Context context;
    private int program;

    public OpenGLSandboxRenderer(Context context) {
        time = 0;
        this.context = context;
    }

    @Override
    public void onDrawFrame(GL10 arg0) {
        glClear(GL_COLOR_BUFFER_BIT);

        setMVP(width, height);
        glUniformMatrix4fv(uMVP, 1, false, mvp, 0);

        glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
    }

    private static FloatBuffer toFB(float[] x) {
        ByteBuffer byteBuf = ByteBuffer.allocateDirect(x.length
                * BYTES_PER_FLOAT);
        byteBuf.order(ByteOrder.nativeOrder());
        FloatBuffer buffer = byteBuf.asFloatBuffer();
        buffer.put(x);
        buffer.position(0);
        return buffer;
    }

    @Override
    public void onSurfaceChanged(GL10 arg0, int width, int height) {
        glViewport(0, 0, width, height);

        uMVP = glGetUniformLocation(program, U_MVP);
        aColor = glGetAttribLocation(program, A_COLOR);
        aPosition = glGetAttribLocation(program, A_POSITION);

        Log.d(TAG, "MVP at: " + uMVP);

        setMVP(width, height);
        glUniformMatrix4fv(uMVP, 1, false, mvp, 0);

        // @formatter:off
        float[] points = {
                 0.0f,  0.0f, 1, 1, 1, 
                -0.5f, -0.5f, 0, 1, 0,
                 0.5f, -0.5f, 0, 0, 1, 
                 0.5f,  0.5f, 1, 1, 0,
                -0.5f,  0.5f, 0, 1, 1,
                -0.5f, -0.5f, 0, 1, 0
        };
        // @formatter:on

        FloatBuffer pointData = toFB(points);
        glVertexAttribPointer(aPosition, POSITION_COMPONENT_COUNT, GL_FLOAT,
                false, STRIDE, pointData);
        glEnableVertexAttribArray(aPosition);

        pointData.position(POSITION_COMPONENT_COUNT);
        glVertexAttribPointer(aColor, COLOR_COMPONENT_COUNT, GL_FLOAT, false,
                STRIDE, pointData);

        glEnableVertexAttribArray(aColor);
    }

    @Override
    public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
        glClearColor(0, 0, 0, 0);

        String vertexShaderSrc = TextResourceReader.readTextFileFromResource(
                context, R.raw.simple_vertex_shader);
        String fragmentShaderSrc = TextResourceReader.readTextFileFromResource(
                context, R.raw.simple_fragment_shader);
        int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSrc);
        int fragmentShader = ShaderHelper
                .compileFragmentShader(fragmentShaderSrc);

        program = ShaderHelper.linkProgram(vertexShader, fragmentShader);

        glUseProgram(program);
    }

    private void setMVP(int width, int height) {
        mvp = new float[16];

        Matrix.setIdentityM(mvp, 0);

        Log.d(TAG, "Setting MVP: " + time++);
    }
}

TextResourceReaderShaderHelper类是样板类,我确信它们可以正常工作。

有什么想法吗?

编辑:

通常情况如下:

编辑#2

这就是疯狂时的样子:

另一个例子:

(抱歉这些巨大的图片)

注意:结果并不总是如上所示。以前,它通常会导致黑屏。

0 个答案:

没有答案