Некоторые детали отсутствуют при рендеринге 3D-объекта в android (java) с использованием OpenGLES 2 - PullRequest
1 голос
/ 30 марта 2020

Я новичок в 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 от здесь )

Здесь мой метод рисования

@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 Ответ

1 голос
/ 30 марта 2020

Файл модели состоит из четырех квадратов. Если грани четырехугольные, вам нужно сгенерировать 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;
                }
        // [...]
    }
}
...