5

私はglDrawArraysを呼び出すOpenGLレンダリングコードを持っています。これは、OpenGLコンテキストが(自動的に/暗黙的に取得される)4.2の場合は問題なく機能しますが、明示的に要求されたOpenGLコアコンテキスト3.2では一貫して失敗します(GL_INVALID_OPERATION)。(どちらの場合も、シェーダーは常に#version 150に設定されていますが、それはここでのポイントの脇にあると思います。)

仕様によると、glDrawArrays()がGL_INVALID_OPERATIONで失敗する場合は2つだけです。

  • 「ゼロ以外のバッファオブジェクト名が有効な配列にバインドされていて、バッファオブジェクトのデータストアが現在マッピングされている場合」-この時点ではバッファマッピングを行っていません

  • 「ジオメトリシェーダーがアクティブで、モードが[...]と互換性がない場合」-いいえ、現時点ではジオメトリシェーダーはありません。

さらに:

  1. glDrawArrays()呼び出しだけが失敗することを確認して再確認しました。また、glDrawArrays()に渡されるすべての引数が、両方のGLバージョン、バッファーバインディングでも同一であることを再確認しました。

  2. これは、3つの異なるnvidia GPUと2つの異なるOSで発生します(Win7とOSX、どちらも64ビット-もちろん、OSXには3.2コンテキストしかなく、4.2はありません)。

  3. 統合された「IntelHD」GPUでは発生しませんが、その場合は、自動の暗黙的な3.3コンテキストしか取得しません(ここでGLFWを介してこのGPUで3.2コアプロファイルを明示的に強制しようとすると、ウィンドウの作成に失敗しますが、これはまったく別の問題です...)

価値のあるものとして、Golangのレンダリングループから抜粋した関連ルーチンを次に示します。

func (me *TMesh) render () {
    curMesh = me
    curTechnique.OnRenderMesh()
    gl.BindBuffer(gl.ARRAY_BUFFER, me.glVertBuf)
    if me.glElemBuf > 0 {
        gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, me.glElemBuf)
        gl.VertexAttribPointer(curProg.AttrLocs["aPos"], 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
        gl.DrawElements(me.glMode, me.glNumIndices, gl.UNSIGNED_INT, gl.Pointer(nil))
        gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
    } else {
        gl.VertexAttribPointer(curProg.AttrLocs["aPos"], 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
        /* BOOM! */
        gl.DrawArrays(me.glMode, 0, me.glNumVerts)
    }
    gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}

したがって、もちろんこれはより大きなレンダリングループの一部ですが、現時点での「* TMesh」構造全体は、単純な立方体と単純なピラミッドの2つのインスタンスにすぎません。重要なのは、描画ループ全体が問題なく動作し、GLが3.3と4.2の両方でエラーを照会されたときにエラーが報告されないことですが、明示的な3.2コアプロファイルを持つ3つのnvidia GPUでは、仕様に従ってのみ呼び出されるエラーコードで失敗します2つの特定の状況がありますが、私が知る限り、ここでは当てはまりません。

ここで何が間違っている可能性がありますか?これに遭遇したことがありますか?私が見逃しているアイデアはありますか?

4

2 に答える 2

1

私は大げさな推測をしています。

私が理解しているように、すべてのOpenGL呼び出しは同じスレッドで発生する必要があります。同じゴルーチンが実行のさまざまな時点でさまざまなスレッドで実行される可能性があるため、この制限はゴルーチンとうまく混ざりません。

この問題を回避するには、OpenGLを初期化する前に、メインのゴルーチン(またはOpenGL呼び出しを実行しているゴルーチン)を現在のスレッドにロックする必要があります。

import "runtime"

func main() {
    runtime.LockOSThread()

    ...
}

一貫性のない結果が表示される理由は、実装の違いによって説明できます。

于 2012-10-24T20:33:49.697 に答える
1

DrawArraysだけ ではありません。ここで間違っていました。どういうわけか、glVertexAttribPointerを呼び出す私の方法がここで問題です。厳密なコア プロファイルでは、3.2 か 4.2 かに関係なく、さらに調査します4.2 の non-strict コンテキストでは問題ありません。

于 2012-10-25T04:57:24.620 に答える