Skip to content

Commit

Permalink
Geometry renderer (#42227)
Browse files Browse the repository at this point in the history
  • Loading branch information
barsoosayque authored Jul 26, 2020
1 parent e55c3fc commit 6f0192f
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 176 deletions.
11 changes: 6 additions & 5 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,10 @@ formatted_text::formatted_text( const std::string &text, const int color,
}
}

cata_tiles::cata_tiles( const SDL_Renderer_Ptr &renderer ) :
cata_tiles::cata_tiles( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry ) :
renderer( renderer ),
minimap( renderer )
geometry( geometry ),
minimap( renderer, geometry )
{
assert( renderer );

Expand Down Expand Up @@ -1004,7 +1005,7 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
"SDL_RenderSetClipRect failed" );

//fill render area with black to prevent artifacts where no new pixels are drawn
render_fill_rect( renderer, clipRect, 0, 0, 0 );
geometry->rect( renderer, clipRect, SDL_Color() );
}

point s;
Expand Down Expand Up @@ -2173,7 +2174,7 @@ bool cata_tiles::draw_terrain_below( const tripoint &p, const lit_level, int &,
if( tile_iso ) {
belowRect.y += tile_height / 8;
}
render_fill_rect( renderer, belowRect, tercol.r, tercol.g, tercol.b );
geometry->rect( renderer, belowRect, tercol );

return true;
}
Expand Down Expand Up @@ -2721,7 +2722,7 @@ bool cata_tiles::draw_critter_at_below( const tripoint &p, const lit_level, int
belowRect.y += tile_height / 8;
}

render_fill_rect( renderer, belowRect, tercol.r, tercol.g, tercol.b );
geometry->rect( renderer, belowRect, tercol );

return true;
}
Expand Down
4 changes: 3 additions & 1 deletion src/cata_tiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "pimpl.h"
#include "point.h"
#include "sdl_wrappers.h"
#include "sdl_geometry.h"
#include "type_id.h"
#include "weather.h"
#include "weighted_list.h"
Expand Down Expand Up @@ -266,7 +267,7 @@ using color_block_overlay_container = std::pair<SDL_BlendMode, std::multimap<poi
class cata_tiles
{
public:
cata_tiles( const SDL_Renderer_Ptr &render );
cata_tiles( const SDL_Renderer_Ptr &render, const GeometryRenderer_Ptr &geometry );
~cata_tiles();
public:
/** Reload tileset, with the given scale. Scale is divided by 16 to allow for scales < 1 without risking
Expand Down Expand Up @@ -498,6 +499,7 @@ class cata_tiles

/** Variables */
const SDL_Renderer_Ptr &renderer;
const GeometryRenderer_Ptr &geometry;
std::unique_ptr<tileset> tileset_ptr;

int tile_height = 0;
Expand Down
9 changes: 5 additions & 4 deletions src/pixel_minimap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ struct pixel_minimap::submap_cache {
}
};

pixel_minimap::pixel_minimap( const SDL_Renderer_Ptr &renderer ) :
pixel_minimap::pixel_minimap( const SDL_Renderer_Ptr &renderer,
const GeometryRenderer_Ptr &geometry ) :
renderer( renderer ),
geometry( geometry ),
type( pixel_minimap_type::ortho ),
screen_rect{ 0, 0, 0, 0 }
{
Expand Down Expand Up @@ -269,7 +271,7 @@ void pixel_minimap::flush_cache_updates()

const SDL_Rect rect = SDL_Rect{ tile_pos.x, tile_pos.y, tile_size.x, tile_size.y };

render_fill_rect( renderer, rect, 0x00, 0x00, 0x00 );
geometry->rect( renderer, rect, SDL_Color() );
}
}
}
Expand All @@ -282,8 +284,7 @@ void pixel_minimap::flush_cache_updates()
SetRenderDrawColor( renderer, tile_color.r, tile_color.g, tile_color.b, tile_color.a );
RenderDrawPoint( renderer, tile_pos );
} else {
const SDL_Rect rect = SDL_Rect{ tile_pos.x, tile_pos.y, pixel_size.x, pixel_size.y };
render_fill_rect( renderer, rect, tile_color.r, tile_color.g, tile_color.b );
geometry->rect( renderer, tile_pos, pixel_size.x, pixel_size.y, tile_color );
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/pixel_minimap.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "point.h"
#include "sdl_wrappers.h"
#include "sdl_geometry.h"

class pixel_minimap_projector;

Expand All @@ -33,7 +34,7 @@ struct pixel_minimap_settings {
class pixel_minimap
{
public:
pixel_minimap( const SDL_Renderer_Ptr &renderer );
pixel_minimap( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry );
~pixel_minimap();

void set_type( pixel_minimap_type type );
Expand Down Expand Up @@ -66,6 +67,7 @@ class pixel_minimap

private:
const SDL_Renderer_Ptr &renderer;
const GeometryRenderer_Ptr &geometry;

pixel_minimap_type type;
pixel_minimap_settings settings;
Expand Down
77 changes: 77 additions & 0 deletions src/sdl_geometry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#if defined(TILES)
#include "sdl_geometry.h"
#include "debug.h"

void GeometryRenderer::horizontal_line( const SDL_Renderer_Ptr &renderer, const point &pos, int x2,
int thickness, const SDL_Color &color ) const
{
SDL_Rect rect { pos.x, pos.y, x2 - pos.x, thickness };
this->rect( renderer, rect, color );
}

void GeometryRenderer::vertical_line( const SDL_Renderer_Ptr &renderer, const point &pos, int y2,
int thickness, const SDL_Color &color ) const
{
SDL_Rect rect { pos.x, pos.y, thickness, y2 - pos.y };
this->rect( renderer, rect, color );
}

void GeometryRenderer::rect( const SDL_Renderer_Ptr &renderer, const point &pos, int width,
int height, const SDL_Color &color ) const
{
SDL_Rect rect { pos.x, pos.y, width, height };
this->rect( renderer, rect, color );
}


void DefaultGeometryRenderer::rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
const SDL_Color &color ) const
{
SetRenderDrawColor( renderer, color.r, color.g, color.b, color.a );
RenderFillRect( renderer, &rect );
}

ColorModulatedGeometryRenderer::ColorModulatedGeometryRenderer( const SDL_Renderer_Ptr &renderer )
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
static const Uint32 rmask = 0xff000000;
static const Uint32 gmask = 0x00ff0000;
static const Uint32 bmask = 0x0000ff00;
static const Uint32 amask = 0x000000ff;
#else
static const Uint32 rmask = 0x000000ff;
static const Uint32 gmask = 0x0000ff00;
static const Uint32 bmask = 0x00ff0000;
static const Uint32 amask = 0xff000000;
#endif
SDL_Surface_Ptr alt_surf( SDL_CreateRGBSurface( 0, 1, 1, 32, rmask, gmask, bmask, amask ) );
if( alt_surf ) {
FillRect( alt_surf, nullptr, SDL_MapRGB( alt_surf->format, 255, 255, 255 ) );

tex.reset( SDL_CreateTextureFromSurface( renderer.get(), alt_surf.get() ) );
alt_surf.reset();

// Test to make sure color modulation is supported by renderer
bool tex_enable = !SetTextureColorMod( tex, 0, 0, 0 );
if( !tex_enable ) {
tex.reset();
}
DebugLog( D_INFO, DC_ALL ) << "ColorModulatedGeometryRenderer constructor() = " <<
( tex_enable ? "FAIL" : "SUCCESS" ) << ". tex_enable = " << tex_enable;
} else {
DebugLog( D_ERROR, DC_ALL ) << "CreateRGBSurface failed: " << SDL_GetError();
}
}

void ColorModulatedGeometryRenderer::rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
const SDL_Color &color ) const
{
if( tex ) {
SetTextureColorMod( tex, color.r, color.g, color.b );
RenderCopy( renderer, tex, nullptr, &rect );
} else {
DefaultGeometryRenderer::rect( renderer, rect, color );
}
}

