4

Code::Blocks (C++) と MinGW を使用して、Windows 上の OpenGL でゲームを作成しています。すべての描画とロジックは問題なく、ゲームは完璧に機能します。突然、そうでなくなるまで。ランダムな時間が経過すると、ゲームはセグメンテーション違反になります。GL segfault でよくあることですが、スタック トレースは役に立ちません。私が得た唯一のことは、ベンダーの OpenGL の実装で segfault が発生したことでした。さまざまなベンダーの複数のグラフィックス カードでこれをテストしましたが、それらはすべてこれを行うため、問題は私の側にあります。

gDEBugger を使用してプログラムを実行したところ、同じ役に立たないスタック トレースが表示されました。笑。GLIntercept も使用しましたが、何も飛び出しませんでした。そこで、セグメンテーション違反を手動で見つけることに着手し (BuGLe はコンパイルを拒否します...)、基本的にトレース メッセージをログに書き込みます。glDrawArrays への 1 回の呼び出しに絞り込みました。私はインターネットをたくさん調べて、見つけた多くの修正を試みました。

このゲームは移植性を考慮してコーディングされていないため、wine と valgrind で実行することをためらっています。その素晴らしい混乱をいじる前に、私のコードを見てエラーを見つけていただければ幸いです。(確かにそれは明らかなことだと思います...)

(注: 読みやすくするために、すべてのトレース行を削除しました)

void PlayerShip::Render()
{
    glPushMatrix(); //Save the current state

    glTranslatef(m_PosX, m_PosY, 0);
    glRotatef(vect.Rotation - 90, 0, 0, 1); //Matrixes are applied in reverse order


    double xl = m_SizeX / 2, yl = m_SizeY / 2; //Get values to add/subract to the midpoint for the corners
    glEnable(GL_TEXTURE_2D); //Redundant
    TextureManager::Inst()->BindTexture(TexIDs::Playership01); //Bind the texture

    glEnableClientState(GL_VERTEX_ARRAY); //These enables and disables are redundant here
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    GLdouble* Verts;
    Verts = new GLdouble[12] { -xl, -yl, -.5,    xl, -yl, -.5,
                           xl,  yl, -.5,    -xl, yl, -.5}; //Calculate quad vertices
    GLdouble* Texs;
    Texs = new GLdouble[8] {0, 0,    1, 0,   1, 1,    0, 1}; //Calculate texture vertices

    glVertexPointer(3, GL_DOUBLE, 0, Verts);
    glTexCoordPointer(2, GL_DOUBLE, 0, Texs);

    glDrawArrays(GL_QUADS, 0, 12);

    delete [] Verts;
    delete [] Texs;

    glPopMatrix();
}

興味深いのは、このコードが機能することです...しばらくの間。すべての変数の値を出力しました。それらはすべて正しく、ポインターは null ではありません。コード全体に間隔を置いて配置された glGetError 呼び出しは、常に NO_ERROR を返します。率直に言って、私は途方に暮れています。

何か違うことを提案する人へのメモ: レガシー (1.4) GL 実装をサポートするために頂点配列を使用する必要があり、(将来) 複数のプリミティブを描画するためにそれらを再利用できるように、配列をポインターとして宣言しています。一度に(たとえば、排気ガスを船から出す)

4

1 に答える 1

6

glDrawArrays の最後の引数は、12 (float の数) ではなく、4 (要素の数) にする必要があります。

12 個の要素 (= 36 個の浮動小数点数) を描画しようとしており、配列の境界を越えてアクセスしています。

于 2012-05-18T02:03:35.837 に答える