【问题标题】:SDL OpenGL window instantly closesSDL OpenGL 窗口立即关闭
【发布时间】:2014-02-07 00:23:34
【问题描述】:

所以我刚刚开始使用 sdl,我让它在一个类中运行良好,但由于某种原因,当我将事物分成单独的类时,显示打开一个 insta 关闭。一个想法?

主类头

#pragma once
#include <SDL.h>
#include <glew.h>
#include <iostream>

#include "Input.h"
#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"

class Main
{   
public:
    Main();
    ~Main();

    /* Engine settings & Engine Controlls*/
    void start();
    void stop();
    void pause(bool value);
    void run();

private:

    /* Loop Controllers */
    bool running;
    bool paused;


    /* Engine Initialisation */
    void initSDL();

    RenderingEngine render_core  = RenderingEngine(4, 2);
    PhysicsEngine   physics_core = PhysicsEngine();
    Display     display      = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    Input input;


};

主类

#include "Main.h"

Main::Main()
{
   initSDL();
   start();
}


Main::~Main()
{

}

void Main::initSDL()
{
    SDL_Init(SDL_INIT_EVERYTHING);
}

void Main::start()
{
    if (running) return;
        running = true;
        run();
}

void Main::stop()
{
if (!running) return;
     running = false;
     exit(0);
}   

void Main::pause(bool value)
{
    paused = value;
}

void Main::run()
{

  while (running)
  {

     if (!paused)
     {

     }
    render_core.render();
    display.swapBackBuffer();
    input.update();
   }
 }

int main(int argc, char *argv[]) 
{

  Main engine;

  return 0;
}

显示标题

#pragma once
#include <iostream>
#include <SDL.h>

class Display
{   
public:
    Display(const char* name, int x, int y, int w, int h, Uint32 flags);
    ~Display();

    void swapBackBuffer();

private:

    int x;
    int y;
    int w;
    int h;

    const char* name;

    Uint32 flags;
    SDL_Window *window;
    SDL_GLContext opengl;

};

显示类

#include "Display.h"

Display::Display(const char* n, int x, int y, int w, int h, Uint32 f)
{
    this->x = x;
    this->y = y;
    this->w = w;
    this->h = h;
    this->name = name;
    this->flags = flags;

    this->window = SDL_CreateWindow(n, x, y, w, h, f);
    this->opengl = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, opengl);
    printf("Display: initialised\n\n");
}


Display::~Display()
{
    SDL_GL_DeleteContext(opengl);
    SDL_DestroyWindow(window);
    printf("Display: destroyed\n\n");
}

void Display::swapBackBuffer()
{
    SDL_GL_SwapWindow(window);
}

Render Engine 类....标题中没有任何重要的内容

#include "RenderingEngine.h"


RenderingEngine::RenderingEngine(int major_version, int minor_version)
{
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major_version);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor_version);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
    setClearColour(0, 0, 0, 1);
    printf("Rendering Engine:: initialised\n\n");
}


RenderingEngine::~RenderingEngine()
{
    printf("Rendering Engine:: destroyed\n");
}

void RenderingEngine::setClearColour(float r, float g, float b, float a)
{
    glClearColor(r, g, b, a);
}

void RenderingEngine::clearScreen()
{
    glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT);
}

void RenderingEngine::render()
{
    clearScreen();
}

输入类

   #include "Input.h"

Input::Input()
{
    printf("Input:: initialised\n");
}


Input::~Input()
{
    printf("Input:: destroyed\n");
}

void Input::setMouseVisabilityTo(bool value)
{
    if (value) SDL_ShowCursor(1);
    else       SDL_ShowCursor(0);
}

int Input::getMouseX()
{
    return mouseX;
}

int Input::getMouseY()
{
    return mouseY;
}

void Input::update()
{
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {

        case SDL_QUIT:

            break;

        case SDL_KEYDOWN:
            keyboard[event.key.keysym.sym] = true;
            break;

        case SDL_KEYUP:
            keyboard[event.key.keysym.sym] = false;
            break;

        case SDL_MOUSEBUTTONDOWN:
            mouse[event.button.button] = true;
            break;

        case SDL_MOUSEBUTTONUP:
            mouse[event.button.button] = false;
            break;

        case SDL_MOUSEWHEEL:

            break;

        case SDL_MOUSEMOTION:
            mouseX = event.button.x;
            mouseY = event.button.y;
            break;
        }   
    }   
}

我知道有很多文件,因此非常感谢您的帮助,这已经困扰我一段时间了

我编辑的 main.h 文件

#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"

class Main
{
public:
    Main() :
        render_core(4, 2),
        display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
        physics_core(),
        input()
    {
        running = false;
        paused = false;
        initSDL();
        start();
    }


    ~Main();

    /* Engine settings & Engine Controlls*/
    void start();
    void stop();
    void pause(bool value);
    void run();

private:

    /* Loop Controllers */
    bool running;
    bool paused;


    /* Engine Initialisation */
    void initSDL();

    RenderingEngine render_core;
    PhysicsEngine   physics_core;
    Display     display;

    Input input;

【问题讨论】:

  • 您是否曾经将running 设置为false?您应该始终在构造函数中初始化变量。

标签: c++ opengl sdl


【解决方案1】:

这是一个奇怪的 C++ 版本(例如 C++11),您可以在同一语句中声明和初始化一个非静态成员变量吗?

您不应该做那种事情,渲染上下文相对于软件其余部分的构建和初始化顺序非常重要。 这就是构造函数的用途。

假设您实际上是有意 (ab) 在这里使用 C++11,您的窗口会立即关闭,因为以下语句:

Display     display = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

构造一个Display 对象,然后复制该对象并将其分配给display。此语句“返回”后,原始对象被销毁。

看看Display 的析构函数做了什么:

Display::~Display()
{
    SDL_GL_DeleteContext(opengl);
    SDL_DestroyWindow(window);
    printf("Display: destroyed\n\n");
}

长话短说,不要以这种方式初始化您的成员。在 C++11 出现并让生活变得更加困难之前,构造函数非常好。

请考虑类似以下的构造函数

Main () : render_core  (4, 2),
          display      ("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
          physics_core ()
{
  initSDL ();
  start   ();
}

...

private:
  RenderingEngine render_core;
  PhysicsEngine   physics_core;
  Display         display;

此解决方案在构造时初始化Main 的所有成员,无需任何复制分配,并且与更广泛的 C++ 编译器兼容。此代码中没有临时的Display 对象意味着您的窗口不会被创建然后立即销毁。

【讨论】:

  • 嗨,感谢您对此的见解,但在添加该构造函数并更改我正在运行和暂停的布尔值以进行初始化后,它仍然会立即分散:/
  • 你改了Display display的声明吧?
  • 是的,我将编辑我的问题,向您展示我所做的更改
  • @DanielCollier:那应该已经解决了这个问题,现在我想知道您的Main 对象是如何创建的?你能在你构造Main对象的地方显示几行代码吗?
  • 如果你向下滚动到底部,它在我发布的第二个代码块中,main.cpp 文件 int main(int argc, char *argv[]) { Main engine;返回0; }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多