将顶点传递给着色器时出错

时间:2015-01-18 10:41:16

标签: android opengl-es glsl opengl-es-2.0 vertex-shader

我开始使用简单的2d gles 2.0 android应用程序。 出于某些奇怪的原因,我总是在屏幕中心得到一个点而不是传递给着色器的顶点坐标。 我显然做错了什么。无法理解什么。 Lonely point 附:我没有使用任何投影矩阵,因为我需要标准的四边形绘图。尝试投射 - 没有帮助。

public class TestActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glv = new GLSurfaceView(this);
        glv.setEGLContextClientVersion(2);
        SimpleRenderer renderer = new SimpleRenderer(this);
        glv.setRenderer(renderer);
        glv.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
        setContentView(glv);
    }
}

public class SimpleRenderer implements GLSurfaceView.Renderer {
    private final float[] squareVertices = {
            -1.0f, -1.0f,
            1.0f, -1.0f,
            -1.0f,  1.0f,
            1.0f,  1.0f,
    };
    private FloatBuffer squareBuffer;

    private final Context context;

    private int text_program;
    private int aPositionLocation2;


    public SimpleRenderer(Context context) {
        this.context = context;
        squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).asFloatBuffer();
        squareBuffer.put(squareVertices).position(0);
    }

    public void onDrawFrame(GL10 gl) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(text_program);
        glEnableVertexAttribArray(aPositionLocation2);
        glVertexAttribPointer(aPositionLocation2, 2, GL_FLOAT, false, 0, squareBuffer);
        glDrawArrays(GL_POINTS, 0, 4);
        glDisableVertexAttribArray(aPositionLocation2);

    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        glViewport(0, 0, width, height);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        text_program = ShaderHelper.buildProgram(TextResourceReader.readTextFileFromResource(context, R.raw.texture_vertex_shader),
                TextResourceReader.readTextFileFromResource(context, R.raw.texture_fragment_shader));

        aPositionLocation2 = glGetAttribLocation(text_program, "a_Position");
        glClearColor(0f, 0f, 0f, 0f);
    }
}

public class ShaderHelper {
    private static final String TAG = "ShaderHelper";

    public static int compileVertexShader(String shaderCode) {
        return compileShader(GL_VERTEX_SHADER, shaderCode);
    }

    public static int compileFragmentShader(String shaderCode) {
        return compileShader(GL_FRAGMENT_SHADER, shaderCode);
    }

    private static int compileShader(int type, String shaderCode) {
        final int shaderObjectId = glCreateShader(type);
        if (shaderObjectId == 0) Log.w(TAG, "Shader not created!");
        glShaderSource(shaderObjectId, shaderCode);
        glCompileShader(shaderObjectId);
        final int[] compileStatus = new int[1];
        glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
        Log.v(TAG, "Results of compiling source:" + "\n" + shaderCode + "\n:"
                + glGetShaderInfoLog(shaderObjectId));
        if (compileStatus[0] == 0) {
            // If it failed, delete the shader object.
            glDeleteShader(shaderObjectId);
            Log.w(TAG, "Compilation of shader failed.");
            return 0;
        }
        return shaderObjectId;
    }

    public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
        final int programObjectId = glCreateProgram();
        if (programObjectId == 0) {
            Log.w(TAG, "Could not create new program");
            return 0;
        }
        glAttachShader(programObjectId, vertexShaderId);
        glAttachShader(programObjectId, fragmentShaderId);
        glLinkProgram(programObjectId);
        final int[] linkStatus = new int[1];
        glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
        Log.v(TAG, "Results of linking program:\n"
                + glGetProgramInfoLog(programObjectId));
        if (linkStatus[0] == 0) {
            // If it failed, delete the program object.
            glDeleteProgram(programObjectId);
            Log.w(TAG, "Linking of program failed.");
            return 0;
        }
        return programObjectId;
    }

    public static boolean validateProgram(int programObjectId) {
        glValidateProgram(programObjectId);
        final int[] validateStatus = new int[1];
        glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
        Log.v(TAG, "Results of validating program: " + validateStatus[0]
                + "\nLog:" + glGetProgramInfoLog(programObjectId));
        return validateStatus[0] != 0;
    }

    public static int buildProgram(String vertexShaderSource,
                                   String fragmentShaderSource) {
        int program;
        // Compile the shaders.
        int vertexShader = compileVertexShader(vertexShaderSource);
        int fragmentShader = compileFragmentShader(fragmentShaderSource);
        // Link them into a shader program.
        program = linkProgram(vertexShader, fragmentShader);

        validateProgram(program);

        return program;
    }

}

顶点着色器:

attribute vec4 a_Position;

void main()
{
    gl_Position = a_Position;
    gl_PointSize = 10.0;
}

片段着色器:

void main()
{
    gl_FragColor = vec4(1.0,1.0,1.0,1.0);
}

1 个答案:

答案 0 :(得分:1)

问题确实在于传递顶点数据:OpenGL使用本机字节顺序(x86 emu的little-endian),但我在java(我认为是big-endian)中分配了缓冲区,因此损坏的浮点值被传递给顶点着色器。在字节缓冲区中指定字节顺序后,一切正常。

squareBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();