2012-12-11 60 views
7

我與新SDL2測試和OpenGL3方面的實驗裏面,我有一個奇怪的問題:SDL2 OpenGL3如何初始化SDL功能

如果我跑在我的主SDL的初始化代碼( )函數,它工作正常,但我想要在單獨的init_sdl()函數中具有此代碼。

如果我將初始化代碼放在一個單獨的init_sdl()函數中,並從main()中調用此函數,則永遠不會繪製背景顏色,並且程序開始瘋狂地佔用我係統的所有資源。

可能有人點我到SDL在一個單獨的函數初始化的工作的例子嗎?我似乎無法找到一個...也許這是不可能的?我想我隱約記得SDL 1.2有類似的問題,但是我已經使用了幾年,而且我認爲我沒有找到解決方案。實際上,這可能是我選擇轉而使用SFML的原因。

我真的想用SDL2,而不是SFML因爲它運行在更多的平臺,但不能夠的東西分離出來,進入小功能是一個大忌我。這應該很容易,我錯過了明顯的東西?

編輯:

這工作:

#include <iostream> 
#include <GL/glew.h> 
#include <SDL.h> 
#define PROGRAM_NAME "SDL2 OpenGL3 Example" 

int main(int argc, char** argv) 
{ 
    SDL_Window* sdl2_window = 0; 
    SDL_GLContext opengl3_context; 

    SDL_Init(SDL_INIT_VIDEO); 

    // set the opengl context version 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 

    // turn on double buffering set the depth buffer to 24 bits 
    // you may need to change this to 16 or 32 for your system 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 

    // create the sdl2 window 
    sdl2_window = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, 
      SDL_WINDOWPOS_CENTERED, 512, 512, 
      SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 

    // create the opengl3 context 
    opengl3_context = SDL_GL_CreateContext(sdl2_window); 

    GLenum status = glewInit(); 
    if (status != GLEW_OK) 
    { 
     std::cerr << "GLEW Error: " << glewGetErrorString(status) << "\n"; 
     exit(1); 
    } 

    // sync buffer swap with monitor's vertical refresh rate 
    SDL_GL_SetSwapInterval(1); 

    // set background color 
    glClearColor(1.0, 0.0, 0.0, 1.0); 

    while (true) 
    { 
     int status = 0; 

     glClear(GL_COLOR_BUFFER_BIT); 

     SDL_GL_SwapWindow(sdl2_window); 

     SDL_Event event; 

     while (SDL_PollEvent(&event)) 
     { 
      switch (event.type) 
      { 
      case SDL_KEYDOWN: 
       break; 
      case SDL_KEYUP: 
       // if escape is pressed, quit 
       if (event.key.keysym.sym == SDLK_ESCAPE) 
        status = 1; // set status to 1 to exit main loop 
       break; 
      case SDL_QUIT: 
       status = 1; 
       break; 
      } 
     } 

     if (status == 1) // if received instruction to quit 
      break; 
    } 

    // delete opengl3 context, destroy sdl2 window, and shut down sdl subsystems 
    SDL_GL_DeleteContext(opengl3_context); 
    SDL_DestroyWindow(sdl2_window); 
    SDL_Quit(); 

    return 0; 
} 

這不起作用:

#include <iostream> 
#include <GL/glew.h> 
#include <SDL.h> 
#define PROGRAM_NAME "SDL2 OpenGL3 Example" 

void init_sdl(SDL_Window* sdl2_window, SDL_GLContext& opengl3_context) 
{ 
    SDL_Init(SDL_INIT_VIDEO); 

    // set the opengl context version 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 

    // turn on double buffering set the depth buffer to 24 bits 
    // you may need to change this to 16 or 32 for your system 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 

    // create the sdl2 window 
    sdl2_window = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, 
      SDL_WINDOWPOS_CENTERED, 512, 512, 
      SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 

    // create the opengl3 context 
    opengl3_context = SDL_GL_CreateContext(sdl2_window); 
} 

int main(int argc, char** argv) 
{ 
    SDL_Window* sdl2_window = 0; 
    SDL_GLContext opengl3_context; 

    init_sdl(sdl2_window, opengl3_context); 

    GLenum status = glewInit(); 
    if (status != GLEW_OK) 
    { 
     std::cerr << "GLEW Error: " << glewGetErrorString(status) << "\n"; 
     exit(1); 
    } 

    // sync buffer swap with monitor's vertical refresh rate 
    SDL_GL_SetSwapInterval(1); 

    // set background color 
    glClearColor(1.0, 0.0, 0.0, 1.0); 

    while (true) 
    { 
     int status = 0; 

     glClear(GL_COLOR_BUFFER_BIT); 

     SDL_GL_SwapWindow(sdl2_window); 

     SDL_Event event; 

     while (SDL_PollEvent(&event)) 
     { 
      switch (event.type) 
      { 
      case SDL_KEYDOWN: 
       break; 
      case SDL_KEYUP: 
       // if escape is pressed, quit 
       if (event.key.keysym.sym == SDLK_ESCAPE) 
        status = 1; // set status to 1 to exit main loop 
       break; 
      case SDL_QUIT: 
       status = 1; 
       break; 
      } 
     } 

     if (status == 1) // if received instruction to quit 
      break; 
    } 

    // delete opengl3 context, destroy sdl2 window, and shut down sdl subsystems 
    SDL_GL_DeleteContext(opengl3_context); 
    SDL_DestroyWindow(sdl2_window); 
    SDL_Quit(); 

    return 0; 
} 
+1

[SSCCE(http://sscce.org/)時間。 – genpfault

+0

我加了代碼示例 – Defcronyke

回答

3
void init_sdl(SDL_Window* sdl2_window, SDL_GLContext& opengl3_context) 

你的第一個參數應該是一個參考了。否則當你回到main()sdl2_window仍然是零。

+0

謝謝!所以一個指針參考,呃?我沒有意識到指針和指針引用之間有區別。 – Defcronyke

+0

沒問題!這就是爲什麼我喜歡SSCCE :) – genpfault

+1

@Defcronyke,當你發送一個變量(一個函數)的值,你複製它的內容和功能將無法改變該變量。如果這個變量恰好是一個指針,那是一樣的。您正在傳遞「by-value」指針,這意味着'init_sdl'有一個地址(它可以改變它指向的地址),但不能更改保存該地址的原始變量。這就是爲什麼你需要通過引用發送它,所以你可以改變指針本身。 – Shahbaz

0

確定的背景下是沒有過錯:

int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_SHOWN; 
win = SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 768, flags); 
SDL_assert(win != NULL); 

context = SDL_GL_CreateContext(win); 
SDL_assert(context != NULL);