Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge some commits from the base of new_rendering, should fix problems with rendering on MacOS in master #6756

Merged
merged 10 commits into from
Jun 10, 2022
344 changes: 180 additions & 164 deletions src/display.cpp

Large diffs are not rendered by default.

59 changes: 28 additions & 31 deletions src/display.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,7 @@ class display : public video2::draw_layering
const std::string& timeid,
TERRAIN_TYPE terrain_type);

std::vector<surface> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);

void draw_image_for_report(surface& img, SDL_Rect& rect);
std::vector<texture> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);

void scroll_to_xy(int screenxpos, int screenypos, SCROLL_TYPE scroll_type,bool force = true);

Expand Down Expand Up @@ -753,7 +751,7 @@ class display : public video2::draw_layering

// Not set by the initializer:
std::map<std::string, SDL_Rect> reportRects_;
std::map<std::string, surface> reportSurfaces_;
std::map<std::string, texture> reportSurfaces_;
std::map<std::string, config> reports_;
std::vector<std::shared_ptr<gui::button>> menu_buttons_, action_buttons_;
std::set<map_location> invalidated_;
Expand All @@ -777,15 +775,14 @@ class display : public video2::draw_layering

private:

// This surface must be freed by the caller
surface get_flag(const map_location& loc);
texture get_flag(const map_location& loc);

/** Animated flags for each team */
std::vector<animated<image::locator>> flags_;

// This vector is a class member to avoid repeated memory allocations in get_terrain_images(),
// which turned out to be a significant bottleneck while profiling.
std::vector<surface> terrain_image_vector_;
std::vector<texture> terrain_image_vector_;

