【问题标题】:Some parts are missing when render 3D object in android(java) using OpenGLES 2使用 OpenGLES 2 在 android(java) 中渲染 3D 对象时缺少某些部分
【发布时间】:2020-03-30 15:32:21
【问题描述】:

我是 OpenGL 的新手,我正在尝试将 .obj 文件加载到我的 Android 应用程序中并使用 OpenGLES 2 显示它。对象被渲染。但是其中有一些空格,如下图所示。我该如何解决这个问题?

这是实际的对象。

这是我的代码(补充:我在 MaxST Instant tracker 中使用它)

objLoader = new ObjLoader(context, "andy.obj");

    numFaces = objLoader.numFaces;


    positions = ByteBuffer.allocateDirect(objLoader.positions.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    positions.put(objLoader.positions).position(0);

    normals = ByteBuffer.allocateDirect(objLoader.normals.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    normals.put(objLoader.normals).position(0);

    textureCoordinates = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    textureCoordinates.put(objLoader.textureCoordinates).position(0);

    ByteBuffer bb = ByteBuffer.allocateDirect(objLoader.positions.length * Float.SIZE / 8);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(positions);
    vertexBuffer.position(0);

    bb = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * Float.SIZE / 8);
    bb.order(ByteOrder.nativeOrder());
    textureCoordBuff = bb.asFloatBuffer();
    textureCoordBuff.put(textureCoordinates);
    textureCoordBuff.position(0);


    shaderProgramId = ShaderUtil.createProgram(VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC);

    positionHandle = GLES20.glGetAttribLocation(shaderProgramId, "a_position");
    textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramId, "a_texCoord");
    mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramId, "u_mvpMatrix");
    textureHandle = GLES20.glGetUniformLocation(shaderProgramId, "u_texture");

    textureNames = new int[1];

    GLES20.glGenTextures(1, textureNames, 0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureNames[0]);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

(ObjLoader 类来自here

这是我的绘制方法

@Override
public void draw() {
    GLES20.glUseProgram(shaderProgramId);

    GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false,
            0, vertexBuffer);
    GLES20.glEnableVertexAttribArray(positionHandle);
    GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false,
            0, textureCoordBuff);
    GLES20.glEnableVertexAttribArray(textureCoordHandle);

    Matrix.setIdentityM(modelMatrix, 0);
    Matrix.multiplyMM(modelMatrix, 0, translation, 0, rotation, 0);
    Matrix.multiplyMM(modelMatrix, 0, modelMatrix, 0, scale, 0);
    Matrix.multiplyMM(modelMatrix, 0, transform, 0, modelMatrix, 0);

    Matrix.multiplyMM(localMvpMatrix, 0, projectionMatrix, 0, modelMatrix, 0);
    GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, localMvpMatrix, 0);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glUniform1i(textureHandle, 0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureNames[0]);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, objLoader.positions.length / 3);

    GLES20.glDisableVertexAttribArray(positionHandle);
    GLES20.glDisableVertexAttribArray(textureCoordHandle);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
}

【问题讨论】:

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


    【解决方案1】:

    模型文件似乎由四边形组成。如果面是四边形,则必须为每个面生成 2 个三角形。

    调整对象加载器。例如:

    class ObjLoader {
        // [...]
    
        public ObjLoader(Context context, String file) {
            // [...]
    
                   switch (parts[0]) {
                       // [...]
    
                        case "f":
                            // faces: vertex/texture/normal
                            if (parts.length == 5) {
                                // triangle 1
                                faces.add(parts[1]);
                                faces.add(parts[2]);
                                faces.add(parts[3]);
                                // triangle 2
                                faces.add(parts[1]);
                                faces.add(parts[3]);
                                faces.add(parts[4]);
                            }
                            else {
                                faces.add(parts[1]);
                                faces.add(parts[2]);
                                faces.add(parts[3]);
                            }
                            break;
                    }
            // [...]
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-29
      • 2014-03-02
      • 1970-01-01
      • 2011-05-24
      • 2017-04-30
      • 1970-01-01
      • 2021-11-14
      • 2014-01-02
      相关资源
      最近更新 更多