Android glDrainElements()仅绘制前两个面

Android glDrainElements()仅绘制前两个面,android,opengl-es,opengl-es-2.0,google-cardboard,Android,Opengl Es,Opengl Es 2.0,Google Cardboard,已解决。问题解决方案:attribStride未正确设置 我正在编写一个小的谷歌纸板应用程序,它可以加载和渲染任何Wavefront.obj文件,并在链接的.mtl文件中显示其表面的材质属性。对于渲染,我使用VBO和IBO。对于表面和闪电的材质属性,我使用phong着色 我的问题是,glpaurements()只渲染立方体的前两个三角形,立方体由12个三角形组成 构成立方体的所有三角形都是逆时针设置的 通过解析.obj文件生成的顶点数组和索引数组数据是有效的 VBO的客户端FloatBuffe

已解决。问题解决方案:
attribStride
未正确设置

我正在编写一个小的谷歌纸板应用程序,它可以加载和渲染任何Wavefront.obj文件,并在链接的.mtl文件中显示其表面的材质属性。对于渲染,我使用VBO和IBO。对于表面和闪电的材质属性,我使用phong着色

我的问题是,
glpaurements()
只渲染立方体的前两个三角形,立方体由12个三角形组成

  • 构成立方体的所有三角形都是逆时针设置的
  • 通过解析.obj文件生成的顶点数组和索引数组数据是有效的
  • VBO的客户端FloatBuffer和IBO的客户端ShortBuffer的数据和长度有效
  • glBufferData()
    设置的VBO和IBO的长度有效
  • 着色器已正确编译和附着
  • 通过
    glGetAttriblLocation()
    glGetUniformLocation()
    为着色器设置的所有属性和统一位置均有效
我已经在调试器和logcat中检查了这些点。 我意识到它有很多代码。但我在任何地方都找不到问题或问题的答案。所以请帮助我:D,首先谢谢你:)

此方法设置VBO、IBO、着色器程序、着色器程序位置、纹理和着色器程序统一值:

private void initializeGL() {
    Log.i(TAG, "initializeGL()");

    // Set camera matrix.
    Matrix.setLookAtM(camera, OFFSET, EYE_POINT_X, EYE_POINT_Y, EYE_POINT_Z, CENTER_OF_VIEW_X, CENTER_OF_VIEW_Y, CENTER_OF_VIEW_Z, UP_VECTOR_X, UP_VECTOR_Y, UP_VECTOR_Z);

    // Initialize shader program.
    shaderProgram.init();
    shaderProgramHandle = shaderProgram.getProgramHandle();

    // Initialize object information.
    objectInformation.init();

    vboHandle = objectInformation.getVbo().getVboHandle();
    vboLength = objectInformation.getVbo().getVboLength();

    iboHandle = objectInformation.getIbo().getIboHandle();
    iboLength = objectInformation.getIbo().getIboLength();

    uniforms = objectInformation.getUniformArray();
    numOfUniforms = objectInformation.getNumOfUniforms();
    Log.i(TAG, "initializeGL(): Number of uniforms = " + numOfUniforms);

    textures = objectInformation.getTextureArray();
    numOfTextures = objectInformation.getNumOfTextures();
    Log.i(TAG, "initializeGL(): Number of textures = " + numOfTextures);

    // Get vertex shader uniform locations.
    modelViewProjectionParam = GLES20.glGetUniformLocation(shaderProgramHandle, "u_ModelViewProjection");
    Log.i(TAG, "initializeGL(): modelViewProjectionParam = " + modelViewProjectionParam);

    modelViewParam = GLES20.glGetUniformLocation(shaderProgramHandle, "u_ModelView");
    Log.i(TAG, "initializeGL(): modelViewParam = " + modelViewParam);

    normalMatrixParam = GLES20.glGetUniformLocation(shaderProgramHandle, "u_NormalMatrix");
    Log.i(TAG, "initializeGL(): normalMatrixParam = " + normalMatrixParam);

    // Get vertex shader attribute locations.
    positionParam = GLES20.glGetAttribLocation(shaderProgramHandle, "a_Position");
    Log.i(TAG, "initializeGL(): positionParam = " + positionParam);
    if(boolTexCoords) {
        attribStride += 4 * BYTES_PER_FLOAT;
        texCoordParam = GLES20.glGetAttribLocation(shaderProgramHandle, "a_TexCoord");
        Log.i(TAG, "initializeGL(): texCoordParam = " + texCoordParam);
    }
    normalParam = GLES20.glGetAttribLocation(shaderProgramHandle, "a_Normal");
    Log.i(TAG, "initializeGL(): normalParam = " + normalParam);

    // Get fragment shader phong uniform locations.
    if(boolPhongLightning) {
        lightPosParam = GLES20.glGetUniformLocation(shaderProgramHandle, "lightPosition");
        Log.i(TAG, "initializeGL(): lightPosParam = " + lightPosParam);
        IaParam = GLES20.glGetUniformLocation(shaderProgramHandle, "Ia");
        Log.i(TAG, "initializeGL(): IaParam = " + IaParam);
        IpParam = GLES20.glGetUniformLocation(shaderProgramHandle, "Ip");
        Log.i(TAG, "initializeGL(): IpParam = " + IpParam);
    }

    // Set fragment shader material uniforms.
    GLES20.glUseProgram(shaderProgramHandle);

    for(int i = 0; i < numOfUniforms; i++) {
        String unifName = uniforms[i].getUnifName();
        location = GLES20.glGetUniformLocation(shaderProgramHandle, unifName);
        checkGLError(TAG, "initializeGL(): " + unifName + " shader location");

        vec = uniforms[i].getArray();
        if(vec != null) {
            GLES20.glUniform3fv(location, 1, vec, 0);
            Log.i(TAG, "initializeGL(): " + unifName + "_Param = " + location);
        } else {
            float value = uniforms[i].getValue();
            GLES20.glUniform1f(location, value);
            Log.i(TAG, "initializeGL(): " + unifName + "_Param = " + location);
        }
    }

    // Set fragment shader phong uniforms.
    if(boolPhongLightning) {
        GLES20.glUniform3fv(IaParam, 1, Ia, 0);
        GLES20.glUniform3fv(IpParam, 1, Ip, 0);
    }

    // Set fragment shader textures.
    for(int i = 0; i < numOfTextures; i++) {
        // Set active texture unit.
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);

        // Bind texture to active texture unit.
        int texHandle = textures[i].getTextureHandle();
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texHandle);

        // Assign texture unit to uniform in fragment shader.
        String unifName = textures[i].getUnifName();
        location = GLES20.glGetUniformLocation(shaderProgramHandle, unifName);

        GLES20.glUniform1i(location, i);
        checkGLError(TAG, "initializeGL(): glUniform1i()");
        Log.i(TAG, "initializeGL(): " + unifName + "Param = " + location);
    }

    GLES20.glUseProgram(0);

    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glDepthFunc(GLES20.GL_LESS);

    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glFrontFace(GLES20.GL_CCW);
    GLES20.glCullFace(GLES20.GL_BACK);

    GLES20.glClearColor(0.3f, 0.3f, 0.3f, 0.1f);
}
私人作废提款():

编辑: 类RPVBO和RPIBO。有趣的部分是init()方法:

