2011-12-10 132 views
2

我正在使用OpenGL/SDL編寫程序,但窗口不會繪製。該窗口的條目出現在任務欄和alt +選項卡菜單中,但不顯示縮略圖。當我點擊它時,它被標記爲活動,但屏幕上沒有任何變化。SDL沒有顯示的OpenGL窗口

我可以驗證glClear(GL_COLOR_BUFFER_BIT)SDL_GL_SwapBuffers()正在從我的渲染循環中調用,並且SDL_SetVideoMode成功,但它仍然不會呈現。這不是共享庫問題,因爲其他SDL/GL應用程序可以正常工作。

任何想法?

編輯:

這裏的顯卡初始化:

void GraphicsManager::initGraphics() { 
    // Access prefs 
    PreferencesManager* prefMgr = PreferencesManager::getInstance(); 
    int width = prefMgr->getIntKey("res_width"); 
    int height = prefMgr->getIntKey("res_height"); 

    if(SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { 
     fprintf(stderr, "Cannot initialize SDL video!\n"); 
     exit(1); 
    } 

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 

    m_screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL); 
    if(!m_screen) { 
     fprintf(stderr, "Error: Invalid screen pointer\n"); 
     exit(2); 
    } 

    SDL_ShowCursor(SDL_DISABLE); 

    // Setup OpenGL stuffs 
    glDisable(GL_DEPTH_TEST); // We're only using 2D 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glViewport(0.0, 0.0, width, height); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0.0, width, height, 0.0, -1.0f, 1.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glEnable(GL_TEXTURE_2D); 
    glClear(GL_COLOR_BUFFER_BIT); 
    SDL_GL_SwapBuffers(); 

    // Init FPS stuff 
    m_avgFps = 60.0f; 
    m_lastUpdate = SDL_GetTicks(); 
} 

這裏是我的主循環:

while(stateMgr->getState() != GS_QUIT) { 
    // Process input events 
    inputMgr->processEvents(); 

    // Update the current system mode 
    stateMgr->update(); 

    // Update GUI state 
    guiMgr->update(); 

    // Render 
    gfxMgr->render(); 
    //char buf[16]; 
    //snprintf(buf, 16, "FPS: %4.2f", gfxMgr->getFramerate()); 
    //testWindow->getChild("TestRoot/Framerate")->setText(buf); 
    SDL_Delay(10); 
} 

和這裏的渲染功能:

void GraphicsManager::render() { 
    std::list<IRenderCallback*>::iterator rci; 

    // Clear the screen 
    glClear(GL_COLOR_BUFFER_BIT); 

    // Run render callbacks 
    /*for(rci=m_renderCallbacks.begin();rci != m_renderCallbacks.end();rci++) { 
     (*rci)->preRender(); 
    } 

    // Iterate through all renderables and render them 
    std::list<Renderable*>::iterator i; 
    for(i=m_renderables.begin();i != m_renderables.end();i++) { 
     (*i)->render(); 
    } 

    // Run render callbacks 
    for(rci=m_renderCallbacks.begin();rci != m_renderCallbacks.end();rci++) { 
     (*rci)->preFlip(); 
    }*/ 

    // Flip the buffers 
    SDL_GL_SwapBuffers(); 

    // Update FPS stuff 
    Uint32 now = SDL_GetTicks(); 
    Uint32 timeTaken = now - m_lastUpdate; 
    m_lastUpdate = now; 
    double seconds = (double)timeTaken/1000.0f; 
    m_avgFps = (1.0f/seconds); 

    // Run render callbacks 
    for(rci=m_renderCallbacks.begin();rci != m_renderCallbacks.end();rci++) { 
     (*rci)->postRender(); 
    } 
} 
+3

特別是,您的窗口創建和主循環。 – Thomas

+0

好的,我添加了主循環,渲染代碼和渲染初始化 – computergeek6

回答

1

打破它。做到這一點應該工作(主要是-ISH)最簡單的事情:

#include <SDL.h> 
#include <SDL_opengl.h> 
#include <cstdio> 
#include <iostream> 

using namespace std; 

int main(int argc, char** argv) 
{ 
    if(SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { 
     fprintf(stderr, "Cannot initialize SDL video!\n"); 
     exit(1); 
    } 

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 

    int width = 640; 
    int height = 480; 

    SDL_Surface* m_screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL); 
    if(!m_screen) { 
     fprintf(stderr, "Error: Invalid screen pointer\n"); 
     exit(2); 
    } 

    cout << "GL_VERSION : " << glGetString(GL_VERSION) << endl; 
    cout << "GL_VENDOR : " << glGetString(GL_VENDOR) << endl; 
    cout << "GL_RENDERER : " << glGetString(GL_RENDERER) << endl; 

    SDL_ShowCursor(SDL_DISABLE); 

    // Setup OpenGL stuffs 
    glDisable(GL_DEPTH_TEST); // We're only using 2D 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glViewport(0.0, 0.0, width, height); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0.0, width, height, 0.0, -1.0f, 1.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    //glEnable(GL_TEXTURE_2D); 
    glClear(GL_COLOR_BUFFER_BIT); 
    SDL_GL_SwapBuffers(); 

    float angle = 0; 
    bool running = true; 
    while(running) 
    { 
     // handle all pending events 
     SDL_Event event; 
     while(SDL_PollEvent(&event)) 
     { 
      switch (event.type) 
      { 
      case SDL_QUIT: 
       running = false; 
       break; 
      default:   
       break; 
      } 
     } 

     angle += 1; 
     while(angle > 360) 
      angle -= 360; 

     // Render 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     glPushMatrix(); 
     glTranslatef(width/2, height/2, 0); 
     glScalef(150, 150, 0); 

     glRotatef(angle, 0, 0, 1); 
     glColor3ub(255,0,0); 
     glBegin(GL_TRIANGLES); 
     glVertex2i(0,0); 
     glVertex2i(1,0); 
     glVertex2i(1,1); 
     glEnd(); 

     glPopMatrix(); 

     // Flip the buffers 
     SDL_GL_SwapBuffers(); 

     SDL_Delay(10); 
    } 

    SDL_Quit(); 
    return 0; 
} 

如果該工程所有你需要做的(哈!)是找出簡單的程序執行流程從大的程序有什麼不同。如果它不起作用,你的環境可能會以某種方式被愚弄。

GL_VERSION/VENDOR/RENDERER檢查在您的系統上打印什麼?

1

它看起來像你設置每個像素的位爲0

m_screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL); 

一般來說,我覺得你在你的情況要32。

隨着中說,如果不解決您的問題,嘗試調用:

m_screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER); 

這將請求硬件表面和雙緩衝。

我還沒有看到你把這個:

glViewport(0, 0, width, height); 

你第一次調用glLoadIdentity之前。您可能在過去完成了此操作 - 但是,SDL_SetVideoMode可能會導致GL上下文重置,因此重新設置所需的所有OpenGL參數是一種很好的做法。

但是有一個更大的問題。我們專注於您的GL代碼,但可能會在此子系統初始化之前(或之後)將SDL弄糟。 我想建議您在進入主循環之前只需調用一次SDL_GetError(),以查看您沒有檢查過的某個錯誤是否沒有受到干擾。

當使用OpenGL時,SDL可以挑剔的事情還有很多。我的下一個擔心是您的代碼流可能不止一次地調用get_surface ...嘗試添加一個靜態變量,如下所示:

static int has_init = 0; 

has_init++; 
if (has_init > 1) { 
    // Well that's odd isn't it 
}