当前位置: 首页 > 知识库问答 >
问题:

使用OpenGLES 2在android(java)中渲染3D对象时缺少一些部分

沙岳
2023-03-14

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

这是真实的物体。

这是我的代码(附加:我在MaxST即时跟踪器中使用这个)

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类来自此处)

这是我的画法

@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);
}

共有1个答案

姜弘化
2023-03-14

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

调整对象加载器。例如:

java prettyprint-override">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;
                }
        // [...]
    }
}
 类似资料:
  • This experimental class provides a fast code path for rendering meshes with frequently updated geometry data. When the renderer encounters an instance of ImmediateRenderObject, it only takes care abou

  • 问题内容: 我试图通过对象属性(此示例的名称)并在函数的轻松循环中列出它们。我发现这样做有些尴尬,但这似乎不正确。 这是我得到的: 有一个更好的方法吗?我只需要一个循环即可遍历对象数组,列出所需的属性并创建许多html节点之一。 问题答案: 您可以简单地在数组上 映射

  • 问题内容: 我有这样的代码,可以在没有定义路线的情况下渲染玉器模板。可以把它想成express.static,但是它用URL调用res.render。 问题在于res.render()不会引发错误。而是呈现错误页面。有没有办法检测丢失的模板或任何渲染错误? 问题答案: 一个更好的方法是使用render的callback ,而不是需要另一个回调,而是:

  • CSS3DRenderer用于通过CSS3的transform属性, 将层级的3D变换应用到DOM元素上。 如果你希望不借助基于canvas的渲染来在你的网站上应用3D变换,那么这一渲染器十分有趣。 同时,它也可以将DOM元素与WebGL的内容相结合。 然而,这一渲染器也有一些十分重要的限制: 它不可能使用three.js中的材质系统。 同时也不可能使用几何体。因此,CSS3DRenderer仅仅

  • 问题内容: 我有一些记录。单击每条记录后,需要在手风琴中显示信息。 该信息应该从数据库动态获取。 到目前为止,我所做的是 创建局部视图。那是为了显示详细信息。 在记录上单击后,我调用jquery方法并在控制器上执行我的方法。控制器以Json的形式返回对象(或任何其他东西,打开以获取任何建议)。 现在,JQuery方法具有该(模型)对象,但是如何使用它来呈现其局部视图。 问题答案: 我有一些记录。单

  • 问题内容: 如何使用jquery渲染局部视图? 我们可以这样渲染部分视图: 我们如何使用jquery做同样的事情? 问题答案: 我已经使用ajax加载来做到这一点: