Проблема рендеринга сетки из файла OBJ - PullRequest
0 голосов
/ 01 августа 2011

У меня проблема с адаптацией или, я думаю, понимание вершин / индексов / граней в файле OBJ. Я хочу в конечном итоге проанализировать файл OBJ программно, но сначала мне нужно понять, как это сделать вручную. Я использую адаптацию примера из GLWallpaperService (предоставленную разработчиком в Интернете), чтобы сделать это.

Проблема, с которой я сталкиваюсь, заключается в том, что, похоже, он отлично работает с предоставленным им кодом, чтобы создать общий куб с разноцветными гранями, который он должен был реализовать и нарисовать по отдельности. Мой скорректированный код ниже пытается нарисовать только базовый куб из координат, которые я экспортировал из blender и добавил значения.

public class GLCube {
private final int _nrOfVertices = 8;

private FloatBuffer _vertexBuffer;
private FloatBuffer _normalBuffer;
private ShortBuffer _indiceBuffer;

public GLCube() {
    this.init();
}

private void init() {
    // 3 is the number of coordinates to each vertex.
    _vertexBuffer = BufferFactory.createFloatBuffer(_nrOfVertices * 3);
    _normalBuffer = BufferFactory.createFloatBuffer(18);
    _indiceBuffer = BufferFactory.createShortBuffer(72);

    // Coordinates for the vertexes of the cube.
    float[] vertexCoords = {
            /*
            1f,  1f,  0f,
            0f,  1f,  0f, 
            0f,  0f,  0f, 
            1f,  0f,  0f, 
            1f,  0f, -1f, 
            1f,  1f, -1f, 
            0f,  1f, -1f, 
            0f,  0f, -1f,
            */
            2.195671f, -0.176713f, -1.292541f,
            2.195671f, -0.176713f,  0.707459f,
            0.195671f, -0.176713f,  0.707459f,
            0.195672f, -0.176713f, -1.292542f,
            2.195672f,  1.823287f, -1.292541f,
            2.195671f,  1.823287f,  0.707460f,
            0.195671f,  1.823287f,  0.707459f,
            0.195671f,  1.823287f, -1.292541f
    };

    short[] indicesArray = {/*
            0, 1, 2,   0, 2, 3,
            3, 4, 0,   4, 5, 0,
            7, 2, 6,   6, 2, 1,
            4, 7, 5,   7, 6, 5,
            1, 0, 6,   6, 0, 5,
            2, 7, 3,   7, 4, 3
            */
            1,1,2, 1,3,1,
            1,1,3, 1,4,1,
            5,2,8, 2,7,2,
            5,2,7, 2,6,2,
            1,3,5, 3,6,3,
            1,3,6, 3,2,3,
            2,4,6, 4,7,4,
            2,4,7, 4,3,4,
            3,5,7, 5,8,5,
            3,5,8, 5,4,5,
            5,6,1, 6,4,6,
            5,6,4, 6,8,6
            };

    //Coordinates for Normal Vector. Used for Lighting calculations
    float[] normalCoords = {/*
             0f, 0f, 1f,   0f, 0f, 1f,   
             0f, 0f, 1f,   0f, 0f, 1f,   
             0f, 0f, 1f,   0f, 0f, 1f,   
             1f, 0f, 0f,   1f, 0f, 0f,   
             1f, 0f, 0f,   1f, 0f, 0f,   
             1f, 0f, 0f,   1f, 0f, 0f,   
            -1f, 0f, 0f,  -1f, 0f, 0f,  
            -1f, 0f, 0f,  -1f, 0f, 0f,  
            -1f, 0f, 0f,  -1f, 0f, 0f,  
             0f, 0f,-1f,   0f, 0f,-1f,   
             0f, 0f,-1f,   0f, 0f,-1f,   
             0f, 0f,-1f,   0f, 0f,-1f,   
             0f, 1f, 0f,   0f, 1f, 0f,   
             0f, 1f, 0f,   0f, 1f, 0f,   
             0f, 1f, 0f,   0f, 1f, 0f,  
             0f,-1f, 0f,   0f,-1f, 0f,   
             0f,-1f, 0f,   0f,-1f, 0f,   
             0f,-1f, 0f,   0f,-1f, 0f   
             */
             0f, -1f,  0f,
             0f,  1f,  0f,
             1f, -0f,  0f,
            -0f, -0f,  1f,
            -1f, -0f, -0f,
             0f,  0f, -1f
    };

    _vertexBuffer.put(vertexCoords);
    _normalBuffer.put(normalCoords);
    _indiceBuffer.put(indicesArray);

    _indiceBuffer.position(0);
    _vertexBuffer.position(0);
    _normalBuffer.position(0);

}

public void draw(GL10 gl) {
    // 3 coordinates in each vertex
    // 0 is the space between each vertex. They are densely packed in the array, so the value is 0
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);

