C ++ SDL2: как визуализировать ректы в нескольких окнах просмотра - PullRequest
0 голосов
/ 26 января 2020

Я новичок в SDL2 (версия 2.0.10) и преподаю его из учебника Lazy Foo. В уроке примера кода ViewPort отображается только первое изображение в левом окне просмотра, а другие нет. Рендеринг ректов в разных видовых экранах тоже не работает. Что я делаю неправильно, когда хочу рендерить ректы в разных окнах, например:

while( !quit ){

while( SDL_PollEvent( &e ) != 0 ){
if( e.type == SDL_QUIT ){
 quit = true;
}
}

//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );

//Top left corner viewport
SDL_Rect topLeftViewport;
topLeftViewport.x = 0;
topLeftViewport.y = 0;
topLeftViewport.w = SCREEN_WIDTH / 2;
topLeftViewport.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport( gRenderer, &topLeftViewport );

SDL_Rect fillRect = { 10, 10, 100, 100 };
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0x00, 0x00, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect );

SDL_Rect topRightViewport;
topRightViewport.x = SCREEN_WIDTH / 2;
topRightViewport.y = 0;
topRightViewport.w = SCREEN_WIDTH / 2;
topRightViewport.h = SCREEN_HEIGHT / 2;
SDL_RenderSetViewport( gRenderer, &topRightViewport );

SDL_Rect fillRect2 = { 10, 10, 100, 100 };
SDL_SetRenderDrawColor( gRenderer, 0x00, 0xFF, 0x00, 0xFF );
SDL_RenderFillRect( gRenderer, &fillRect2 );

SDL_RenderPresent( gRenderer );
}

1 Ответ

0 голосов
/ 26 января 2020

Как я видел, вы рисуете прямоугольник 10, 10 из 100x100 два раза, эти координаты не учитывают координаты области просмотра. И в некотором смысле, если вы хотите сделать это, изменив отсечение области просмотра, не имеет значения ... просто нарисуйте квадрат, где вы хотите.

ОБНОВЛЕНИЕ: Я пробовал несколько окон просмотра. Вот рабочий пример. Вы можете выбрать между средством визуализации (с окнами просмотра) или классическим c способом.

main. cpp:

#include "Application.hpp"

int
main (int argc, char * argv[])
{
    Application app("SDL 2 Test", 800, 600, true);

    return app.mainLoop();
}

Application.hpp:

#ifndef APPLICATION_HPP
#define APPLICATION_HPP

#include <SDL2/SDL.h>

class Application
{
    public:

        Application (const char * title = "UnknownApplication", int baseWidth = 640, int baseHeight = 480, bool useRenderer = false) noexcept;

        ~Application ();

        int mainLoop () noexcept;

    private:

        int m_width = 0;
        int m_height = 0;
        SDL_Window * m_window = nullptr;
        SDL_Renderer * m_renderer = nullptr;
        bool m_useRenderer = false;
        bool m_isRunning = false;
};

#endif /* APPLICATION_HPP */

Приложение. cpp:

#include "Application.hpp"

#include <iostream>

#include <SDL2/SDL_image.h>

Application::Application (const char * title, int baseWidth, int baseHeight, bool useRenderer) noexcept
    : m_width(baseWidth), m_height(baseHeight), m_useRenderer(useRenderer)
{
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;

        return;
    }

    m_window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_width, m_height, SDL_WINDOW_SHOWN);

    if ( m_window == nullptr )
    {
        std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;

        return;
    }

    if ( m_useRenderer )
    {
        m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);

        if ( m_renderer == nullptr )
        {
            std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl;

            return;
        }
    }

    m_isRunning = true;
}

int
Application::mainLoop () noexcept
{
    SDL_Event event;

    const auto filepath = "SET_IMAGE_YOU_WANT_HERE";

    auto surface = IMG_Load(filepath);

    if ( surface == nullptr )
    {
        std::cerr << "Unable to read image file : " << filepath << std::endl;

        return 1;
    }

    SDL_Rect logoPosition = {8, 8, 32, 32};

    if ( m_useRenderer )
    {
        auto texture = SDL_CreateTextureFromSurface(m_renderer, surface);

        SDL_Rect screenA = {0, 0, m_width / 2, m_height / 2};
        SDL_Rect screenB = {m_width / 2, 0, m_width / 2, m_height / 2};

        while ( m_isRunning )
        {
            while ( SDL_PollEvent(&event) != 0 )
            {
                if ( event.type == SDL_QUIT )
                    m_isRunning = false;
            }

            SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255);
            SDL_RenderClear(m_renderer);

            SDL_RenderSetViewport(m_renderer, &screenA);
            SDL_SetRenderDrawColor(m_renderer, 255, 0, 0, 255);
            SDL_RenderFillRect(m_renderer, nullptr);
            SDL_RenderCopy(m_renderer, texture, nullptr, &logoPosition);

            SDL_RenderSetViewport(m_renderer, &screenB);
            SDL_SetRenderDrawColor(m_renderer, 0, 255, 0, 255);
            SDL_RenderFillRect(m_renderer, nullptr);
            SDL_RenderCopy(m_renderer, texture, nullptr, &logoPosition);

            SDL_RenderPresent(m_renderer);
        }

        SDL_DestroyTexture(texture);
    }
    else
    {
        auto windowSurface = SDL_GetWindowSurface(m_window);

        while ( m_isRunning )
        {
            while ( SDL_PollEvent(&event) != 0 )
            {
                if ( event.type == SDL_QUIT )
                    m_isRunning = false;
            }

            SDL_FillRect(windowSurface, nullptr, SDL_MapRGB(windowSurface->format, 0xFF, 0x00, 0xFF));

            //SDL_BlitSurface(surface, nullptr, windowSurface, &logoPosition);
            SDL_BlitScaled(surface, nullptr, windowSurface, &logoPosition);

            SDL_UpdateWindowSurface(m_window);
        }
    }

    SDL_FreeSurface(surface);

    return 0;
}

Application::~Application (void)
{
    if ( m_renderer != nullptr )
        SDL_DestroyRenderer(m_renderer);

    if ( m_window != nullptr )
        SDL_DestroyWindow(m_window);

    SDL_Quit();
}
...