2013-07-26 78 views
0

我正在使用SFML,OpenGL和VC++編譯器。當我渲染某些東西時,它只會在第二次運行時正確彈出(?)。這裏是我的代碼:OpenGL僅適用於第二幀

void Renderer::initializeOpenGL() { 
    glEnable(GL_DEPTH_TEST); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glOrtho(0, 1024, 0, 576, 0, 1024); 
} 

void Renderer::drawWorld(World* world) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glColor3f(1.F, 1.F, 1.F); 
    std::vector<int> vertices; 
    for(unsigned int x = 0; x < world->width; x++) { 
     bool left = false, right = false; 
     if(x == 0) 
      left = true; 
     else if(x == world->width -1) 
      right = true; 
     for(unsigned int z = 0; z < world->depth; z++) { 
      bool front = false, back = false; 
      if(z == 0) 
       front = true; 
      else if(z == world->depth -1) 
       back = true; 
      for(unsigned int y = 0; y < world->height; y++) { 
       if(!world->blocks[x][z][y]) 
        continue; 
       if(left == true || !world->blocks[x-1][z][y]) { 
        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 

        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 

        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 
       } 
       if(right == true || !world->blocks[x+1][z][y]) { 
        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 
       } 

       if(front == true || !world->blocks[x][z-1][y]) { 
        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 

        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 

        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 
       } 
       if(back == true || !world->blocks[x][z+1][y]) { 
        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 

        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 
       } 

       if(y == 0 || !world->blocks[x][z][y-1]) { 
        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 

        vertices.push_back(x); 
        vertices.push_back(y); 
        vertices.push_back(z+1); 
       } 
       if(y == world->height -1 || !world->blocks[x][z][y+1]) { 
        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z); 

        vertices.push_back(x+1); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 

        vertices.push_back(x); 
        vertices.push_back(y+1); 
        vertices.push_back(z+1); 
       } 
      } 
     } 
    } 

    glVertexPointer(3, GL_INT, 0, &vertices[0]); 
    glDrawArrays(GL_QUADS, 0, vertices.size() /3); 
    std::cout << "Vertices: " << vertices.size() << std::endl; 
} 

這裏是我的結果:
drawWorld的第一個呼叫:http://i.imgur.com/yMchEG9.png
drawWorld的第二個呼叫:http://i.imgur.com/d9swgao.png

顯然initializeOpenGL只被調用1時,第一個呼叫之前。在所提供的代碼之外沒有OpenGL語句。

回答

0

更新:

顯然,通過我的答案的評論討論我的做法是錯誤的。用戶derhass在評論中指出什麼是正確的。從derhass引用:

編號GL是一個狀態機。這些國家在不使用時如何設置 並不重要。對於頂點數組狀態,所有重要的是 繪製調用。您必須確保您需要的所有陣列都已啓用 ,並且您不需要的所有內容都在繪圖調用時被禁用。其實,避免不必要的狀態改變是一種好的做法。

我的錯誤的假設,而導致此更新:

void Renderer::initializeOpenGL() { 
    glEnable(GL_DEPTH_TEST); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glOrtho(0, 1024, 0, 576, 0, 1024); 
} 

glEnableClientState並沒有真正像這樣工作。 您需要在繪製調用之前啓用客戶端狀態並在其後禁用它。

所以我看你在你的繪製電話後失蹤glDisableClientState(GL_VERTEX_ARRAY);。 也從您的initializeOpenGL()函數中刪除glEnableClientState(GL_VERTEX_ARRAY);,並將其放入您的drawWorld函數(編輯:在vertexpointer調用之前)。

這可能導致您的問題。

+1

一次啓用該頂點數組並絕不禁用它絕對沒有錯。 – derhass

+0

如果這是真的,那肯定是很好的知道,但我想它應該用這種方式來說'好的做法',對吧? – Bisder

+3

No. GL是一個狀態機。這些國家在不使用時如何設置並不重要。對於頂點數組狀態,所有重要的事情都是繪製調用。您必須確保所有需要的數組都已啓用,並且在繪圖調用時禁用所有不需要的數組。實際上,避免不必要的狀態改變是一種很好的做法。你在這裏建議的是一個基於一些教程/例子的貨物崇拜編程的典型例子。 – derhass

相關問題