1

OpenGL 3.2 の使用方法を学び始めたばかりで、現在、ジオメトリ データをロードするためのユーティリティをまとめようとしています。頂点にロードするためのコードを見ると、すべてが正しいように見え、入れたデバッグ出力でも正しい値が得られているようです。コードは、各点が完全な r、g、または b を取得する単一の三角形を生成する必要がありますが、代わりにほぼ純粋な赤/オレンジになっています。

ジオメトリ データを含むコードは次のとおりです。

    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

これは、それぞれ 4 つの浮動小数点値を持つ 3 つの頂点のセットが 2 つ見つかったことを意味します。そのうちの 1 つは配列オフセット 0 から始まり、もう 1 つは配列オフセット 12 から始まります。これは、送信される配列に対応します: x、y、z、w 値を持つ 3 つの頂点と、r、g、b を持つ 3 つの頂点、値。出力から、機能しているように見えますが、そうではありません。これを理解するための助けをいただければ幸いです。

4

1 に答える 1

1

lwjgl には詳しくありませんがglVertexAttribPointer、C API の OpenGL 関数の最後の引数はデータのバイト オフセットです。代わりに配列インデックスを渡しているようです。これは、12 番目のバイト (3 つの float の後) で始まるデータが次のようになるため、赤/オレンジ色の三角形が表示される理由を説明できます。

        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

ブレンド設定がゼロ アルファ コンポーネントを無視するようなものであると仮定すると、オレンジ、赤、黄色の頂点が得られます。

于 2013-03-07T22:53:01.903 に答える