公共最终类RPVBO{
私有静态最终字符串TAG=“RPVBO”;
私有静态最终整数字节/FLOAT=4;
私有int[]VBO句柄;
私有向量顶点;
专用的国际标准长度;
公共RPVBO(){
Log.i(标记“Constructor()”);
vboHandles=null;
顶点=新向量();
vboLength=0;
}
公共void init(){
Log.i(标记“init()”);
如果((vboHandles!=null)和&(vboHandles[0]!=0)){
返回;
}
vboHandles=新整数[1];
GLES20.glGenBuffers(1,vboHandles,0);
如果(vboHandles[0]!=0){
float[]vertexArray=getVertexArray();
FloatBuffer clientSideBuffer=ByteBuffer.allocateDirect(vertexArray.length*字节/浮点数).order(ByteOrder.nativeOrder()).asFloatBuffer();
clientSideBuffer.position(0);
clientSideBuffer.put(vertexArray);
clientSideBuffer.position(0);
if(clientSideBuffer.capacity()!=vertexArray.length){
e(标记“init():创建客户端浮动缓冲区时出错”);
抛出新的RuntimeException(“错误:“+TAG+”init():创建客户端浮动缓冲区时出错”);
}
GLES20.glBindBuffer(GLES20.GL_数组_BUFFER,vboHandles[0]);
GLES20.glBufferData(GLES20.GL_数组_BUFFER,clientSideBuffer.capacity()*字节/u浮点,clientSideBuffer,GLES20.GL_静态_DRAW);
checkleror(标记,“init():glBufferData()”;
int[]参数=新的int[2];
GLES20.glGetBufferParameteriv(GLES20.GL_数组_BUFFER,GLES20.GL_BUFFER_SIZE,params,0);
checkelError(标记,“init():glGetBufferParameteriv()”;
GLES20.glGetBufferParameteriv(GLES20.GL_数组_BUFFER,GLES20.GL_BUFFER_用法,参数,1);
checkelError(标记,“init():glGetBufferParameteriv()”;
GLES20.glBindBuffer(GLES20.GL_数组_BUFFER,0);
if(参数[0]!=(clientSideBuffer.capacity()*字节/浮点数)){
e(标记“init():设置OpenGL VBO数据时出错”);
抛出新的运行时异常(“错误:“+TAG+”:init():设置OpenGL VBO数据时出错”);
}
i(标记“init():OpenGL VBO句柄:”+vboHandles[0]);
Log.i(标记“init():OpenGL VBO大小(字节):+params[0]);
开关(参数[1]){
案例GLES20.GL_流_图:
i(标记“init():OpenGL VBO用法:GL_STREAM_DRAW”);
打破
案例20.GL\U静态\U绘图:
i(标记“init():OpenGL VBO用法:GL_STATIC_DRAW”);
打破
案例20.GL\u动态\u绘图:
i(标记,“init():OpenGL VBO用法:GL_DYNAMIC_DRAW”);
}
顶点。清除();
}
if(vboHandles[0]==0){
e(标记“init():在OpenGL中创建VBO时出错”);
抛出新的RuntimeException(“错误:“+TAG+”init():在OpenGL中创建VBO时出错”);
}
}
公共无效附加值(最终浮动值){
顶点。添加(值);
++vboLength;
}
公共无效附加值(最终浮动值){
顶点。添加(值);
++vboLength;
}
公共void addArray(最终浮点[]数组){
最终整数数组长度=array.length;
对于(int i=0;i

公共最终类RPIBO{
私有静态最终字符串TAG=“RPIBO”;
私有静态最终整型字节\u每\u短=
@Override
public void onDrawEye(Eye eye) {
    Log.i(TAG, "onDrawEye()");

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    projection = eye.getPerspective(Z_NEAR, Z_FAR);
    Matrix.multiplyMM(view, 0, eye.getEyeView(), 0, camera, 0);
    Matrix.multiplyMM(modelView, 0, view, 0, modelMatrix, 0);
    Matrix.multiplyMM(modelViewProjection, 0, projection, 0, modelView, 0);
    Matrix.multiplyMV(lightPosInEyeSpace, 0, view, 0, lightPosInWorldSpace, 0);
    normalMatrix = RPMath.getNormalMatrix3x3(modelView);

    draw();
}
private void draw() {
    Log.i(TAG, "draw()");

    // Bind shader program, VBO and IBO.
    GLES20.glUseProgram(shaderProgramHandle);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboHandle);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, iboHandle);

    // Set vertex shader uniforms.
    GLES20.glUniformMatrix4fv(modelViewProjectionParam, 1, false, modelViewProjection, 0);
    GLES20.glUniformMatrix4fv(modelViewParam, 1, false, modelView, 0);
    GLES20.glUniformMatrix3fv(normalMatrixParam, 1, false, normalMatrix, 0);
    if(boolPhongLightning) { // fragment shader uniforms.
        vec = new float[3];
        vec[0] = lightPosInEyeSpace[0];
        vec[1] = lightPosInEyeSpace[1];
        vec[2] = lightPosInEyeSpace[2];
        GLES20.glUniform3fv(lightPosParam, 1, vec, 0);
    }

    // Set vertex attribute pointers.
    attribOffset = 0;
    GLES20.glVertexAttribPointer(positionParam, 4, GLES20.GL_FLOAT, false, attribStride, attribOffset);
    if(boolTexCoords) {
        attribOffset += 4 * BYTES_PER_FLOAT;
        GLES20.glVertexAttribPointer(texCoordParam, 4, GLES20.GL_FLOAT, false, attribStride, attribOffset);
    }
    attribOffset += 4 * BYTES_PER_FLOAT;
    GLES20.glVertexAttribPointer(normalParam, 4, GLES20.GL_FLOAT, false, attribStride, attribOffset);

    // Enable vertex attribute arrays.
    GLES20.glEnableVertexAttribArray(positionParam);
    if(boolTexCoords) {
        GLES20.glEnableVertexAttribArray(texCoordParam);
    }
    GLES20.glEnableVertexAttribArray(normalParam);

    // Draw.
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, iboLength, GLES20.GL_UNSIGNED_SHORT, 0);

    // Disable vertex attribute arrays.
    GLES20.glDisableVertexAttribArray(positionParam);
    if(boolTexCoords) {
        GLES20.glDisableVertexAttribArray(texCoordParam);
    }
    GLES20.glDisableVertexAttribArray(normalParam);

    // Unbind shader program, VBO and IBO.
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
    GLES20.glUseProgram(0);
}
public final class RPVBO {

    private static final String TAG = "RPVBO";
    private static final int BYTES_PER_FLOAT = 4;

    private int[] vboHandles;
    private Vector<Float> vertices;
    private int vboLength;


    public RPVBO() {
        Log.i(TAG, "Constructor()");
        vboHandles = null;
        vertices = new Vector();
        vboLength = 0;
    }


    public void init() {
        Log.i(TAG, "init()");

        if((vboHandles != null) && (vboHandles[0] != 0)) {
            return;
        }

        vboHandles = new int[1];
        GLES20.glGenBuffers(1, vboHandles, 0);

        if(vboHandles[0] != 0) {
            float[] vertexArray = getVertexArray();

            FloatBuffer clientSideBuffer = ByteBuffer.allocateDirect(vertexArray.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
            clientSideBuffer.position(0);
            clientSideBuffer.put(vertexArray);
            clientSideBuffer.position(0);

            if(clientSideBuffer.capacity() != vertexArray.length) {
                Log.e(TAG, "init(): Error creating client side Floatbuffer.");
                throw new RuntimeException("Error: " + TAG + "init(): Error creating client side Floatbuffer.");
            }

            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboHandles[0]);

            GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, clientSideBuffer.capacity() * BYTES_PER_FLOAT, clientSideBuffer, GLES20.GL_STATIC_DRAW);
            MainActivity.checkGLError(TAG, "init(): glBufferData()");

            int[] params = new int[2];
            GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, params, 0);
            MainActivity.checkGLError(TAG, "init(): glGetBufferParameteriv()");
            GLES20.glGetBufferParameteriv(GLES20.GL_ARRAY_BUFFER, GLES20.GL_BUFFER_USAGE, params, 1);
            MainActivity.checkGLError(TAG, "init(): glGetBufferParameteriv()");

            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

            if(params[0] != (clientSideBuffer.capacity() * BYTES_PER_FLOAT)) {
                Log.e(TAG, "init(): Error setting OpenGL VBO data.");
                throw new RuntimeException("Error: " + TAG + ": init(): Error setting OpenGL VBO data.");
            }

            Log.i(TAG, "init(): OpenGL VBO handle: " + vboHandles[0]);
            Log.i(TAG, "init(): OpenGL VBO size in Bytes: " + params[0]);
            switch(params[1]) {
                case GLES20.GL_STREAM_DRAW:
                    Log.i(TAG, "init(): OpenGL VBO usage: GL_STREAM_DRAW.");
                    break;

                case GLES20.GL_STATIC_DRAW:
                    Log.i(TAG, "init(): OpenGL VBO usage: GL_STATIC_DRAW.");
                    break;

                case GLES20.GL_DYNAMIC_DRAW:
                    Log.i(TAG, "init(): OpenGL VBO usage: GL_DYNAMIC_DRAW.");
            }

            vertices.clear();
        }

        if(vboHandles[0] == 0) {
            Log.e(TAG, "init(): Error creating VBO in OpenGL.");
            throw new RuntimeException("Error: " + TAG + "init(): Error creating VBO in OpenGL.");
        }
    }


    public void addValue(final float value) {
        vertices.add(value);
        ++vboLength;
    }

    public void addValue(final Float value) {
        vertices.add(value);
        ++vboLength;
    }


    public void addArray(final float[] array) {
        final int arrayLength = array.length;
        for(int i = 0; i < arrayLength; i++) {
            vertices.add(array[i]);
            ++vboLength;
        }
    }

    public void addArray(final Float[] array) {
        final int arrayLength = array.length;
        for(int i = 0; i < arrayLength; i++) {
            vertices.add(array[i]);
            ++vboLength;
        }
    }


    public int getVboHandle() {
        if(vboHandles == null) {
            return 0;
        }
        return vboHandles[0];
    }
    @Nullable
    public float[] getVertexArray() {
        float[] array = new float[vertices.size()];
        for(int i = 0; i < vertices.size(); i++) {
            array[i] = vertices.get(i);
        }
        return array;
    }

    public int getVboLength() {
        return vboLength;
    }
}
public final class RPIBO {

    private static final String TAG = "RPIBO";
    private static final int BYTES_PER_SHORT = 2;

    private int[] iboHandles;
    private Vector<Short> indices;
    private int iboLength;


    public RPIBO() {
        Log.i(TAG, "Constructor()");
        iboHandles = null;
        indices = new Vector();
        iboLength = 0;
    }


    public void init() {
        Log.i(TAG, "init()");

        if((iboHandles != null) && (iboHandles[0] != 0)) {
            return;
        }

        iboHandles = new int[1];
        GLES20.glGenBuffers(1, iboHandles, 0);

        if(iboHandles[0] != 0) {
            short[] indexArray = getIndexArray();

            ShortBuffer clientSideBuffer = ByteBuffer.allocateDirect(indexArray.length * BYTES_PER_SHORT).order(ByteOrder.nativeOrder()).asShortBuffer();
            clientSideBuffer.position(0);
            clientSideBuffer.put(indexArray);
            clientSideBuffer.position(0);

            if(clientSideBuffer.capacity() != indexArray.length) {
                Log.e(TAG, "init(): Error creating client side Shortbuffer.");
                throw new RuntimeException("Error: " + TAG + "init(): Error creating client side Shortbuffer.");
            }

            GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, iboHandles[0]);

            GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, clientSideBuffer.capacity() * BYTES_PER_SHORT, clientSideBuffer, GLES20.GL_STATIC_DRAW);
            MainActivity.checkGLError(TAG, "init(): glBufferData()");

            int[] params = new int[2];
            GLES20.glGetBufferParameteriv(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20.GL_BUFFER_SIZE, params, 0);
            MainActivity.checkGLError(TAG, "init(): glGetBufferParameteriv()");
            GLES20.glGetBufferParameteriv(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20.GL_BUFFER_USAGE, params, 1);
            MainActivity.checkGLError(TAG, "init(): glGetBufferParameteriv()");

            GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

            if(params[0] != (clientSideBuffer.capacity() * BYTES_PER_SHORT)) {
                Log.e(TAG, "init(): Error setting OpenGL IBO data.");
                throw new RuntimeException("Error: " + TAG + ": init(): Error setting OpenGL IBO data.");
            }

            Log.i(TAG, "init(): OpenGL IBO handle: " + iboHandles[0]);
            Log.i(TAG, "init(): OpenGL IBO size in Bytes: " + params[0]);
            switch(params[1]) {
                case GLES20.GL_STREAM_DRAW:
                    Log.i(TAG, "init(): OpenGL IBO usage: GL_STREAM_DRAW.");
                    break;

                case GLES20.GL_STATIC_DRAW:
                    Log.i(TAG, "init(): OpenGL IBO usage: GL_STATIC_DRAW.");
                    break;

                case GLES20.GL_DYNAMIC_DRAW:
                    Log.i(TAG, "init(): OpenGL IBO usage: GL_DYNAMIC_DRAW.");
            }

            indices.clear();
        }

        if(iboHandles[0] == 0) {
            Log.e(TAG, "init(): Error creating IBO in OpenGL.");
            throw new RuntimeException("Error: " + TAG + "init(): Error creating IBO in OpenGL.");
        }
    }


    public void addValue(final short value) {
        indices.add(value);
        ++iboLength;
    }

    public void addValue(final Short value) {
        indices.add(value);
        ++iboLength;
    }


    public void addArray(final short[] array) {
        final int arrayLength = array.length;
        for(int i = 0; i < arrayLength; i++) {
            indices.add(array[i]);
            ++iboLength;
        }
    }

    public void addArray(final Short[] array) {
        final int arrayLength = array.length;
        for(int i = 0; i < arrayLength; i++) {
            indices.add(array[i]);
            ++iboLength;
        }
    }


    public int getIboHandle() {
        if(iboHandles == null) {
            return 0;
        }
        return iboHandles[0];
    }
    @Nullable
    public short[] getIndexArray() {
        short[] array = new short[indices.size()];
        for(int i = 0; i < indices.size(); i++) {
            array[i] = indices.get(i);
        }
        return array;
    }

    public int getIboLength() {
        return iboLength;
    }
}
vx, vy, vz, 1.0,  s, t, 0.0, 1.0,  nx, ny, nz, 1.0