2013-03-07 3 views
1

Я только начал изучать, как использовать OpenGL 3.2, и сейчас я пытаюсь собрать утилиту для загрузки данных геометрии. Когда я смотрю код для загрузки в вершинах, все выглядит правильно, и вывод отладки, который я вставляю, даже, кажется, дает мне правильные значения. Код должен создавать один треугольник с каждой точкой, получающей полный r, g или b, но вместо этого получая почти чистый красный/оранжевый.Шиндер OpenGL получает неверные данные, хотя кажется правильным

Вот код с данными геометрии:

final float[] vertexPositions3 = new float[] { 
      0.0f, 0.5f, 0.0f, 1.0f, 
      0.5f, -0.366f, 0.0f, 1.0f, 
      -0.5f, -0.366f, 0.0f, 1.0f, 
      1.0f, 0.0f, 0.0f, 1.0f, 
      0.0f, 1.0f, 0.0f, 1.0f, 
      0.0f, 0.0f, 1.0f, 1.0f, 
    }; 

    geometry = new Geometry(); 
    geometry.addBufferOffset(vertexPositions3, GL_STATIC_DRAW, 0, Geometry.VERTEX_4F, Geometry.VERTEX_4F); 

И код, который загружает его:

protected int getDataTypeSize(int dataType) { 
    if(dataType == VERTEX_1F) { 
     return 1; 
    } 
    else if(dataType == VERTEX_2F) { 
     return 2; 
    } 
    else if(dataType == VERTEX_3F) { 
     return 3; 
    } 
    else { 
     return 4; 
    } 
} 

public void addBufferOffset(float[] data, int usage, int vertexColumn, int... dataTypes) { 
    if(numAttributes + dataTypes.length >= MAX_VBO) { 
     throw new IllegalStateException("Can only have up to 16 attributes, requested: " + (numAttributes + dataTypes.length)); 
    } 

    int rowSize = 0; 
    for(int type : dataTypes) { 
     rowSize += getDataTypeSize(type); 
    } 
    if(numRows == 0) { 
     numRows = data.length/rowSize; 
    } 
    else if(numRows != (data.length/rowSize)) { 
     throw new IllegalStateException("Number of rows in buffers don't match: " + numRows + " vs " + (data.length/rowSize)); 
    } 

    if(numVertices == 0) { 
     numVertices = getDataTypeSize(dataTypes[0]) * (data.length/rowSize)/getDataTypeSize(dataTypes[0]); 
    } 
    else { 
     int addingVerts = getDataTypeSize(dataTypes[0]) * (data.length/rowSize); 
     if(addingVerts != numVertices) { 
      throw new IllegalStateException("Vertex count for buffers don't match: " + numVertices + " vs " + addingVerts); 
     } 
    } 
    glBindVertexArray(vao); 

    FloatBuffer buf = BufferUtils.createFloatBuffer(data.length); 
    buf.put(data); 
    buf.flip(); 
    int vbo = glGenBuffers(); 
    vbos[numBuffers++] = vbo; 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, buf, usage); 

    int startPos = 0; 
    for(int i = 0; i < dataTypes.length; i++) { 
     glEnableVertexAttribArray(numAttributes + i); 
     glVertexAttribPointer(numAttributes + i, getDataTypeSize(dataTypes[i]), GL_FLOAT, false, 0, startPos); 
     System.out.println((numAttributes + i) + ", " + getDataTypeSize(dataTypes[i]) + ", " + startPos); 
     startPos += numRows * getDataTypeSize(dataTypes[i]); 
    } 
    System.out.println("Num verts: " + numVertices); 
    if(usesIndices) { 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesRef); 
    } 
    numAttributes += dataTypes.length; 
    glBindVertexArray(0); 
} 

И вершинные шейдеры:

#version 330 

layout(location = 0) in vec4 position; 
layout(location = 1) in vec4 color; 

smooth out vec4 theColor; 
uniform float loopDuration; 
uniform float time; 
uniform vec4 camera; 

void main() { 
    float timeScale = 3.14159f * 2.0f/loopDuration; 
    vec4 totalOffset = vec4(
     cos(time * 1.5f * timeScale) * 0.5f, 
     sin(time * 1.5f * timeScale) * 0.5f, 
     0.0f, 
     0.0f); 
    gl_Position = position + totalOffset; 
    theColor = color; 
} 

И, наконец, фрагмент шейдер:

#version 330 

smooth in vec4 theColor; 

out vec4 outputColor; 

uniform float fragLoopDuration; 
uniform float time; 

const vec4 firstColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); 
const vec4 secondColor = vec4(0.0f, 1.0f, 0.0f, 1.0f); 

void main() { 
    float lerpTime = time * 1.5f/fragLoopDuration; 
    outputColor = theColor; 
} 

Когда я запускаю программу, метод addBufferOffset производит следующий вывод:

0, 4, 0 
1, 4, 12 
Num verts: 3 

означает, что он нашел два набора из трех вершин с четырьмя значениями с плавающей запятой в каждой. Один из них начинается с смещения массива 0, а другой начинается с смещения массива 12. Это соответствует массиву, который получает его: 3 вершины с значениями x, y, z, w и 3 вершины с r, g, b , значения. Из результата кажется, что он должен работать, но это не так. Я бы очень признателен за помощь в этом.

ответ

1

Я не знаком с lwjgl, но последний аргумент функции OpenGL glVertexAttribPointer в C API - это смещение байтов данных - кажется, что вы передаете вместо этого индекс массива. Это может объяснить, почему вы видите красный/оранжевый треугольник, так как данные, начиная с 12-го байта (после 3-х поплавков) выглядит следующим образом:

 1.0f, 0.5f, -0.366f, 0.0f, 
     1.0f, -0.5f, -0.366f, 0.0f, 
     1.0f, 1.0f, 0.0f, 0.0f 

Зажимные эти значения между 0 и 1 даст

 1.0f, 0.5f, 0.0f, 0.0f, 
     1.0f, 0.0f, 0.0f, 0.0f, 
     1.0f, 1.0f, 0.0f, 0.0f 

Предполагая, что ваши настройки смешивания таковы, что вы игнорируете нулевой альфа-компонент, они будут давать оранжевые, красные и желтые вершины.

+0

LWJGL имеет почти 1 к 1 перевод API C с незначительными изменениями (например, не требуется длина для FloatBuffer, поскольку длина сохраняется в объекте). Ошибка смещения байта была абсолютно правильной, спасибо вам много. Мне просто пришлось умножить индекс на 4, и все сработало. Я немного порвал свои волосы. – Freezerburn

Смежные вопросы