2013-07-10 114 views
2

我正在嘗試顯示一個小三角形。Opengl將不會顯示任何內容

這裏是我的初始化代碼:

void PlayerInit(Player P1) 
{ 
    glewExperimental = GL_TRUE; 
    glewInit(); 

    //initialize buffers needed to draw the player 
    GLuint vao; 
    GLuint buffer; 
    glGenVertexArrays(1, &vao); 
    glGenBuffers(1, &buffer); 

    //bind the buffer and vertex objects 
    glBindVertexArray(vao); 
    glBindBuffer(GL_ARRAY_BUFFER, buffer); 

    //Set up a buffer to hold 6 floats for position, and 9 floats for color 
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*18, NULL, GL_STATIC_DRAW); 

    //push the vertices of the player into the buffer 
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*9, CalcPlayerPoints(P1.GetPosition())); 

    //push the color of each player vertex into the buffer 
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(float)*9, sizeof(float)*9, CalcPlayerColor(1)); 

    //create and compile the vertex/fragment shader objects 
    GLuint vs = create_shader("vshader.glsl" ,GL_VERTEX_SHADER); 
    GLuint fs = create_shader("fshader.glsl" ,GL_FRAGMENT_SHADER); 

    //create a program object and link the shaders 
    GLuint program = glCreateProgram(); 
    glAttachShader(program, vs); 
    glAttachShader(program, fs); 

    glLinkProgram(program); 

    //error checking for linking 
    GLint linked; 
    glGetProgramiv(program, GL_LINK_STATUS, &linked); 
    if(!linked) 
    { 
     std::cerr<< "Shader program failed to link" <<std::endl; 
     GLint logSize; 
     glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); 
     char* logMsg = new char[logSize]; 
     glGetProgramInfoLog(program, logSize, NULL, logMsg); 
     std::cerr<< logMsg << std::endl; 
     delete [] logMsg; 
     exit(EXIT_FAILURE); 
    } 
    glUseProgram(program); 

    //create attributes for color and position to pass to shaders 
    //enable each attribute 
    GLuint Pos = glGetAttribLocation(program, "vPosition"); 
    glEnableVertexAttribArray(Pos); 

    GLuint Col = glGetAttribLocation(program, "vColor"); 
    glEnableVertexAttribArray(Col); 

    //set a pointer at the proper offset into the buffer for each attribute 
    glVertexAttribPointer(Pos, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*0)); 
    glVertexAttribPointer(Col, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) (sizeof(float)*9)); 
} 

我沒有太多的經驗,編寫着色器接頭,所以我認爲這是哪裏出了問題可能是。我在着色器加載器中檢查了一些錯誤,沒有出現。所以我認爲這很好。

接下來我有我的顯示和主要功能:

//display function for the game 
void GameDisplay(void) 
{ 
    //set the background color 
    glClearColor(1.0, 0.0, 1.0, 1.0); 

    //clear the screen 
    glClear(GL_COLOR_BUFFER_BIT); 

    //Draw the Player 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glutSwapBuffers(); 
} 

//main function 
int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); 
    glutInitWindowSize(500, 500); 
    glutCreateWindow("Asteroids"); 

    Player P1 = Player(0.0, 0.0); 
    PlayerInit(P1); 
    glutDisplayFunc(GameDisplay); 

    glutMainLoop(); 
    return 0; 
} 

頂點着色器:

attribute vec3 vPosition; 
attribute vec3 vColor; 
varying vec4 color; 

void main() 
{ 
    color = vec4(vColor, 1.0); 
    gl_Position = vec4(vPosition, 1.0); 
} 

片段着色器

varying vec4 color; 

void main() 
{ 
    gl_FragColor = color; 
} 

這是所有相關的代碼。 CalcPlayerPoints只是返回一個大小爲9的float數組來保存三角座標。 CalcPlayerColor做類似的事情。

可能有助於診斷問題的最後一個問題是,無論何時嘗試通過關閉應用程序的窗口退出程序,我都會在glutmainloop中得到一個斷點,但是如果關閉控制檯窗口,它會退出正常。

編輯:我添加了着色器以供參考。 編輯:我使用的OpenGL 3.1版

+2

你的着色器在哪裏?這些有點重要:) – genpfault

+0

你使用的是什麼GLSL版本?我沒有看到任何#version指令。 – Grimmy

+0

你確定你的'Pos'和'Col'實際上是否包含有效位置?我不相信舊的「屬性」類型可以在這裏工作。指定您的GL和GLSL版本IS再次非常重要! – Grimmy

回答

2

沒有着色器,我們不能說,如果故障代碼不GLSL(壞頂點變換等) 您是否嘗試過檢查glGetError,看看問題是否沒有按來自你的初始化代碼?

也許嘗試將片段着色器的輸出設置爲vec4(1.0, 0.0, 0.0, 1.0),以檢查其正常輸出是否格式不正確。

你的最後一個問題似乎揭示了一個未定義的行爲,如錯誤的內存分配/釋放,這可能發生在你的Player類中(通過考慮在初始化代碼中將對象作爲參考傳遞的方式,因爲它可能在瞬間觸發一個淺拷貝,然後是一個雙指針)。

+0

感謝您的回覆rems4e。我爲這個問題添加了着色器。我只是試着在init代碼的末尾調用glGetError。它返回0,表示沒有錯誤。代碼運行並編譯得很好,它只是不顯示。我也編輯了片段着色器到純色的vec4。沒有區別。最後,我改變了init代碼以獲取指向Player的指針而不是副本。沒有變化,但我會保持這種變化,因爲這似乎是更好的做法。感謝您的建議。 – user2569107

+0

您的着色器看起來正確。但是glGetError()返回0的事實並不意味着你的代碼中沒有發生錯誤!在每次GL調用後,它的返回值都會重置爲0,並且您必須在每次調用後檢查值,以確保它們中的非GL值包含GL狀態。 – rems4e

+0

好吧,我會這樣做的。謝謝你的澄清。我會評論結果。 – user2569107

0

結果是我從函數中返回頂點數組來計算它們時出錯了。修復後,其餘的代碼工作正常。