使用glVertexAttribPointer和glDrawElements从包装的顶点缓冲区绘制 [英] Using glVertexAttribPointer and glDrawElements to draw from a packed vertex buffer

查看:248
本文介绍了使用glVertexAttribPointer和glDrawElements从包装的顶点缓冲区绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含现在的位置是一个拥挤的顶点缓冲格式藏汉坐标颜色值顶点{X,Y,Z,R,G,B,A}

我能够用硬$ C $唯彩正确显示矩形时,我采取了a_Color属性和硬编码gl_FragColor一个vec4值改变片段着色器,但我不能够通过颜色vec4属性进入片段着色器(矩形不会在那种情况下显示)。

什么是使用glVertexAttribPointer(...)和glDrawElements(...)从包装顶点缓冲区中的OpenGL ES 2.0得出正确的方法是什么?

请参阅下面我的code:

 公共类GameRenderer实现渲染{
    公共静态最终诠释POS_SZ = 3;
    公共静态最终诠释COL_SZ = 4;
    公共静态最终诠释FLOAT_SZ = 4;
    公共静态最终诠释SHORT_SZ = 2;    私人FloatBuffer gridVB;
    私人ShortBuffer gridIndices;
    INT程序code,paPositionHandle,paColorHandle,puMVPMatrixHandle;    私人最终字符串vertexShader code =
        统一mat4 u_MVPMatrix; \\ n+
        属性vec4 a_Position; \\ n+
        无效的主要(){\\ n+
        GL_POSITION = u_MVPMatrix * a_Position; \\ n+
        } \\ n;    私人字符串fragmentShader code =
        precision mediump浮动; \\ n+
        属性vec4 a_Color; \\ n+
        无效的主要(){\\ n+
        gl_FragColor = a_Color; \\ n+
        } \\ n;    公共无效staticGrid(){
        浮vertexArray [] = {
            -0.75f​​,0.75f​​,0.0,//位置
            0.0,0.0,1.0F,1.0F,//颜色
            0.75f​​,0.75f​​,0.0,
            0.0,0.0,1.0F,1.0F,
            0.75f​​,-0.75f​​,0.0,
            0.0,0.0,1.0F,1.0F,
            -0.75f​​,-0.75f​​,0.0,
            0.0,0.0,1.0F,1.0F
        };        短indicesArray [] = {
            0,1,2,0,2,3
        };        ByteBuffer的VBB = ByteBuffer.allocateDirect(vertexArray.length * FLOAT_SZ);
        vbb.order(ByteOrder.nativeOrder());
        gridVB = vbb.asFloatBuffer();
        gridVB.put(vertexArray);
        gridVB.position(0);        IBB的ByteBuffer = ByteBuffer.allocateDirect(indicesArray.length * SHORT_SZ);
        ibb.order(ByteOrder.nativeOrder());
        gridIndices = ibb.asShortBuffer();
        gridIndices.put(indicesArray);
        gridIndices.position(0);
    }    公共无效onSurfaceCreated(GL10不用,EGLConfig ARG1){
        GLES20.glClearColor(0.5F,0.5F,0.5F,1.0F);
        staticGrid();
        INT vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
        INT fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShader code);
        程序code = GLES20.glCreateProgram();
        GLES20.glAttachShader(程序code,vertexShader);
        GLES20.glAttachShader(程序code,fragmentShader);
        GLES20.glLinkProgram(程序code);        paPositionHandle = GLES20.glGetAttribLocation(程序code,a_Position);
        paColorHandle = GLES20.glGetAttribLocation(程序code,a_Color);
        puMVPMatrixHandle = GLES20.glGetUniformLocation(程序code,u_MVPMatrix);
    }    公共无效onDrawFrame(GL10未使用){
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        GLES20.glUseProgram(程序code);        INT跨距=(POS_SZ + COL_SZ)* FLOAT_SZ;
        INT indices_cnt = 6;        gridVB.position(0);
        GLES20.glEnableVertexAttribArray(paPositionHandle);
        GLES20.glVertexAttribPointer(paPositionHandle,POS_SZ,GLES20.GL_FLOAT,假的,步幅,gridVB);        gridVB.position(POS_SZ);
        GLES20.glEnableVertexAttribArray(paColorHandle);
        GLES20.glVertexAttribPointer(paColorHandle,COL_SZ,GLES20.GL_FLOAT,假的,步幅,gridVB);        //矩阵操作...        GLES20.glDrawElements(GLES20.GL_TRIANGLES,indices_cnt,GLES20.GL_UNSIGNED_SHORT,gridIndices);
    }
}


解决方案

片段着色器不使用的属性。属性是每个顶点值,其中一个片段着色器不会一无所知。你想要做的是把颜色作为属性来的顶点着色器,然后用不同来通过颜色的片段着色器。

另外,请开始使用错误检查你的着色器,它会告诉你,当你做这样的错误:

