mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-08 03:18:47 +00:00
Re-added SDL_Texture wrapper and render utils
These were from the last attempt at accelerated rendering. We might be getting somewhere this time...
This commit is contained in:
parent
fe69a7f501
commit
0a265d1c51
@ -1,6 +1,7 @@
|
|||||||
sdl/exception.cpp
|
sdl/exception.cpp
|
||||||
sdl/rect.cpp
|
sdl/rect.cpp
|
||||||
sdl/surface.cpp
|
sdl/surface.cpp
|
||||||
|
sdl/texture.cpp
|
||||||
sdl/utils.cpp
|
sdl/utils.cpp
|
||||||
sdl/window.cpp
|
sdl/window.cpp
|
||||||
tracer.cpp
|
tracer.cpp
|
||||||
|
160
src/sdl/render_utils.hpp
Normal file
160
src/sdl/render_utils.hpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2017 - 2022
|
||||||
|
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY.
|
||||||
|
|
||||||
|
See the COPYING file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sdl/rect.hpp"
|
||||||
|
#include "sdl/texture.hpp"
|
||||||
|
#include "video.hpp"
|
||||||
|
|
||||||
|
#include <SDL2/SDL_rect.h>
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the renderer output target to the specified texture.
|
||||||
|
*/
|
||||||
|
class render_target_setter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit render_target_setter(texture& t)
|
||||||
|
: renderer_(CVideo::get_singleton().get_renderer())
|
||||||
|
, last_target_(nullptr)
|
||||||
|
{
|
||||||
|
if(renderer_) {
|
||||||
|
// Validate we can render to this texture.
|
||||||
|
assert(t.get_info().access == SDL_TEXTUREACCESS_TARGET);
|
||||||
|
|
||||||
|
last_target_ = SDL_GetRenderTarget(renderer_);
|
||||||
|
SDL_SetRenderTarget(renderer_, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~render_target_setter()
|
||||||
|
{
|
||||||
|
if(renderer_) {
|
||||||
|
SDL_SetRenderTarget(renderer_, last_target_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Renderer* renderer_;
|
||||||
|
SDL_Texture* last_target_; // TODO: use the texture wrapper?
|
||||||
|
};
|
||||||
|
|
||||||
|
using sdl_rect_getter = void (*)(SDL_Renderer*, SDL_Rect*);
|
||||||
|
using sdl_rect_setter = int (*)(SDL_Renderer*, const SDL_Rect*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for renderer RAII helpers that operate on SDL_Rects.
|
||||||
|
*
|
||||||
|
* @tparam G Getter function. Will fetch the current applicable rect.
|
||||||
|
* That will be restored as the applicable state once this object is destroyed.
|
||||||
|
* @tparam S Setter function.
|
||||||
|
*/
|
||||||
|
template<sdl_rect_getter G, sdl_rect_setter S>
|
||||||
|
class render_raii_rect_setter_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit render_raii_rect_setter_base(SDL_Rect* rect)
|
||||||
|
: operate_(rect != nullptr)
|
||||||
|
, last_rect_()
|
||||||
|
, renderer_(CVideo::get_singleton().get_renderer())
|
||||||
|
{
|
||||||
|
if(renderer_ && operate_) {
|
||||||
|
std::invoke(G, renderer_, &last_rect_);
|
||||||
|
std::invoke(S, renderer_, rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~render_raii_rect_setter_base()
|
||||||
|
{
|
||||||
|
if(renderer_ && operate_) {
|
||||||
|
if(last_rect_ != sdl::empty_rect) {
|
||||||
|
std::invoke(S, renderer_, &last_rect_);
|
||||||
|
} else {
|
||||||
|
std::invoke(S, renderer_, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool operate_;
|
||||||
|
SDL_Rect last_rect_;
|
||||||
|
SDL_Renderer* renderer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the renderer clip rect.
|
||||||
|
*/
|
||||||
|
using render_clip_rect_setter = render_raii_rect_setter_base<
|
||||||
|
&SDL_RenderGetClipRect,
|
||||||
|
&SDL_RenderSetClipRect>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the renderer viewport rect.
|
||||||
|
*/
|
||||||
|
using render_viewport_setter = render_raii_rect_setter_base<
|
||||||
|
&SDL_RenderGetViewport,
|
||||||
|
&SDL_RenderSetViewport>;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set renderer drawing color.
|
||||||
|
*/
|
||||||
|
inline void set_draw_color(SDL_Renderer* renderer, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
|
{
|
||||||
|
SDL_SetRenderDrawColor(renderer, r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set renderer drawing color.
|
||||||
|
*/
|
||||||
|
inline void set_draw_color(SDL_Renderer* renderer, color_t color)
|
||||||
|
{
|
||||||
|
set_draw_color(renderer, color.r, color.g, color.b, color.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEXTURE SETTERS =========================================================================
|
||||||
|
* Need to decide if these need their own file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline void set_texture_alpha(texture& t, uint8_t amount)
|
||||||
|
{
|
||||||
|
SDL_SetTextureAlphaMod(t, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_texture_blend_color(texture& t, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
SDL_SetTextureColorMod(t, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_texture_blend_mode(texture& t, SDL_BlendMode mode)
|
||||||
|
{
|
||||||
|
SDL_SetTextureBlendMode(t, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the texture scale quality. Note this should be called *before* a texture
|
||||||
|
* is created, since the hint has no effect on existing textures or render ops.
|
||||||
|
*
|
||||||
|
* @param value The scaling mode. Use either 'linear' or 'nearest'.
|
||||||
|
*/
|
||||||
|
inline void set_texture_scale_quality(const std::string& value)
|
||||||
|
{
|
||||||
|
SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, value.c_str(), SDL_HINT_OVERRIDE);
|
||||||
|
}
|
119
src/sdl/texture.cpp
Normal file
119
src/sdl/texture.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2017 - 2022
|
||||||
|
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY.
|
||||||
|
|
||||||
|
See the COPYING file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdl/texture.hpp"
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
#include "sdl/render_utils.hpp"
|
||||||
|
#include "sdl/surface.hpp"
|
||||||
|
#include "video.hpp"
|
||||||
|
|
||||||
|
static lg::log_domain log_sdl("SDL");
|
||||||
|
#define ERR_SDL LOG_STREAM(err, log_sdl)
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// The default pixel format to create textures with.
|
||||||
|
const int default_texture_format = SDL_PIXELFORMAT_ARGB8888;
|
||||||
|
|
||||||
|
void cleanup_texture(SDL_Texture* t)
|
||||||
|
{
|
||||||
|
if(t != nullptr) {
|
||||||
|
SDL_DestroyTexture(t);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
texture::texture()
|
||||||
|
: texture_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
texture::texture(SDL_Texture* txt)
|
||||||
|
: texture_(txt, &cleanup_texture)
|
||||||
|
{
|
||||||
|
finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
texture::texture(const surface& surf)
|
||||||
|
: texture_(nullptr)
|
||||||
|
{
|
||||||
|
SDL_Renderer* renderer = CVideo::get_singleton().get_renderer();
|
||||||
|
if(!renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_.reset(SDL_CreateTextureFromSurface(renderer, surf), &cleanup_texture);
|
||||||
|
if(!texture_) {
|
||||||
|
ERR_SDL << "When creating texture from surface: " << SDL_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
texture::texture(int w, int h, SDL_TextureAccess access)
|
||||||
|
: texture_(nullptr)
|
||||||
|
{
|
||||||
|
reset(w, h, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::finalize()
|
||||||
|
{
|
||||||
|
set_texture_blend_mode(*this, SDL_BLENDMODE_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::reset()
|
||||||
|
{
|
||||||
|
if(texture_) {
|
||||||
|
texture_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::reset(int w, int h, SDL_TextureAccess access)
|
||||||
|
{
|
||||||
|
// No-op if texture is null.
|
||||||
|
reset();
|
||||||
|
|
||||||
|
SDL_Renderer* renderer = CVideo::get_singleton().get_renderer();
|
||||||
|
if(!renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_.reset(SDL_CreateTexture(renderer, default_texture_format, access, w, h), &cleanup_texture);
|
||||||
|
if(!texture_) {
|
||||||
|
ERR_SDL << "When creating texture: " << SDL_GetError() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::assign(SDL_Texture* t)
|
||||||
|
{
|
||||||
|
texture_.reset(t, &cleanup_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture& texture::operator=(texture&& t)
|
||||||
|
{
|
||||||
|
texture_ = std::move(t.texture_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture::info::info(SDL_Texture* t)
|
||||||
|
: format(0)
|
||||||
|
, access(0)
|
||||||
|
, w(0)
|
||||||
|
, h(0)
|
||||||
|
{
|
||||||
|
SDL_QueryTexture(t, &format, &access, &w, &h);
|
||||||
|
}
|
89
src/sdl/texture.hpp
Normal file
89
src/sdl/texture.hpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2017 - 2022
|
||||||
|
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY.
|
||||||
|
|
||||||
|
See the COPYING file for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class surface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class to encapsulate creation and management of an SDL_Texture.
|
||||||
|
* Supports free creation and creation from a surface.
|
||||||
|
*/
|
||||||
|
class texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Default ctor. Texture will be a nullptr. */
|
||||||
|
texture();
|
||||||
|
|
||||||
|
texture(const texture&) = default;
|
||||||
|
|
||||||
|
/** Assigns the given texture to this one. */
|
||||||
|
explicit texture(SDL_Texture* txt);
|
||||||
|
|
||||||
|
/** Construct a texture from a surface. */
|
||||||
|
explicit texture(const surface& surf);
|
||||||
|
|
||||||
|
/** Construct a texture of the specified size and access type. */
|
||||||
|
texture(int w, int h, SDL_TextureAccess access);
|
||||||
|
|
||||||
|
/** Small wrapper that queries metadata about the provided texture. */
|
||||||
|
struct info
|
||||||
|
{
|
||||||
|
explicit info(SDL_Texture* t);
|
||||||
|
|
||||||
|
uint32_t format;
|
||||||
|
int access;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Queries metadata about the texture, such as its dimensions. */
|
||||||
|
const info get_info() const
|
||||||
|
{
|
||||||
|
return info(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Releases ownership of the managed texture and resets the ptr to null. */
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/** Releases ownership of the managed texture and creates a new one. */
|
||||||
|
void reset(int w, int h, SDL_TextureAccess access);
|
||||||
|
|
||||||
|
/** Replaces ownership of the managed texture with the given one. */
|
||||||
|
void assign(SDL_Texture* t);
|
||||||
|
|
||||||
|
texture& operator=(const texture& t) = default;
|
||||||
|
|
||||||
|
/** Move assignment. Releases ownership of the managed texture from the passed object. */
|
||||||
|
texture& operator=(texture&& t);
|
||||||
|
|
||||||
|
operator SDL_Texture*() const
|
||||||
|
{
|
||||||
|
return texture_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool null() const
|
||||||
|
{
|
||||||
|
return texture_ == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void finalize();
|
||||||
|
|
||||||
|
std::shared_ptr<SDL_Texture> texture_;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user