VBO с чередованием с плавающей запятой и байтом - PullRequest
0 голосов
/ 21 мая 2019

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

/*
 * 20^3 blocks per chunk, 6 faces per block, 3 vertices per face
 * max. every second face can be visible
 */
private static final int MAX_FLOAT_AMOUNT = 20 * 20 * 20 * 6 * 3 / 2;

/*
 * 20^3 blocks per chunk, 6 faces per block, 2 bytes per face
 * max. every second face can be visible
 */
private static final int MAX_BYTE_AMOUNT = 20 * 20 * 20 * 6 * 2 / 2;

private int dataVboIndex;

protected int vaoId;
protected int indicesCount;

protected boolean isInitialized = false;


public static ByteBuffer dataFloatBuffer = BufferUtils.createByteBuffer(4 * MAX_FLOAT_AMOUNT + MAX_BYTE_AMOUNT);

DefaultChunkVao(int indiciesVboId) {
    init();
}

DefaultChunkVao(boolean initialize) {
    if(initialize) init();
}

private void init() {
    isInitialized = true;

    // bind vao
    vaoId = glGenVertexArrays();
    glBindVertexArray(vaoId);

    //create vbo
    dataVboIndex = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, dataVboIndex);

    dataFloatBuffer.clear();
    dataFloatBuffer.position(4 * MAX_FLOAT_AMOUNT + MAX_BYTE_AMOUNT);
    dataFloatBuffer.flip();

    // allocate memory
    glBufferData(GL_ARRAY_BUFFER, dataFloatBuffer, GL_STREAM_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4 + 2, 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 1, GL_UNSIGNED_BYTE, false, 3 * 4 + 2, 3 * 4);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 1, GL_UNSIGNED_BYTE, false, 3 * 4 + 2, 3 * 4 + 1);

    // unbind vao
    glBindVertexArray(0);
}

public void updateData(float[] data) {
    if(!isInitialized) init();

    dataFloatBuffer.clear();
    for(int counter = 0; counter < data.length; counter+=0) {
        dataFloatBuffer.putFloat(data[counter++]);
        dataFloatBuffer.putFloat(data[counter++]);
        dataFloatBuffer.putFloat(data[counter++]);

        dataFloatBuffer.put((byte) data[counter++]);
        dataFloatBuffer.put((byte) data[counter++]);
    }
    dataFloatBuffer.flip();

    glBindBuffer(GL_ARRAY_BUFFER, dataVboIndex);
    glBufferSubData(GL_ARRAY_BUFFER, 0, dataFloatBuffer);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    this.indicesCount = data.length / 5;
}

Константы MAX_FLOAT_AMOUNT и MAX_BYTE_AMOUNT содержатколичество поплавков соответственнобайт на VBO.Правильно ли я считаю, что мне нужно умножить количество поплавков на 4, когда я определяю емкость ByteBuffer, поскольку каждый поплавок имеет 4 байта?

И что я сделал не так, что я - мой байт?значения всегда равны 0 в шейдере?


EDIT : я смог воспроизвести проблему на более простом примере.Здесь я хочу сохранить позицию и два байта в VBO.В фрагментном шейдере я проверяю, правильно ли передано значение byte1.Если это так, шейдер отображает форму зеленым, в противном случае - синим.К сожалению, моя фигура отображается синим цветом, поэтому я предполагаю, что значение byte1 не передано правильно.

vertexShader

#version 400 core

in vec3 position;
in int byte1;
in int byte2;

flat out int p_byte1;
flat out int p_byte2;

void main(void) {

    gl_Position = vec4(position, 1);

    p_byte1 = byte1;
    p_byte2 = byte2;
}

фрагментShader :

#version 400 core

flat in int p_byte1;
flat in int p_byte2;

out vec3 out_color;

void main(void) {
    if(p_byte1 == 45) {
        out_color = vec3(0, 1, 0);
    } else out_color = vec3(0, 0, 1);

}

создание VAO:

vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
final int vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);

float[] data = {0, 0, 0, 20f, 20f, 1, 1, 1, 20f, 20f, 1, 0, 1, 20f, 20f, 0, 1, 1, 20f, 20f};
ByteBuffer dataBuffer = BufferUtils.createByteBuffer(4 * (3 * 4) + 1 * (2 * 4));
for(int counter = 0; counter < data.length; counter+=0) {
dataBuffer.putFloat(data[counter++]);
dataBuffer.putFloat(data[counter++]);
dataBuffer.putFloat(data[counter++]);

dataBuffer.put((byte) data[counter++]);
dataBuffer.put((byte) data[counter++]);
}
dataBuffer.flip();

glBufferData(GL_ARRAY_BUFFER, dataBuffer, GL_STREAM_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4 + 2, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_UNSIGNED_BYTE, false, 3 * 4 + 2, 3 * 4);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_UNSIGNED_BYTE, false, 3 * 4 + 2, 3 * 4 + 1);

glBindVertexArray(0);

1 Ответ

0 голосов
/ 23 мая 2019

Мне удалось найти решение моего вопроса. Необходимо использовать glVertexAttribIPointer вместо glVertexAttribPointer для целочисленных типов данных.

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4 + 2, 0);
glEnableVertexAttribArray(1);
glVertexAttribIPointer(1, 1, GL_UNSIGNED_BYTE, 3 * 4 + 2, 3 * 4);
glEnableVertexAttribArray(2);
glVertexAttribIPointer(2, 1, GL_UNSIGNED_BYTE, 3 * 4 + 2, 3 * 4 + 1);
...