c++ - SDL2 OpenGL3 如何在函数内初始化 SDL

标签 c++ opengl sdl sdl-2 opengl-3

我正在试验新的 SDL2 beta 和 OpenGL3 上下文,我遇到了一个奇怪的问题:

如果我在 main() 函数中运行 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;
}

最佳答案

void init_sdl(SDL_Window* sdl2_window, SDL_GLContext& opengl3_context)

您的第一个参数也应该是一个引用。否则,当您返回 main() 时,sdl2_window 仍为零。

关于c++ - SDL2 OpenGL3 如何在函数内初始化 SDL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13826150/

相关文章:

c++ - 双向链表 C++ 中的 add 方法问题

c++ - 如何模拟 QML 组件

c++ - 如何为一个类添加一个异常处理程序?

c++ - Intel/AMD C++ 上的 OpenGL 3+ 失败

c++ - 如何缩放到 SDL 中的分辨率?

c++ - 我应该为 `size_t` 包含哪个 header ?

c++ - gluLookAt 没有出现

opengl - 如果 GLSL 中的格式限定符是 r32f,imageLoad() 函数将返回什么?

c++ - 移动 SDL2 窗口的功能,同时鼠标向下闪烁窗口并且移动不够 'fast'

c++ - 如何在 SDL2 的窗口标题中使用重音字符?