编写自定义OpenGL ES 2.0 Shader / MatrixHandler,获取空白屏幕

时间:2012-08-04 08:07:06

标签: android opengl-es opengl-es-2.0

我正在尝试使用GLES20为Android应用程序编写自己的着色器类和矩阵处理类。但是,现在我只得到背景颜色。

我已经把头发拉了几天。我想比较我的类和GL10之间的矩阵运算,以确保它们吐出相同的结果,但我不能在我的生活中得到api示例MatrixGrabber和MatrixTrackingGL除了单位矩阵之外吐出任何东西(尽管渲染正确地)。

所以我要发布一些代码,如果你发现这两个类中的任何问题,请告诉我!

这是我的MatrixHandler类:

import java.util.Stack;

import android.opengl.Matrix;

public class MatrixHandler
{
    public static float[] mMVPMatrix = new float[16];
    public static float[] mProjMatrix = new float[16];
    public static float[] mViewMatrix = new float[16];
    public static float[] mRotationMatrix = new float[16];

    public static Stack<float[]> mvpStack = new Stack<float[]>();
    public static Stack<float[]> projStack = new Stack<float[]>();
    public static Stack<float[]> viewStack = new Stack<float[]>();
    public static Stack<float[]> rotationStack = new Stack<float[]>();

    public static void setViewIdentity()
    {
        Matrix.setIdentityM(mViewMatrix, 0);
    }

    public static void setProjIdentity()
    {
        Matrix.setIdentityM(mProjMatrix, 0);
    }

    public static void setViewport(float left, float right, float bottom, float top, float near, float far)
    {
        Matrix.frustumM(mProjMatrix, 0,
                left, right,
                bottom, top,
                near, far
            );
    }

    public static void setLookAt(
            float eyeX, float eyeY, float eyeZ,
            float posX, float posY, float posZ,
            float upX, float upY, float upZ
        )
    {
        Matrix.setLookAtM(
                mViewMatrix, 0,

                eyeX, eyeY, eyeZ,
                posX, posY, posZ,
                upX, upY, upZ
            );

        //Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);
    }

    public static void translate(float x, float y, float z)
    {
        Matrix.translateM(mViewMatrix, 0,
                x, y, z
            );
        Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mMVPMatrix, 0);
    }

    public static void rotate(float a, float x, float y, float z)
    {
        Matrix.rotateM(mRotationMatrix, 0,
                a, x, y, z
            );
        Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
    }

    public static void pushMatrix()
    {
        mvpStack.push(mMVPMatrix);
        projStack.push(mProjMatrix);
        viewStack.push(mViewMatrix);
        rotationStack.push(mRotationMatrix);
    }

    public static void popMatrix()
    {
        mMVPMatrix = mvpStack.pop();
        mProjMatrix = projStack.pop();
        mViewMatrix = viewStack.pop();
        mRotationMatrix = rotationStack.pop();
    }

    public static void printMatrix(String label, float[] m)
    {
        System.err.print(label + " : {");
        for(float i : m)
        {
            System.err.print(i + ", ");
        }
        System.err.println("}");
    }
}

这是我的Shader课程:

import java.nio.FloatBuffer;

import com.bradsproject.appName.MatrixHandler;

import android.opengl.GLES20;

public class Shader
{
    private static int mProgram;

    static int maPositionHandle;
    static int maColorHandle;
    static int maTextureHandle;

    static int muMVPMatrixHandle;

    static int maTexture;

    private final static String mVertexShader =
        "uniform mat4 uMVPMatrix;" +
        "attribute vec3 aPosition;" +
        "attribute vec2 aTextureCoord;" +
        "attribute vec4 aColor;" +
        "varying vec4 vColor;" +
        "varying vec2 vTextureCoord;" +
        "void main() {" +
        "  gl_Position = uMVPMatrix * vec4(aPosition, 1.0);" +
        "  vTextureCoord = aTextureCoord;" +
        "  vColor = aColor;" +
        "}";

    private final static String mFragmentShader =
            "precision mediump float;" +
            "varying vec2 vTextureCoord;" +
            "uniform sampler2D sTexture;" +
            "varying vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = texture2D(sTexture, vTextureCoord);" +
            "}";

    public static void init()
    {
        mProgram = createProgram(mVertexShader, mFragmentShader);
        if (mProgram == 0)
            return;

        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
        maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
        maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");

        maTexture = GLES20.glGetUniformLocation(mProgram, "sTexture");

        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    }

    public static void drawArrays(FloatBuffer mPosition, FloatBuffer mColor, FloatBuffer mTexture, int textureId, int mode)
    {
        GLES20.glUseProgram(mProgram);

        mPosition.position(0);
        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 3 * 4, mPosition);
        GLES20.glEnableVertexAttribArray(maPositionHandle);

        mColor.position(0);
        GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 4 * 4, mColor);
        GLES20.glEnableVertexAttribArray(maColorHandle);

        mTexture.position(0);
        GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 2 * 4, mTexture);
        GLES20.glEnableVertexAttribArray(maTextureHandle);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
        GLES20.glUniform1i(maTexture, 0);

        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixHandler.mMVPMatrix, 0);

        GLES20.glDrawArrays(mode, 0, mPosition.capacity() / 3);
    }

    private static int createProgram(String vertexSource, String fragmentSource)
    {
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
        if (vertexShader == 0)
        {
            System.err.println("Failed to load vertex shader.");
            return 0;
        }

        int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
        if (pixelShader == 0)
        {
            System.err.println("Failed to load fragment shader.");
            return 0;
        }

        int program = GLES20.glCreateProgram();
        if (program != 0)
        {
            GLES20.glAttachShader(program, vertexShader);
            checkGlError("glAttachShader");
            GLES20.glAttachShader(program, pixelShader);
            checkGlError("glAttachShader");
            GLES20.glLinkProgram(program);
            int[] linkStatus = new int[1];
            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
            if (linkStatus[0] != GLES20.GL_TRUE)
            {
                GLES20.glDeleteProgram(program);
                program = 0;
            }
        }
        return program;
    }

    private static int loadShader(int shaderType, String source)
    {
        int shader = GLES20.glCreateShader(shaderType);
        if (shader != 0)
        {
            GLES20.glShaderSource(shader, source);
            GLES20.glCompileShader(shader);
            int[] compiled = new int[1];
            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
            if (compiled[0] == 0)
            {
                GLES20.glDeleteShader(shader);
                shader = 0;
            }
        }
        return shader;
    }

    private static void checkGlError(String op)
    {
        int error;
        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR)
        {
            throw new RuntimeException(op + ": glError " + error);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你最后遗漏了“\ n”

避免使用那些矩阵堆栈,当你的代码变得超过1000行代码时,无论是openglgame还是openglapp

,很快就会遇到那些沉重的事情。

对于速度使用const,着色器代码中的局部变量以及在片段着色器中执行更多计算

这是一个着色器集

private static final String vertexShaderCodeLight = 
        "uniform vec4 uVPosition;                   \n"
    +   "uniform mat4 uP;                           \n"
    +   "void main(){                               \n"
    +   " gl_PointSize = 15.0;                      \n"
    +   " gl_Position = uP * uVPosition;            \n"
    +   "}                                          \n";
private static final String fragmentShaderCodeLight = 
        "#ifdef GL_FRAGMENT_PRECISION_HIGH          \n"
    +   "precision highp float;                     \n"
    +   "#else                                      \n"
    +   "precision mediump float;                   \n"
    +   "#endif                                     \n"
    +   "void main(){                               \n"
    +   " gl_FragColor = vec4(1.0,1.0,1.0,1.0);     \n"
    +   "}                                          \n";