【问题标题】:SDL 2.0 and a hung window frame (c++)SDL 2.0 和悬挂式窗框 (c++)
【发布时间】:2015-12-15 02:19:03
【问题描述】:

我目前正在编写一个依赖于定期上传数据的物理设备的应用程序,并且我正在使用 SDL 为我绘制这些数据。我遵循了有关设置和渲染内容(线条、圆圈等)的在线教程。

我无法让窗口实际响应(我使用的是 Windows 7)。渲染发生但由于某种原因,即使我在渲染窗口之前处理事件也完全没有响应。我什至无法单击最大化、最小化和关闭按钮(并且鼠标指示为微调器)。我在控制台中也收到了很多 SDL_WINDOWEVENT_SHOWN 事件,我不确定这是否正常。

下面的 Presenter 类是在我的应用中控制 SDL 的唯一代码。

hpp:

#ifndef PRESENTER_HPP
#define PRESENTER_HPP

#include "Common.hpp"
#include "Presenter.hpp"
#include "SDL.h"
#include "SDL_surface.h"

namespace STFFT
{
    class Presenter {

        public:
            bool initPresenter();
            bool render();

        private:
            SDL_Renderer* ctxRndr;
            SDL_Window* ctxWnd;
            SDL_Surface* ctx;
            SDL_Event* ctxEvnt;
    };



}

#endif

cpp:

#include "Presenter.hpp"
#include "Log.hpp"

namespace STFFT {

    bool Presenter::initPresenter() {
        if(SDL_Init(SDL_INIT_VIDEO) < 0) {
            Log("Unable to Init SDL: %s", SDL_GetError());
            return false;
        }
        else {

            if(!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) {
                Log("Unable to Init hinting: %s", SDL_GetError());
            }

            if((ctxWnd = SDL_CreateWindow(
                "My SDL Game",
                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,640, 480, SDL_WINDOW_SHOWN)
            ) == NULL) {
                Log("Unable to create SDL Window: %s", SDL_GetError());
                return false;
            }

            ctxEvnt = new SDL_Event();

            ctx = SDL_GetWindowSurface(ctxWnd);

            if((ctxRndr = SDL_CreateRenderer(ctxWnd, -1, SDL_RENDERER_ACCELERATED)) == NULL) {
                Log("Unable to create renderer");
                return false;
            }
        }

        return true;
    }



    bool Presenter::render() {

        SDL_PollEvent( ctxEvnt );
        if( ctxEvnt->type == SDL_QUIT ) { 
         int dsfsd = 0;
        }
        if (ctxEvnt->type == SDL_WINDOWEVENT) {
        switch (ctxEvnt->window.event) {
            case SDL_WINDOWEVENT_SHOWN:
                SDL_Log("Window %d shown", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_HIDDEN:
                SDL_Log("Window %d hidden", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_EXPOSED:
                SDL_Log("Window %d exposed", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_MOVED:
                SDL_Log("Window %d moved to %d,%d",
                        ctxEvnt->window.windowID, ctxEvnt->window.data1,
                        ctxEvnt->window.data2);
                break;
            case SDL_WINDOWEVENT_RESIZED:
                SDL_Log("Window %d resized to %dx%d",
                        ctxEvnt->window.windowID, ctxEvnt->window.data1,
                        ctxEvnt->window.data2);
                break;
            case SDL_WINDOWEVENT_SIZE_CHANGED:
                SDL_Log("Window %d size changed to %dx%d",
                        ctxEvnt->window.windowID, ctxEvnt->window.data1,
                        ctxEvnt->window.data2);
                break;
            case SDL_WINDOWEVENT_MINIMIZED:
                SDL_Log("Window %d minimized", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_MAXIMIZED:
                SDL_Log("Window %d maximized", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_RESTORED:
                SDL_Log("Window %d restored", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_ENTER:
                SDL_Log("Mouse entered window %d",
                        ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_LEAVE:
                SDL_Log("Mouse left window %d", ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_FOCUS_GAINED:
                SDL_Log("Window %d gained keyboard focus",
                        ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_FOCUS_LOST:
                SDL_Log("Window %d lost keyboard focus",
                        ctxEvnt->window.windowID);
                break;
            case SDL_WINDOWEVENT_CLOSE:
                SDL_Log("Window %d closed", ctxEvnt->window.windowID);
                break;
            default:
                SDL_Log("Window %d got unknown event %d",
                        ctxEvnt->window.windowID, ctxEvnt->window.event);
                break;
            }
        }

            SDL_SetRenderDrawColor(ctxRndr, 0x00, 0x00, 0x00, 0xFF);
            SDL_RenderClear(ctxRndr);
            SDL_SetRenderDrawColor(ctxRndr,0xFF,0xFF,0xFF,0xFF);
            SDL_RenderSetScale(ctxRndr,1,1);
            SDL_RenderDrawLine(ctxRndr,0,0,639,479);
            SDL_RenderPresent(ctxRndr);

        return true;
    }

}

Presenter::render 通过间接回调被多次调用。由于这也是基于硬件的渲染,因此各种 FPS 应用程序都报告了舒适的 60fps,所以我不明白为什么在我的情况下需要一个 while 循环。

你能看到我为了让窗口响应而遗漏了什么吗?

【问题讨论】:

  • 是否定期调用render,例如每秒至少几次?
  • 是的 - 设备发送回调至少 200 次/秒

标签: c++ sdl


【解决方案1】:

您需要在render 方法中耗尽所有 个事件,而不仅仅是一个。

// Exhaust all events in the event queue.
while (SDL_PollEvent(&ctxEvnt))
{
    // handle the current event
};

【讨论】:

  • 修复了重复的 SDL_WINDOWEVENT_SHOWN 事件但窗口仍然挂起
猜你喜欢
  • 1970-01-01
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多