2011-12-10 95 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 
}