简体   繁体   中英

SDL 2.0 and a hung window frame (c++)

Im currently writing an app that is dependent on a physical device which uploads data at regular intervals and i am using SDL to do the drawing of this data for me. I've followed the online tutorials about setting up and rendering content (lines, circles etc).

I'm having trouble getting the window to actually respond (I am using Windows 7). Rendering occurs but for some reason even though I am handling the events prior to rendering the window is completely unresponsive. I cant even click the maximize, minimize and close buttons (and the mouse is indicating as a spinner). I get a lot of SDL_WINDOWEVENT_SHOWN events in the console as well which i am not sure if that is normal.

The Presenter class below is the sole code for controlling SDL in my app.

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 is called many times via an indirect callback. Since this is also Hardware based rendering various FPS applications are reporting a comfortable 60fps so I don't see why a while loop is needed in my case.

Can you see what I have missed in order to get the window to be responsive?

You need to exhaust all events in your render method, not just one.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM