1

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

我只想在屏幕上绘制一个基本的多色矩形。它工作得很好,我什至得到了模型-视图-投影矩阵的代码。但是,我发现当我尝试重新分配我用作MVP矩阵的uniform的值时,程序会在渲染几百次后突然失败。虽然最初的几分钟我得到了我想要的东西,但在调用了大约 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

这是它发疯时的样子:

另一个例子:

(对不起,巨大的图像)

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

4

0 回答 0