SDL2两个窗口在不同的线程中

3
我正在尝试创建一个有两个窗口的进程。每个窗口都有一个不同的线程用于绘制。问题是,当我运行程序时,在随机的时间后会出现错误并给出分段错误。这是我的代码:
main.cpp
std::thread *thr1 = new std::thread(thread_func);
std::thread *thr2 = new std::thread(thread_func);

thread.cpp:

 Window *win = new Window(display_name, 1024, 768);
    Renderer *rend = win->CreateRenderer();
    Texture *pic = new Texture(rend, path);

    while (!quit)
    {
       usleep (10000);
       pic->DrawToWindow(src_rect,rect);
       rend->SetColor(255,255,255,255);
       rend->DrawLine(10,10,300,300,4);

    }
    delete pic;
    delete rend;
    delete win;

Window.cpp:

Window::Window(std::string &name, uint32_t w, uint32_t h, uint32_t x, uint32_t y)
: window(nullptr),
  windowRect()
{
    if (!SDL_WasInit(SDL_INIT_VIDEO))
    {
        PDEBUG("ERROR: SDL Was not inited please init platform first!\n");
        return;
    }

    //Create Window
    window = SDL_CreateWindow(name.c_str(), x, y, w, h, SDL_WINDOW_OPENGL);
    if (window == nullptr)
    {
        PDEBUG("ERROR: SDL_CreateWindow() %s\n", SDL_GetError());
        return;
    }

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
}

Window::~Window()
{
    if (window != nullptr)
    {
        SDL_DestroyWindow(window);
        window = nullptr;
    }
}

void
Window::Flush()
{
    SDL_GL_SwapWindow(window);
}


Renderer*
Window::CreateRenderer()
{
    return new Renderer(this);
}

Renderer.cpp:

Renderer::Renderer(Window *win)
    : window(win),
      render(nullptr),
      context()
{
    if (win == nullptr)
    {
        PDEBUG("ERROR: Window is NULL\n");
        return;
    }

    //Create Renderer
    render = SDL_CreateRenderer(win->window, -1, SDL_RENDERER_ACCELERATED);
    if (render == nullptr)
    {
        PDEBUG("ERROR: SDL_CreateRenderer(): %s\n", SDL_GetError());
        return;
    }

    //Create Window OpenGL Context
    //context = SDL_GL_CreateContext(win->window);
    //if (SDL_GL_MakeCurrent(window->window, context) != 0)
    //  PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());

    Clear();
}

Renderer::~Renderer()
{
    if (render != nullptr)
    {
        SDL_DestroyRenderer(render);
        render = nullptr;
        //SDL_GL_DeleteContext(context);
    }
}

bool
Renderer::DrawLine(int xStart, int yStart, int xEnd, int yEnd, int width)
{
    //if (SDL_GL_MakeCurrent(window->window, context) != 0)
    //      PDEBUG("ERROR: SDL_GL_MakeCurrent() %s\n", SDL_GetError());
    //}
    glLineWidth(width);
    if (SDL_RenderDrawLine(render, xStart, yStart, xEnd, yEnd) < 0)
    {
        PDEBUG("ERROR: SDL_RenderDrawLine() %s\n", SDL_GetError());
        return false;
    }
    return true;
}

我需要在两个窗口中只使用一个线程来绘图吗?还是要使用同步来绘图,或者使用SDL_Thread来创建线程呢?
2个回答

6

我只需要为两个窗口绘制一个线程吗?

是的。

根据SDL2线程文档:

注意:您不应该期望能够在主线程以外的任何线程上创建窗口、渲染或接收事件。对于特定于平台的异常或复杂选项,请在邮件列表或论坛上咨询。


好的,但是如果我在主线程中创建窗口并进行渲染,我可以使用指针将它们传递给线程。但是这并没有涉及到绘制、纹理加载和渲染过程,是吗? - shoc

-2

你好,我找到了在不同线程中解决2个窗口的方法。以下是示例:

static bool quit = false;

void
thread_function(SDL_Window* win, SDL_Renderer *rend)
{
  SDL_Event event;
  while(!quit)
  {
     //DO THINGS with renderer and window. (Draw, Fill, Present Textures and others)

     SDL_PollEvent(&event);
  }
}

对于每个线程,您需要轮询事件,因为窗口事件也在事件查询中。


不,这是不正确的。文档明确说明您不能期望在除主线程之外的任何其他线程上进行渲染。 - Martin Véronneau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接