2012-03-05 3 views
1

何が価値がある場合:OpenGL 2.0ベースのシェーダ処理コードが:: glBegin()でクラッシュする原因は何ですか?

  • 私のグラフィックスドライバ(のATI Mobility Radeonの4570)最新です。
  • 私はシェイダーハンドリングコードに基づいたARB拡張機能を以前は同じ設定で動作させることができました(シェーダーに戻るまでにはしばらく時間がかかりましたが)。
  • 私のセットアップでLighthouse3dのチュートリアルに従っていました(ゆるやかに:Lighthouse3d shader setupシェイダーのログコードがSOの質問からリッピングされていました。クレジットが足りなくて申し訳ありませんが、今は見つからないようです)

基本的に、すべてのOpenGL操作が正常に実行されたようです。シェーダがコンパイルされ、プログラムがリンクします。以下に示すように、gl ***呼び出しのたびにOpenGLエラーをチェックしてしまいました。シェイダー自体は自明です。

また、もちろん、私は何かばかげて簡単に見落としたかもしれません。

#define GLOP(operation) operation; if(!GFX::CheckError(#operation)) exit(1) 
// GFX::CheckError() prints an error message, if any. 

    GFX::Init(640, 480, 24, 0); 
    GLOP(Texture2D::Enable()); 

    // shader setup 
    GLuint hFrag = GLOP(::glCreateShader(GL_FRAGMENT_SHADER)); 
    GLuint hVert = GLOP(::glCreateShader(GL_VERTEX_SHADER)); 
    GLuint hProg = GLOP(::glCreateProgram()); 

    std::ifstream inFile; 
    ReadOpen("shader.frag", inFile); 
    std::string str(ReadFile(inFile)); 
    const char* pSource = str.c_str(); 
    GLOP(::glShaderSource(hFrag, 1, &pSource, 0)); 
    GLOP(::glCompileShader(hFrag)); 

    GLint logLength; 
    glGetShaderiv(hFrag, GL_INFO_LOG_LENGTH, &logLength); 
    if (logLength > 0) { 
     GLchar* log = (GLchar*)malloc(logLength); 
     glGetShaderInfoLog(hFrag, logLength, &logLength, log); 
     printf("Shader compile log:\n%s\n", log); 
     free(log); 
    } 

    XR::ReadOpen(core.GetPath() + "shader.vert", inFile); 
    XRLOG(XR::GetFileSize(inFile) << " bytes in file." << std::endl); 
    str = XR::ReadFile(inFile); 
    pSource = str.c_str(); 
    GLOP(::glShaderSource(hVert, 1, &pSource, 0)); 
    GLOP(::glCompileShader(hVert)); 

    glGetShaderiv(hVert, GL_INFO_LOG_LENGTH, &logLength); 
    if (logLength > 0) { 
     GLchar* log = (GLchar*)malloc(logLength); 
     glGetShaderInfoLog(hVert, logLength, &logLength, log); 
     printf("Shader compile log:\n%s\n", log); 
     free(log); 
    } 

    GLOP(::glAttachShader(hProg, hFrag)); 
    GLOP(::glAttachShader(hProg, hVert)); 
    GLOP(::glLinkProgram(hProg)); 

    glGetProgramiv(hProg, GL_INFO_LOG_LENGTH, &logLength); 
    if (logLength > 0) { 
     GLchar* log = (GLchar*)malloc(logLength); 
     glGetProgramInfoLog(hProg, logLength, &logLength, log); 
     printf("Program link log:\n%s\n", log); 
     free(log); 
    } 

    GLOP(::glUseProgram(hProg)); 

    // get uniform's location 
    GLint locTex0 = GLOP(::glGetUniformLocation(hProg, "tex0")); 

    /// [loading image, creating texture goes here. works perfectly.] 

    while(core.IsRunning()) 
    { 
    GLOP(::glActiveTexture(GL_TEXTURE0)); 
    GLOP(pTex->Bind()); 
    GLOP(::glUniform1i(locTex0, GL_TEXTURE0)); 
    GLOP(::glPushMatrix()); 
    GLOP(::glTranslatef(GFX::GetFlopWidth()/2, GFX::GetHeight()/2, .0f)); // still no errors 
    ::glBegin(GL_TRIANGLE_FAN); // crash 
    ::glTexCoord2f(.0f, 1.0f); 
    ::glVertex2f(-100.0f, -100.0f); 
    ::glTexCoord2f(1.0f, 1.0f); 
    ::glVertex2f(100.0f, -100.0f); 
    ::glTexCoord2f(1.0f, .0f); 
    ::glVertex2f(100.0f, 100.0f); 
    ::glTexCoord2f(.0f, .0f); 
    ::glVertex2f(-100.0f, 100.0f); 
    ::glEnd(); 
    ::glPopMatrix(); 
    } 

頂点シェーダ:

void main(void) 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
} 

フラグメントシェーダ:

uniform sampler2D tex0; 

void main() 
{ 
    vec2 texCoords = gl_TexCoord[0].st; 
    vec3 pixel = texture2D(tex0, texCoords).xyz; 
    gl_FragColor = vec4(pixel, 1.0); 
} 

出力:

Successfully set video mode [email protected] 
Shader compile log: 
Fragment shader was successfully compiled to run on hardware. 

Shader compile log: 
Vertex shader was successfully compiled to run on hardware. 

Program link log: 
Vertex shader(s) linked, fragment shader(s) linked. 

答えて

3

それは最初のフレームにクラッシュしていますか?

これはあなたのクラッシュと何か関係がありますが、間違った順序でglVertex/glTexcoordを呼び出していることを知っておく必要があります。 glVertexは頂点を終了するので、最初のglVertexにはtexcoordが設定されておらず、最後のtexcoordが次のループに適用されます。

+0

はい、最初のフレームでクラッシュします。 glVertex2fとglTexCoord2fの間違った順序を指摘してくれてありがとう - それは急いでテクスチャ付き4連表現を書き出した製品です。私は今それを編集しました。この例のランタイムは、とにかくクラッシュする前にそこに到達することはありません。 – zyndor

0

このような頂点を送信するための即時モードは、コアプロファイルではサポートされていないため、OpenGLコンテキストを設定する際にコアプロファイルを指定しているのだろうかと思います。それはなぜglBeginで死ぬのかを説明します。

+0

ハードクラッシュする可能性は低いと思われます。また、彼は、数行前にglPushMatrixを呼び出していますが、どちらもコアではありません。 – Tim

+0

良い点。また、私は自分のセットアップでこれを試しました。コア・プロファイルを使用してコマンドを実行しても問題ありません。彼らはただ役に立ちません。だから私は今どこか他の場所で問題があると思っています。おそらく何らかのスタック破損が何か他の原因によって引き起こされていると思います。 – Robinson

関連する問題