本文介绍了C ++ SDL2:如何将矩形渲染成多个视口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是SDL2(2.0.10版)的新手,我从Lazy Foo教程中教它.在 ViewPort的经验示例代码中,我仅在左侧视口中显示第一张图像,其他人没有.在不同视口中的矩形渲染也不起作用.我想在不同的视口中渲染rect时我做错了什么:

I am new into SDL2(version 2.0.10) and I teach it from Lazy Foo tutorial. In Lesson of The ViewPort example code render me only first image in left viewport and others not. 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 );
}

推荐答案

正如我所看到的,您在100x100的10、10处绘制了两次矩形,此坐标未考虑视口坐标.从某种意义上说,如果您想通过更改视口裁剪来实现此目的不相关,只需在所需的位置绘制正方形即可.

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. 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:

#include "Application.hpp"

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

    return app.mainLoop();
}

Application.hpp:

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 */

Application.cpp:

Application.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();
}

这篇关于C ++ SDL2:如何将矩形渲染成多个视口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 12:42