#endif // TILES
58 changes: 58 additions & 0 deletions src/sdl_geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once
#ifndef CATA_SRC_SDL_GEOMETRY_H
#define CATA_SRC_SDL_GEOMETRY_H

#if defined(TILES)
#include <memory>

#include "sdl_wrappers.h"
#include "point.h"

/// Interface to render geometry with SDL_Renderer.
class GeometryRenderer
{
public:
virtual ~GeometryRenderer() = default;

/// Renders a SDL rectangle with given color.
virtual void rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
const SDL_Color &color ) const = 0;

/// Renders a point+width+height defined rectangle with given color.
void rect( const SDL_Renderer_Ptr &renderer, const point &pos, int width, int height,
const SDL_Color &color ) const;

/// Renders a straight horizontal line with given thickness and color.
void horizontal_line( const SDL_Renderer_Ptr &renderer, const point &pos, int x2, int thickness,
const SDL_Color &color ) const;

/// Renders a straight vertical line with given thickness and color.
void vertical_line( const SDL_Renderer_Ptr &renderer, const point &pos, int y2, int thickness,
const SDL_Color &color ) const;
};
using GeometryRenderer_Ptr = std::unique_ptr<GeometryRenderer>;

/// Implementation of a GeometryRenderer using default RenderFillRect.
class DefaultGeometryRenderer : public GeometryRenderer
{
public:
void rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
const SDL_Color &color ) const override;
};

/// Implementation of a GeometryRenderer using color modulated textures if
/// possible, falling back to DefaultGeometryRenderer otherwise.
class ColorModulatedGeometryRenderer: public DefaultGeometryRenderer
{
public:
ColorModulatedGeometryRenderer( const SDL_Renderer_Ptr &renderer );

void rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
const SDL_Color &color ) const override;
private:
SDL_Texture_Ptr tex;
};

#endif // TILES

#endif // CATA_SRC_SDL_GEOMETRY_H
12 changes: 0 additions & 12 deletions src/sdl_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,6 @@ SDL_Surface_Ptr create_surface_32( int w, int h )
#endif
}

void render_fill_rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect,
Uint32 r, Uint32 g, Uint32 b )
{
if( alt_rect_tex_enabled ) {
SetTextureColorMod( alt_rect_tex, r, g, b );
RenderCopy( renderer, alt_rect_tex, nullptr, &rect );
} else {
SetRenderDrawColor( renderer, r, g, b, 255 );
RenderFillRect( renderer, &rect );
}
}

SDL_Rect fit_rect_inside( const SDL_Rect &inner, const SDL_Rect &outer )
{
const float inner_ratio = static_cast<float>( inner.w ) / inner.h;
Expand Down
4 changes: 0 additions & 4 deletions src/sdl_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,6 @@ SDL_Color curses_color_to_SDL( const nc_color &color );
///@returns Always a valid pointer.
SDL_Surface_Ptr create_surface_32( int w, int h );

// SDL_RenderFillRect replacement handler
void render_fill_rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect, Uint32 r, Uint32 g,
Uint32 b );

SDL_Rect fit_rect_inside( const SDL_Rect &inner, const SDL_Rect &outer );

/** Linearly interpolate intermediate colors between two given colors.
Expand Down
Loading

0 comments on commit 6f0192f

Please sign in to comment.