    // 0 is the space between each vertex. They are densely packed in the array, so the value is 0
    gl.glNormalPointer(GL10.GL_FLOAT, 0, _normalBuffer);

    gl.glColor4f(1.0f, 0f, 0f, 1f);     //Red
    gl.glDrawElements(GL10.GL_TRIANGLES, 72, GL10.GL_UNSIGNED_SHORT, _indiceBuffer);
}
}

Это файл Obj, и, возможно, я просто не помещаю значения в правильные массивы, но я пытался выяснить это некоторое время и, честно говоря, просто не имею никакого опыта работы с OpenGL, так что это мой первый Проект пытается работать с ним.

# Blender v2.58 (sub 1) OBJ File: ''
# www.blender.org
v 2.195671 -0.176713 -1.292541
v 2.195671 -0.176713 0.707459
v 0.195671 -0.176713 0.707459
v 0.195672 -0.176713 -1.292542
v 2.195672 1.823287 -1.292541
v 2.195671 1.823287 0.707460
v 0.195671 1.823287 0.707459
v 0.195671 1.823287 -1.292541
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 -0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl (null)
s off
f 1//1 2//1 3//1
f 1//1 3//1 4//1
f 5//2 8//2 7//2
f 5//2 7//2 6//2
f 1//3 5//3 6//3
f 1//3 6//3 2//3
f 2//4 6//4 7//4
f 2//4 7//4 3//4
f 3//5 7//5 8//5
f 3//5 8//5 4//5
f 5//6 1//6 4//6
f 5//6 4//6 8//6

Любая помощь с этим была бы очень признательна. Я оставил свои комментарии в комментариях, чтобы вы могли видеть, что работает. Изображение, которое я вижу на экране, представляет собой полностью искаженный набор треугольников, и кажется, что оно пытается создать мой куб, но просто не доходит до него.

Ответ, содержащий изменения, был бы потрясающим. - =)

1 Ответ

5 голосов
/ 01 августа 2011

Я думаю, вы неправильно интерпретируете формат .obj. Посмотрите на этот документ .

В основном индексы для ваших лиц в vertexCoords должны быть первыми целыми числами. Каждое лицо определяется индексами в таком формате:

f v1/t1/n1 v2/t2/n2 v3/t3/n3

Где v - это индексы вершин, t - это индексы координат текстуры, а n - нормальные индексы.

То есть для этой линии (которая определяет одно лицо / треугольник)

f 1//1 2//1 3//1

индексы вершин будут 1,2,3, а нормальные индексы 1,1,1. У вас нет текстурных координат, поэтому там нет индексов и, следовательно, двойной косой черты.

Имейте в виду, что индексы для вершин, составляющих грань, и индексы связанных нормалей различны. Таким образом, вам придется создать два набора индексов. (См. Мое редактирование ниже о glDrawElements, хотя)

Другая незначительная деталь - помнить, что файлы .obj начинают считать с индексами в 1 , хотя это может быть (вероятно, является) 0-м значением в вашем массиве. Таким образом, вам придется учитывать это (т.е. вычесть 1 из всех значений индекса).

Edit: Глядя на ваш код, я вижу, что вы используете glDrawElements. Из того, что я знаю (но поправьте меня, если я ошибаюсь), это не позволяет вам иметь несколько (разных) наборов индексов для вершин, текстовых координат и нормалей. Таким образом, вам придется изменить ваши обычные данные, чтобы они соответствовали тем же индексам, что и для ваших вершин.

...