OpenGL VBO - неверный массив массивов? - PullRequest
0 голосов
/ 30 января 2012

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

Прежде всего: У меня есть несколько объектов в моей сцене, которые используют VBO для рендеринга. Ничего другого, никаких других четырехугольников, полиров и т. Д., Только те, что на скриншотах, которые будут следовать.

Код моего поколения VBO очень прост и, надеюсь, понятен и понятен:

Генерация VBO

public boolean buffer() {
    FloatBuffer[] vertexBuffer = new FloatBuffer[1];
    vertexBuffer[0] = FloatBufferFactory.create(this.triangles.size() * 3 * 11);

    for (Triangle triangle : this.triangles) {
        for (int i = 0; i < 3; i++) {
            vertexBuffer[0].put(triangle.vertex[i].position.x);
            vertexBuffer[0].put(triangle.vertex[i].position.y);
            vertexBuffer[0].put(triangle.vertex[i].position.z);

            vertexBuffer[0].put(triangle.vertex[i].normal.x);
            vertexBuffer[0].put(triangle.vertex[i].normal.y);
            vertexBuffer[0].put(triangle.vertex[i].normal.z);

            vertexBuffer[0].put(triangle.vertex[i].color.r);
            vertexBuffer[0].put(triangle.vertex[i].color.g);
            vertexBuffer[0].put(triangle.vertex[i].color.b);

            vertexBuffer[0].put(triangle.vertex[i].uvset.x);
            vertexBuffer[0].put(triangle.vertex[i].uvset.y);
        }
    }

    vertexBuffer[0].position(0);

    GLES20.glGenBuffers(1, this.buffer, 0);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.buffer[0]);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer[0].capacity() * 4, vertexBuffer[0], GLES20.GL_STATIC_DRAW);

    return true;
}

Это очень просто: моя собственная функция в FloatBufferFactory создает Floatbuffer с количеством треугольников * 3 * 11 * 4 байта. Затем я помещаю в него данные для каждой вершины треугольника.

Моя логика: 12 байтов (3 * 4 байта) для одной вершинной позиции, 12 байтов для одной нормальной позиции, 12 байтов для Vertexcolordata и 8 байтов для UV-координат.

Rendering

Когда я рендерил сетку, я использую следующую функцию так же просто, как и другую:

public void render() {
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.buffer[0]);

    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0]);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 12);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 24);
    GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 36);        

    this.passMaterialUniforms();
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, this.triangles.size() * 3);
}

Теперь моя логика, как я ее понял: Все данные в байтах для одной вершины: 12Bytes (позиция) + 12Bytes (нормальный) + 12Bytes (цвет) + 8Bytes (uv) -> делает вывод: 44 байта для каждой вершины, поэтому следующая вершина должна быть после 44 байтов. -> Stride: 44 байта для каждых данных.

Следующая идея состояла в том, чтобы установить начальное смещение: 0Bytes для позиции, 12Bytes для нормальной, 24Bytes для цветной и 36Bytes для uv. Пока все хорошо.

Основная проблема

Теперь, кажется, что-то очень, очень странное в программе. После создания более 3 объектов или около того объекты, созданные после первых трех, отображаются неправильно.

Вот скриншоты: Первый пример и попробуйте (сгенерировано: 5 торов подряд): As you can see, in the first picture the 4. and 5. Torus ( Tori?!) are distorted and look like beans or lenses, or something like that.

Вторая попытка (генерируется 2 сферы, 1 торус, другая сфера, еще один торус): the 3. Sphere ( 4. generated object) looks quite normal, when you just look at the positions, but the texture-coordinates are very strange.

Как вы можете видеть, на первом рисунке 4. и 5. Торус (Тори ?!) искажены и выглядят как бобы или линзы, или что-то в этом роде. На втором рисунке 3. Сфера (4. сгенерированный объект) выглядит вполне нормально, когда вы просто смотрите на позиции, но координаты текстуры очень странные.

Так почему это? Как я могу решить эту проблему?

Спасибо! :)

1 Ответ

2 голосов
/ 30 января 2012

Я думаю, это связано с тем, как вы включили указатель атрибута.

Вы написали это:

GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0]);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 12);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 24);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, this.buffer[0] + 36);

Это должно быть так:

GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeVertex, 3, GLES20.GL_FLOAT, false, 44, 0);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeNormal, 3, GLES20.GL_FLOAT, false, 44, 12);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeColor, 3, GLES20.GL_FLOAT, false, 44, 24);
GLES20.glVertexAttribPointer(BaseActivity.activeShader.attributeUV, 2, GLES20.GL_FLOAT, false, 44, 36);

В любом случае я предлагаю определить некоторые константы для расчетов смещения.

В моем C-движке все основано на функции sizeof

...