<一个href=\"http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramiv.xml\">http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramiv.xml (检查 GL_LINK_STATUS

<一个href=\"http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderiv.xml\">http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderiv.xml (检查 GL_COMPILE_STATUS

<一个href=\"http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramInfoLog.xml\">http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramInfoLog.xml

<一个href=\"http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderInfoLog.xml\">http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderInfoLog.xml

I have a packed vertex buffer containing postion coordinates aswell as color values for a vertex in the format {X, Y, Z, R, G, B, A}.

I am able to display the rectangle properly with a hardcoded color when I alter the fragment shader by taking out the a_Color attribute and hard coding a vec4 value for gl_FragColor but I am not able to pass the color vec4 attribute into the fragment shader (the rectangle won't display in that scenario).

What is the correct way to use glVertexAttribPointer(...) and glDrawElements(...) to draw from a packed vertex buffer in OpenGL ES 2.0?

See my code below:

public class GameRenderer implements Renderer {
    public static final int POS_SZ = 3;
    public static final int COL_SZ = 4;
    public static final int FLOAT_SZ = 4;
    public static final int SHORT_SZ = 2;

    private FloatBuffer gridVB;
    private ShortBuffer gridIndices;
    int programCode, paPositionHandle, paColorHandle, puMVPMatrixHandle;

    private final String vertexShaderCode =
        "uniform mat4 u_MVPMatrix;  \n" +
        "attribute vec4 a_Position; \n" +
        "void main(){               \n" +
        " gl_Position = u_MVPMatrix * a_Position;   \n" +
        "} \n";

    private String fragmentShaderCode = 
        "precision mediump float;   \n" +
        "attribute vec4 a_Color; \n" +
        "void main(){               \n" +
        " gl_FragColor = a_Color;   \n" +
        "}                          \n";

    public void staticGrid() {
        float vertexArray[] = {
            -0.75f, 0.75f, 0.0f,        // position
            0.0f, 0.0f, 1.0f, 1.0f,     // colour
            0.75f, 0.75f, 0.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            0.75f, -0.75f, 0.0f,
            0.0f, 0.0f, 1.0f, 1.0f,
            -0.75f, -0.75f, 0.0f,
            0.0f, 0.0f, 1.0f, 1.0f
        };

        short indicesArray[] = {
            0, 1, 2, 0, 2, 3
        };

        ByteBuffer vbb = ByteBuffer.allocateDirect(vertexArray.length * FLOAT_SZ);
        vbb.order(ByteOrder.nativeOrder());
        gridVB = vbb.asFloatBuffer();
        gridVB.put(vertexArray);
        gridVB.position(0);

        ByteBuffer ibb = ByteBuffer.allocateDirect(indicesArray.length * SHORT_SZ);
        ibb.order(ByteOrder.nativeOrder());
        gridIndices = ibb.asShortBuffer();
        gridIndices.put(indicesArray);
        gridIndices.position(0);
    }

    public void onSurfaceCreated(GL10 unused, EGLConfig arg1) {
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        staticGrid();
        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
        programCode = GLES20.glCreateProgram();
        GLES20.glAttachShader(programCode, vertexShader);
        GLES20.glAttachShader(programCode, fragmentShader);
        GLES20.glLinkProgram(programCode);

        paPositionHandle = GLES20.glGetAttribLocation(programCode, "a_Position");
        paColorHandle = GLES20.glGetAttribLocation(programCode, "a_Color");
        puMVPMatrixHandle = GLES20.glGetUniformLocation(programCode, "u_MVPMatrix");
    }

    public void onDrawFrame(GL10 unused) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        GLES20.glUseProgram(programCode);

        int stride = (POS_SZ + COL_SZ) * FLOAT_SZ;
        int indices_cnt = 6;

        gridVB.position(0);
        GLES20.glEnableVertexAttribArray(paPositionHandle);
        GLES20.glVertexAttribPointer(paPositionHandle, POS_SZ, GLES20.GL_FLOAT, false, stride, gridVB);

        gridVB.position(POS_SZ);
        GLES20.glEnableVertexAttribArray(paColorHandle);
        GLES20.glVertexAttribPointer(paColorHandle, COL_SZ, GLES20.GL_FLOAT, false, stride, gridVB);

        // matrix manipulation ...

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices_cnt, GLES20.GL_UNSIGNED_SHORT, gridIndices);
    }
}

解决方案

Fragment shaders don't use attributes. Attributes are per-vertex values, which a fragment shader wouldn't know anything about. What you want to do is to take the color as an attribute to the vertex shader, and then use a varying to pass the color to the fragment shader.

Also please start using error checking for your shaders, it will tell you when you make mistakes like this:

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramiv.xml (check for GL_LINK_STATUS)

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderiv.xml (check for GL_COMPILE_STATUS)

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetProgramInfoLog.xml

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGetShaderInfoLog.xml

这篇关于使用glVertexAttribPointer和glDrawElements从包装的顶点缓冲区绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