2012-12-11 14 views
7

ich mit der neuen SDL2 Beta bin das Experimentieren und ein OpenGL3 Kontext, und ich ein seltsames Problem mit:SDL2 OpenGL3 Wie SDL in einer Funktion zur Initialisierung

Wenn ich ausführen, um die SDL Initialisierungscode in meinem Haupt () Funktion, es funktioniert gut, aber ich möchte diesen Code in einer separaten init_sdl() -Funktion haben.

Wenn ich den Initialisierungscode in eine separate init_sdl() -Funktion setzen und diese Funktion von main() aufrufen, wird die Hintergrundfarbe nie gezeichnet, und das Programm beginnt, alle Ressourcen meines Systems zu verbrauchen.

Könnte mich jemand auf ein funktionierendes Beispiel verweisen, in dem SDL in einer separaten Funktion initialisiert wird? Ich kann keinen finden ... Vielleicht ist das nicht möglich? Ich denke, ich erinnere mich vage daran, ein ähnliches Problem mit SDL 1.2 zu haben, aber es ist ein paar Jahre her, dass ich es benutzt habe, und ich glaube nicht, dass ich jemals eine Lösung gefunden habe. In der Tat könnte dies der Grund sein, warum ich stattdessen SFML verwendet habe.

Ich möchte wirklich SDL2 anstelle von SFML verwenden, weil es auf mehr Plattformen läuft, aber nicht in der Lage, Dinge in kleine Funktionen zu trennen, ist ein Deal Breaker für mich. Das sollte einfach sein, vermisse ich etwas Offensichtliches?

Edit:

Dies funktioniert:

#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; 
} 

Das funktioniert nicht:

#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/) Zeit. – genpfault

+0

Ich habe Codebeispiele hinzugefügt – Defcronyke

Antwort

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

Ihr erstes Argument sollte auch ein Hinweis sein. Andernfalls, wenn Sie wieder auf main()sdl2_window sind, ist immer noch Null.

+0

Danke! Also eine Zeigerreferenz, oder? Ich wusste nicht, dass es einen Unterschied zwischen einem Zeiger und einer Zeigerreferenz gab. – Defcronyke

+0

Kein Problem! Deshalb mag ich SSCCEs :) – genpfault

+1

@Defcronyke, wenn Sie eine Variable (an eine Funktion) nach Wert senden, kopieren Sie ihren Inhalt und die Funktionen haben keine Möglichkeit, diese Variable zu ändern. Wenn diese Variable ein Zeiger ist, ist es dasselbe. Sie übergeben den Zeiger "by-value", was bedeutet, dass "init_sdl" eine Adresse hat (an der es sich ändern kann), aber die ursprüngliche Variable, die diese Adresse enthält, nicht ändern kann. Deshalb müssen Sie es als Referenz senden, damit Sie den Zeiger selbst ändern können. – Shahbaz

0

Sind Sie sicher, dass der Kontext nicht fehlerhaft ist:

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);