7

編集: rotoglup は私のコードで問題を発見し、削除したシェーダーを追加すると解決策が完成しました。正しいコード (シェーダーを使用) については、以下の私の回答を参照してください。

こんにちは、みんな !

このチュートリアルから最新の OpenGL の基本を学ぼうとしています。

ただし、C++ の代わりに python/pyglet で実行したいと思います。私は、pyglet が低レベルの OpenGL の多くを抽象化できることを知っています。ただし、抽象化のレイヤーの背後にそれらを隠すことに進む前に、いくつかの基本を理解したいと思います。

私の問題は非常に単純です。以下のコードは、私が期待している 3 つのポイントではなく、1 つのポイントしか描画しません。私のコードは、私が知る限り、チュートリアルの C++ と同じですが、頂点シェーダーとフラグメント シェーダー ( Python のgletoolsを介して行われる) の削除を除いて、私の問題に違いはないようです。

物事を一点に単純化すると、私が理解できない動作が示され (最初の座標だけが何かに影響を与えるように見えます)、pyglet、OpenGL、または一般的に3Dでさえ:p

関連するコードは次のとおりです。

import pyglet
from pyglet.gl import *

window = pyglet.window.Window()

positionBufferObject = GLuint()
vao = GLuint()

vertexPositions = [0.0, 0.0, 0.0,
                   0.25, 0.0, 0.0,
                   1.75, 1.75, 0.0]

vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)

@window.event
def on_draw():
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
    glDrawArrays(GL_POINTS, 0, 3)
    glDisableVertexAttribArray(0)

glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)

glClearColor(0.0, 0.0, 0.0, 0.0)
pyglet.app.run()
4

2 に答える 2

5

私はついにこれを正しく理解しました!

頂点、glDrawArrays、および glVertexAttribPointer をいじると、単一のドットが表示されることがあるという事実に惑わされていたようです。これは偶然のようです。rotoglup の回答によって提供される修正では、何も描画されません。これは、元の質問のコードの「正しい」動作です。

誰にも役立つ場合に備えて、私の過ちの目録:

  • w 座標を 1 ではなく 0 に設定すると、チュートリアルのクリップ空間変換の説明が完全に欠落します。

  • glBufferData に、バイトを予期するときに頂点のバッファーのサイズを指定します。

  • 頂点シェーダーとフラグメント シェーダーを削除します (上記の 2 つの問題を探しながらコードを単純化するため)。これにより、何もレンダリングされないことが保証されました...(バグのある?)私が時々得ていた単一のドットを除いて。

記録のために、以下のコードは、パススルーシェーダーを使用して単一の三角形を表示します。これは、最新で正しい OpenGL であることを願っています。要件は pyglet と gletools です。

import pyglet
from pyglet.gl import *
from gletools import ShaderProgram, FragmentShader, VertexShader

window = pyglet.window.Window()

positionBufferObject = GLuint()

vertexPositions = [0.75, 0.75, 0.0, 1.0,
                   0.75, -0.75, 0.0, 1.0,
                   -0.75, -0.75, 0.0, 1.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)

program = ShaderProgram(
    FragmentShader('''
    #version 330
    out vec4 outputColor;
    void main()
    {
       outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    }'''),
    VertexShader('''
    #version 330
    layout(location = 0) in vec4 position;
    void main()
    {
        gl_Position = position;
    }''')
)

@window.event
def on_draw():
    with program:
        glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
        glDrawArrays(GL_TRIANGLES, 0, 3)
        glDisableVertexAttribArray(0)

glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)

pyglet.app.run()
于 2011-01-07T11:07:32.563 に答える
5
glDrawArrays(GL_POINTS, 0, 1)

あなたのチュートリアルでは、 1 は​​ 3 です:

glDrawArrays(GL_POINTS, 0, 3)

また、頂点の 4 番目 (w) のコンポーネントは 0 ではなく 1 でなければならないことに注意してください。

  vertexPositions = [0.0, 0.0, 0.0, 1.0,
                     0.25, 0.0, 0.0, 1.0,
                     1.75, 1.75, 0.0, 1.0]

または、w コンポーネントを削除することもできます。

  vertexPositions = [0.0, 0.0, 0.0,
                     0.25, 0.0, 0.0,
                     1.75, 1.75, 0.0]

次の呼び出しを に変更します。

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)

もう 1 つ、私は pyglet の専門家ではありませんが、glBufferData は、C の対応するものと同様に、要素ではなくバイト単位でサイズを取得する可能性があります。各フロートは 4 バイトなので、次のように試すことができます。

glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
于 2011-01-06T19:30:03.020 に答える