简体   繁体   English

C++ SDL2:如何将矩形渲染到多个视口中

[英]C++ SDL2: How to render rects into multiple viewports

I am new into SDL2(version 2.0.10) and I teach it from Lazy Foo tutorial.我是 SDL2(版本 2.0.10)的新手,我从 Lazy Foo 教程中教授它。 In Lesson of The ViewPort example code render me only first image in left viewport and others not.ViewPort示例代码的课程中,我只在左视口中呈现第一张图像,而其他图像则不然。 Render of rects in different viewports don't work either.在不同视口中渲染矩形也不起作用。 What I am doing wrong when I want render rects in different viewports like this:当我想在不同的视口中渲染矩形时,我做错了什么:

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 );
}

As I saw, you are drawing a rect at 10, 10 of 100x100 two times, this coordinates doesn't take account of the viewport coordinates.正如我所看到的,您在 10, 10 of 100x100 处绘制了两次矩形,此坐标未考虑视口坐标。 And in a way, if you want to do this by changing the viewport clipping is not relevant... just draw the square where you want.并且在某种程度上,如果您想通过更改视口剪裁来做到这一点并不相关……只需在您想要的地方绘制正方形即可。

UPDATE: I tried multiples viewports.更新:我尝试了多个视口。 Here is a working example.这是一个工作示例。 You can choose between the renderer (with viewports) or the classic way.您可以在渲染器(带视口)或经典方式之间进行选择。

main.cpp :主.cpp :

#include "Application.hpp"

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

    return app.mainLoop();
}

Application.hpp :应用程序.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 */

Application.cpp :应用程序.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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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