public:
/**
Expand Down Expand Up @@ -887,12 +884,12 @@ class display : public video2::draw_layering
* for every hex in the row
* ...
*
* * Surfaces are rendered per level in a map.
* * textures are rendered per level in a map.
* * Per level the items are rendered per location these locations are
* stored in the drawing order required for units.
* * every location has a vector with surfaces, each with its own screen
* * every location has a vector with textures, each with its own screen
* coordinate to render at.
* * every vector element has a vector with surfaces to render.
* * every vector element has a vector with textures to render.
*/
class drawing_buffer_key
{
Expand Down Expand Up @@ -922,38 +919,38 @@ class display : public video2::draw_layering
{
public:
// We don't want to copy this.
// It's expensive when done frequently due to the surface vector.
// It's expensive when done frequently due to the texture vector.
blit_helper(const blit_helper&) = delete;

blit_helper(const drawing_layer layer, const map_location& loc,
const int x, const int y, const surface& surf,
const SDL_Rect& dest, const texture& tex,
const SDL_Rect& clip)
: x_(x), y_(y), surf_(1, surf), clip_(clip),
: dest_(dest), tex_(1, tex), clip_(clip),
key_(loc, layer)
{}

blit_helper(const drawing_layer layer, const map_location& loc,
const int x, const int y, const std::vector<surface>& surf,
const SDL_Rect& dest, const std::vector<texture>& tex,
const SDL_Rect& clip)
: x_(x), y_(y), surf_(surf), clip_(clip),
: dest_(dest), tex_(tex), clip_(clip),
key_(loc, layer)
{}

int x() const { return x_; }
int y() const { return y_; }
const std::vector<surface> &surf() const { return surf_; }
const SDL_Rect& dest() const { return dest_; }
const std::vector<texture> &tex() const { return tex_; }
const SDL_Rect &clip() const { return clip_; }

bool operator<(const blit_helper &rhs) const { return key_ < rhs.key_; }

private:
int x_; /**< x screen coordinate to render at. */
int y_; /**< y screen coordinate to render at. */
std::vector<surface> surf_; /**< surface(s) to render. */
SDL_Rect clip_; /**<
* The clipping area of the source if
* omitted the entire source is used.
*/
/** The location on screen to draw to, in drawing coordinates. */
SDL_Rect dest_;
/** One or more textures to render. */
std::vector<texture> tex_;
/** The portion of the source texture to use.
* If omitted, the entire source is used. */
SDL_Rect clip_;
/** Allows ordering of draw calls by layer and location. */
drawing_buffer_key key_;
};

Expand All @@ -967,18 +964,18 @@ class display : public video2::draw_layering
* @param layer The layer to draw on.
* @param loc The hex the image belongs to, needed for the
* drawing order.
* @param x The x coordinate.
* @param y The y coordinate.
* @param surf The surface to use.
* @param dest The target destination on screen,
* in drawing coordinates.
* @param tex The texture to use.
* @param clip
*/
void drawing_buffer_add(const drawing_layer layer,
const map_location& loc, int x, int y, const surface& surf,
const map_location& loc, const SDL_Rect& dest, const texture& tex,
const SDL_Rect &clip = SDL_Rect());

void drawing_buffer_add(const drawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const map_location& loc, const SDL_Rect& dest,
const std::vector<texture> &tex,
const SDL_Rect &clip = SDL_Rect());

protected:
Expand Down
7 changes: 7 additions & 0 deletions src/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,19 @@ void draw::disc(int cx, int cy, int r, uint8_t octants)

void draw::blit(const texture& tex, const SDL_Rect& dst, const SDL_Rect& src)
{
if (!tex) { return; }
SDL_RenderCopy(renderer(), tex, &src, &dst);
}

void draw::blit(const texture& tex, const SDL_Rect& dst)
{
if (!tex) { return; }
SDL_RenderCopy(renderer(), tex, nullptr, &dst);
}

void draw::blit(const texture& tex)
{
if (!tex) { return; }
SDL_RenderCopy(renderer(), tex, nullptr, nullptr);
}

Expand All @@ -257,6 +260,7 @@ void draw::flipped(
bool flip_h,
bool flip_v)
{
if (!tex) { return; }
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
SDL_RenderCopyEx(renderer(), tex, &src, &dst, 0.0, nullptr, flip);
}
Expand All @@ -267,12 +271,14 @@ void draw::flipped(
bool flip_h,
bool flip_v)
{
if (!tex) { return; }
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
SDL_RenderCopyEx(renderer(), tex, nullptr, &dst, 0.0, nullptr, flip);
}

void draw::flipped(const texture& tex, bool flip_h, bool flip_v)
{
if (!tex) { return; }
SDL_RendererFlip flip = get_flip(flip_h, flip_v);
SDL_RenderCopyEx(renderer(), tex, nullptr, nullptr, 0.0, nullptr, flip);
}
Expand All @@ -281,6 +287,7 @@ void draw::flipped(const texture& tex, bool flip_h, bool flip_v)
void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered,
bool mirrored)
{
if (!tex) { return; }
// TODO: highdpi - should this draw at full res? Or game res? For now it's using game res. To draw in higher res, width and height would have to be specified.

// Reduce clip to dst.
Expand Down
12 changes: 8 additions & 4 deletions src/editor/editor_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,18 @@ void editor_display::draw_hex(const map_location& loc)
display::draw_hex(loc);
if (map().on_board_with_border(loc)) {
if (map().in_selection(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image("editor/selection-overlay.png", image::TOD_COLORED));
const texture& tex = image::get_texture(
"editor/selection-overlay.png", image::TOD_COLORED);
SDL_Rect dest{xpos, ypos, tex.w(), tex.h()};
drawing_buffer_add(LAYER_FOG_SHROUD, loc, dest, tex);
}

if (brush_locations_.find(loc) != brush_locations_.end()) {
static const image::locator brush(game_config::images::editor_brush);
drawing_buffer_add(LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(brush, image::SCALED_TO_HEX));
// TODO: highdpi - no prescaling
const texture& tex = image::get_texture(brush, image::SCALED_TO_HEX);
SDL_Rect dest{xpos, ypos, tex.w(), tex.h()};
drawing_buffer_add(LAYER_SELECTED_HEX, loc, dest, tex);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/editor/palette/editor_palettes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ void editor_palette<Item>::draw_contents()

surface item_image(nullptr);
std::stringstream tooltip_text;
// TODO: highdpi - does this need to draw onto a surface? or can it return a texture?
draw_item((*item).second, item_image, tooltip_text);

bool is_core = non_core_items_.find(get_id((*item).second)) == non_core_items_.end();
Expand All @@ -297,7 +298,8 @@ void editor_palette<Item>::draw_contents()
}

tile.set_tooltip_string(tooltip_text.str());
tile.set_item_image(item_image);
// TODO: highdpi - not sure if this is the best place to create the texture
tile.set_item_image(texture(item_image));
tile.set_item_id(item_id);

// if (get_id((*item).second) == selected_bg_item_
Expand Down
98 changes: 51 additions & 47 deletions src/editor/palette/tristate_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@

#include "editor/palette/tristate_button.hpp"

#include "draw.hpp"
#include "game_config.hpp"
#include "picture.hpp"
#include "log.hpp"
#include "sdl/rect.hpp"
#include "sound.hpp"
#include "video.hpp"
#include "video.hpp" // TODO: highdpi - only needed for widget constructor

static lg::log_domain log_display("display");
#define ERR_DP LOG_STREAM(err, log_display)
Expand All @@ -32,59 +33,71 @@ namespace gui {
tristate_button::tristate_button(CVideo& video,
editor::tristate_palette* palette,
std::string button_image_name,
const bool auto_join) :
widget(video, auto_join),
baseImage_(nullptr), touchedBaseImage_(nullptr), activeBaseImage_(nullptr),
itemImage_(nullptr),
pressedDownImage_(nullptr), pressedUpImage_(nullptr), pressedBothImage_(nullptr),
pressedBothActiveImage_(nullptr), pressedDownActiveImage_(nullptr), pressedUpActiveImage_(nullptr),
touchedDownImage_(nullptr), touchedUpImage_(nullptr), touchedBothImage_(nullptr),
textRect_(),
state_(NORMAL), pressed_(false),
base_height_(0), base_width_(0),
palette_(palette), item_id_()
const bool auto_join)
: widget(video, auto_join)
, baseImage_()
, touchedBaseImage_()
, activeBaseImage_()
, itemImage_()
, pressedDownImage_()
, pressedUpImage_()
, pressedBothImage_()
, pressedBothActiveImage_()
, pressedDownActiveImage_()
, pressedUpActiveImage_()
, touchedDownImage_()
, touchedUpImage_()
, touchedBothImage_()
, textRect_()
, state_(NORMAL)
, pressed_(false)
, base_height_(0)
, base_width_(0)
, palette_(palette)
, item_id_()
{

if (button_image_name.empty()) {
button_image_name = "buttons/button_selectable/button_selectable_38_";
}

baseImage_ =
image::get_image(button_image_name + "base.png");
image::get_texture(button_image_name + "base.png");
activeBaseImage_ =
image::get_image(button_image_name + "base-active.png");
image::get_texture(button_image_name + "base-active.png");
touchedBaseImage_ =
image::get_image(button_image_name + "base-touched.png");
image::get_texture(button_image_name + "base-touched.png");

touchedBothImage_ =
image::get_image(button_image_name + "border-touched-both.png");
image::get_texture(button_image_name + "border-touched-both.png");
touchedUpImage_ =
image::get_image(button_image_name + "border-touched-up.png");
image::get_texture(button_image_name + "border-touched-up.png");
touchedDownImage_ =
image::get_image(button_image_name + "border-touched-down.png");
image::get_texture(button_image_name + "border-touched-down.png");

pressedUpImage_ =
image::get_image(button_image_name + "border-pressed-up.png");
image::get_texture(button_image_name + "border-pressed-up.png");
pressedDownImage_ =
image::get_image(button_image_name + "border-pressed-down.png");
image::get_texture(button_image_name + "border-pressed-down.png");
pressedBothImage_ =
image::get_image(button_image_name + "border-pressed-both.png");
image::get_texture(button_image_name + "border-pressed-both.png");

pressedUpActiveImage_ =
image::get_image(button_image_name + "border-active-pressed-up.png");
image::get_texture(button_image_name + "border-active-pressed-up.png");
pressedDownActiveImage_ =
image::get_image(button_image_name + "border-active-pressed-down.png");
image::get_texture(button_image_name + "border-active-pressed-down.png");
pressedBothActiveImage_ =
image::get_image(button_image_name + "border-active-pressed-both.png");
image::get_texture(button_image_name + "border-active-pressed-both.png");

//TODO
// if (button_image.null()) {
// ERR_DP<< "error initializing button!" << std::endl;
// throw error();
// }

base_height_ = baseImage_->h;
base_width_ = baseImage_->w;
// TODO: highdpi - set this some better way
base_height_ = baseImage_.h();
base_width_ = baseImage_.w();

}

Expand Down Expand Up @@ -154,12 +167,10 @@ void tristate_button::enable(bool new_val) {
}
}

void tristate_button::draw_contents() {

surface image(nullptr);

surface overlay(nullptr);
surface base = baseImage_;
void tristate_button::draw_contents()
{
texture overlay;
texture base = baseImage_;

switch (state_) {

Expand Down Expand Up @@ -212,26 +223,19 @@ void tristate_button::draw_contents() {
break;
}

image = base;

// Draw the button base.
const SDL_Rect& loc = location();
draw::blit(base, loc);

surface scaled_item = scale_surface(itemImage_, 36, 36);

surface nbase = base.clone();

//TODO avoid magic numbers
SDL_Rect r {1, 1, 0, 0};
sdl_blit(scaled_item, nullptr, nbase, &r);
// Draw the item.
// TODO: highdpi - no idea why this is offset by 1, or why it's hardcoded as 36x36. But that's how it was previously, so that's how it still is.
SDL_Rect magic{loc.x + 1, loc.y + 1, 36, 36};
draw::blit(itemImage_, magic);

// Draw the button overlay, if any.
if (overlay) {
sdl_blit(overlay, nullptr, nbase, nullptr);
draw::blit(overlay, loc);
}

bg_restore();

image = nbase;
video().blit_surface(loc.x, loc.y, image);
}

//TODO move to widget
Expand Down