mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
Use SDL BlitMode's to speed up image rendering
This commit is contained in:
13
Global.h
13
Global.h
@@ -116,33 +116,32 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
|
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <bitset>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <functional>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <atomic>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
//The only available version is 3, as of Boost 1.50
|
//The only available version is 3, as of Boost 1.50
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ void MapRendererTerrain::renderTile(const IMapRendererContext & context, Canvas
|
|||||||
image->shiftPalette(242, 14, context.terrainImageIndex(14));
|
image->shiftPalette(242, 14, context.terrainImageIndex(14));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image->setBlitMode(EImageBlitMode::OPAQUE);
|
||||||
target.draw(image, Point(0, 0));
|
target.draw(image, Point(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ public:
|
|||||||
/// returns animation frame for terrain
|
/// returns animation frame for terrain
|
||||||
virtual size_t terrainImageIndex(size_t groupSize) const = 0;
|
virtual size_t terrainImageIndex(size_t groupSize) const = 0;
|
||||||
|
|
||||||
/// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
// /// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
||||||
virtual Point getTileSize() const = 0;
|
// virtual Point getTileSize() const = 0;
|
||||||
|
|
||||||
/// if true, map grid should be visible on map
|
/// if true, map grid should be visible on map
|
||||||
virtual bool showGrid() const = 0;
|
virtual bool showGrid() const = 0;
|
||||||
|
|||||||
@@ -189,14 +189,14 @@ size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
|
|||||||
return frameIndex;
|
return frameIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point MapRendererContext::getTileSize() const
|
//Point MapRendererContext::getTileSize() const
|
||||||
{
|
//{
|
||||||
return Point(32, 32);
|
// return Point(32, 32);
|
||||||
}
|
//}
|
||||||
|
|
||||||
bool MapRendererContext::showGrid() const
|
bool MapRendererContext::showGrid() const
|
||||||
{
|
{
|
||||||
return true; // settings["gameTweaks"]["showGrid"].Bool();
|
return settings["gameTweaks"]["showGrid"].Bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapRendererContext::showVisitable() const
|
bool MapRendererContext::showVisitable() const
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
double objectTransparency(ObjectInstanceID objectID) const override;
|
double objectTransparency(ObjectInstanceID objectID) const override;
|
||||||
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
|
size_t objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const override;
|
||||||
size_t terrainImageIndex(size_t groupSize) const override;
|
size_t terrainImageIndex(size_t groupSize) const override;
|
||||||
Point getTileSize() const override;
|
// Point getTileSize() const override;
|
||||||
bool showGrid() const override;
|
bool showGrid() const override;
|
||||||
bool showVisitable() const override;
|
bool showVisitable() const override;
|
||||||
bool showBlockable() const override;
|
bool showBlockable() const override;
|
||||||
|
|||||||
@@ -41,27 +41,31 @@ class IImage;
|
|||||||
class CMapHandler;
|
class CMapHandler;
|
||||||
class IMapObjectObserver;
|
class IMapObjectObserver;
|
||||||
|
|
||||||
|
// from VwSymbol.def
|
||||||
enum class EWorldViewIcon
|
enum class EWorldViewIcon
|
||||||
{
|
{
|
||||||
TOWN = 0,
|
TOWN = 0,
|
||||||
HERO,
|
HERO = 1,
|
||||||
ARTIFACT,
|
ARTIFACT = 2,
|
||||||
TELEPORT,
|
TELEPORT = 3,
|
||||||
GATE,
|
GATE = 4,
|
||||||
MINE_WOOD,
|
MINE_WOOD = 5,
|
||||||
MINE_MERCURY,
|
MINE_MERCURY = 6,
|
||||||
MINE_STONE,
|
MINE_STONE = 7,
|
||||||
MINE_SULFUR,
|
MINE_SULFUR = 8,
|
||||||
MINE_CRYSTAL,
|
MINE_CRYSTAL = 9,
|
||||||
MINE_GEM,
|
MINE_GEM = 10,
|
||||||
MINE_GOLD,
|
MINE_GOLD = 11,
|
||||||
RES_WOOD,
|
RES_WOOD = 12,
|
||||||
RES_MERCURY,
|
RES_MERCURY = 13,
|
||||||
RES_STONE,
|
RES_STONE = 14,
|
||||||
RES_SULFUR,
|
RES_SULFUR = 15,
|
||||||
RES_CRYSTAL,
|
RES_CRYSTAL = 16,
|
||||||
RES_GEM,
|
RES_GEM = 17,
|
||||||
RES_GOLD,
|
RES_GOLD = 18,
|
||||||
|
|
||||||
|
ICONS_PER_PLAYER = 19,
|
||||||
|
ICONS_TOTAL = 19 * 9 // 8 players + neutral set at the end
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMapHandler
|
class CMapHandler
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
|
|||||||
// still here? image is missing
|
// still here? image is missing
|
||||||
|
|
||||||
printError(frame, group, "LoadFrame");
|
printError(frame, group, "LoadFrame");
|
||||||
images[group][frame] = std::make_shared<SDLImage>("DEFAULT");
|
images[group][frame] = std::make_shared<SDLImage>("DEFAULT", EImageBlitMode::ALPHA);
|
||||||
}
|
}
|
||||||
else //load from separate file
|
else //load from separate file
|
||||||
{
|
{
|
||||||
auto img = getFromExtraDef(source[group][frame]["file"].String());
|
auto img = getFromExtraDef(source[group][frame]["file"].String());
|
||||||
if(!img)
|
if(!img)
|
||||||
img = std::make_shared<SDLImage>(source[group][frame]);
|
img = std::make_shared<SDLImage>(source[group][frame], EImageBlitMode::ALPHA);
|
||||||
|
|
||||||
images[group][frame] = img;
|
images[group][frame] = img;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -21,6 +21,19 @@ struct SDL_Surface;
|
|||||||
struct SDL_Color;
|
struct SDL_Color;
|
||||||
class ColorFilter;
|
class ColorFilter;
|
||||||
|
|
||||||
|
/// Defines which blit method will be selected when image is used for rendering
|
||||||
|
enum class EImageBlitMode : uint8_t
|
||||||
|
{
|
||||||
|
/// Image can have no transparency and can be only used as background
|
||||||
|
OPAQUE,
|
||||||
|
|
||||||
|
/// Image can have only a single color as transparency and has no semi-transparent areas
|
||||||
|
COLORKEY,
|
||||||
|
|
||||||
|
/// Image might have full alpha transparency range, e.g. shadows
|
||||||
|
ALPHA
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Base class for images, can be used for non-animation pictures as well
|
* Base class for images, can be used for non-animation pictures as well
|
||||||
*/
|
*/
|
||||||
@@ -57,6 +70,7 @@ public:
|
|||||||
virtual void resetPalette() = 0;
|
virtual void resetPalette() = 0;
|
||||||
|
|
||||||
virtual void setAlpha(uint8_t value) = 0;
|
virtual void setAlpha(uint8_t value) = 0;
|
||||||
|
virtual void setBlitMode(EImageBlitMode mode) = 0;
|
||||||
|
|
||||||
//only indexed bitmaps with 7 special colors
|
//only indexed bitmaps with 7 special colors
|
||||||
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette) = 0;
|
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette) = 0;
|
||||||
@@ -69,6 +83,7 @@ public:
|
|||||||
|
|
||||||
/// loads image from specified file. Returns 0-sized images on failure
|
/// loads image from specified file. Returns 0-sized images on failure
|
||||||
static std::shared_ptr<IImage> createFromFile( const std::string & path );
|
static std::shared_ptr<IImage> createFromFile( const std::string & path );
|
||||||
|
static std::shared_ptr<IImage> createFromFile( const std::string & path, EImageBlitMode mode );
|
||||||
|
|
||||||
/// temporary compatibility method. Creates IImage from existing SDL_Surface
|
/// temporary compatibility method. Creates IImage from existing SDL_Surface
|
||||||
/// Surface will be shared, called must still free it with SDL_FreeSurface
|
/// Surface will be shared, called must still free it with SDL_FreeSurface
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ class SDLImageLoader;
|
|||||||
|
|
||||||
std::shared_ptr<IImage> IImage::createFromFile( const std::string & path )
|
std::shared_ptr<IImage> IImage::createFromFile( const std::string & path )
|
||||||
{
|
{
|
||||||
return std::shared_ptr<IImage>(new SDLImage(path));
|
return std::shared_ptr<IImage>(new SDLImage(path, EImageBlitMode::ALPHA));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IImage> IImage::createFromSurface( SDL_Surface * source )
|
std::shared_ptr<IImage> IImage::createFromSurface( SDL_Surface * source )
|
||||||
{
|
{
|
||||||
return std::shared_ptr<IImage>(new SDLImage(source, true));
|
return std::shared_ptr<IImage>(new SDLImage(source, EImageBlitMode::ALPHA));
|
||||||
}
|
}
|
||||||
|
|
||||||
IImage::IImage() = default;
|
IImage::IImage() = default;
|
||||||
@@ -57,9 +57,10 @@ SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group)
|
|||||||
data->loadFrame(frame, group, loader);
|
data->loadFrame(frame, group, loader);
|
||||||
|
|
||||||
savePalette();
|
savePalette();
|
||||||
|
setBlitMode(EImageBlitMode::ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLImage::SDLImage(SDL_Surface * from, bool extraRef)
|
SDLImage::SDLImage(SDL_Surface * from, EImageBlitMode mode)
|
||||||
: surf(nullptr),
|
: surf(nullptr),
|
||||||
margins(0, 0),
|
margins(0, 0),
|
||||||
fullSize(0, 0),
|
fullSize(0, 0),
|
||||||
@@ -70,14 +71,14 @@ SDLImage::SDLImage(SDL_Surface * from, bool extraRef)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
savePalette();
|
savePalette();
|
||||||
|
setBlitMode(mode);
|
||||||
|
|
||||||
if (extraRef)
|
|
||||||
surf->refcount++;
|
surf->refcount++;
|
||||||
fullSize.x = surf->w;
|
fullSize.x = surf->w;
|
||||||
fullSize.y = surf->h;
|
fullSize.y = surf->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLImage::SDLImage(const JsonNode & conf)
|
SDLImage::SDLImage(const JsonNode & conf, EImageBlitMode mode)
|
||||||
: surf(nullptr),
|
: surf(nullptr),
|
||||||
margins(0, 0),
|
margins(0, 0),
|
||||||
fullSize(0, 0),
|
fullSize(0, 0),
|
||||||
@@ -91,6 +92,7 @@ SDLImage::SDLImage(const JsonNode & conf)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
savePalette();
|
savePalette();
|
||||||
|
setBlitMode(mode);
|
||||||
|
|
||||||
const JsonNode & jsonMargins = conf["margins"];
|
const JsonNode & jsonMargins = conf["margins"];
|
||||||
|
|
||||||
@@ -111,7 +113,7 @@ SDLImage::SDLImage(const JsonNode & conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLImage::SDLImage(std::string filename)
|
SDLImage::SDLImage(std::string filename, EImageBlitMode mode)
|
||||||
: surf(nullptr),
|
: surf(nullptr),
|
||||||
margins(0, 0),
|
margins(0, 0),
|
||||||
fullSize(0, 0),
|
fullSize(0, 0),
|
||||||
@@ -127,6 +129,7 @@ SDLImage::SDLImage(std::string filename)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
savePalette();
|
savePalette();
|
||||||
|
setBlitMode(mode);
|
||||||
fullSize.x = surf->w;
|
fullSize.x = surf->w;
|
||||||
fullSize.y = surf->h;
|
fullSize.y = surf->h;
|
||||||
}
|
}
|
||||||
@@ -172,7 +175,7 @@ void SDLImage::draw(SDL_Surface* where, const Rect * dest, const Rect* src) cons
|
|||||||
if (SDL_GetSurfaceAlphaMod(surf, &perSurfaceAlpha) != 0)
|
if (SDL_GetSurfaceAlphaMod(surf, &perSurfaceAlpha) != 0)
|
||||||
logGlobal->error("SDL_GetSurfaceAlphaMod faied! %s", SDL_GetError());
|
logGlobal->error("SDL_GetSurfaceAlphaMod faied! %s", SDL_GetError());
|
||||||
|
|
||||||
if(surf->format->BitsPerPixel == 8 && perSurfaceAlpha == SDL_ALPHA_OPAQUE)
|
if(surf->format->BitsPerPixel == 8 && perSurfaceAlpha == SDL_ALPHA_OPAQUE && blitMode == EImageBlitMode::ALPHA)
|
||||||
{
|
{
|
||||||
CSDL_Ext::blit8bppAlphaTo24bpp(surf, sourceRect, where, destShift);
|
CSDL_Ext::blit8bppAlphaTo24bpp(surf, sourceRect, where, destShift);
|
||||||
}
|
}
|
||||||
@@ -196,7 +199,7 @@ std::shared_ptr<IImage> SDLImage::scaleFast(const Point & size) const
|
|||||||
else
|
else
|
||||||
CSDL_Ext::setDefaultColorKey(scaled);//just in case
|
CSDL_Ext::setDefaultColorKey(scaled);//just in case
|
||||||
|
|
||||||
SDLImage * ret = new SDLImage(scaled, false);
|
SDLImage * ret = new SDLImage(scaled, EImageBlitMode::ALPHA);
|
||||||
|
|
||||||
ret->fullSize.x = (int) round((float)fullSize.x * scaleX);
|
ret->fullSize.x = (int) round((float)fullSize.x * scaleX);
|
||||||
ret->fullSize.y = (int) round((float)fullSize.y * scaleY);
|
ret->fullSize.y = (int) round((float)fullSize.y * scaleY);
|
||||||
@@ -204,6 +207,9 @@ std::shared_ptr<IImage> SDLImage::scaleFast(const Point & size) const
|
|||||||
ret->margins.x = (int) round((float)margins.x * scaleX);
|
ret->margins.x = (int) round((float)margins.x * scaleX);
|
||||||
ret->margins.y = (int) round((float)margins.y * scaleY);
|
ret->margins.y = (int) round((float)margins.y * scaleY);
|
||||||
|
|
||||||
|
// erase our own reference
|
||||||
|
SDL_FreeSurface(scaled);
|
||||||
|
|
||||||
return std::shared_ptr<IImage>(ret);
|
return std::shared_ptr<IImage>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,9 +226,20 @@ void SDLImage::playerColored(PlayerColor player)
|
|||||||
void SDLImage::setAlpha(uint8_t value)
|
void SDLImage::setAlpha(uint8_t value)
|
||||||
{
|
{
|
||||||
CSDL_Ext::setAlpha (surf, value);
|
CSDL_Ext::setAlpha (surf, value);
|
||||||
|
if (value != 255)
|
||||||
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_BLEND);
|
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDLImage::setBlitMode(EImageBlitMode mode)
|
||||||
|
{
|
||||||
|
blitMode = mode;
|
||||||
|
|
||||||
|
if (blitMode != EImageBlitMode::OPAQUE && surf->format->Amask != 0)
|
||||||
|
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_BLEND);
|
||||||
|
else
|
||||||
|
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
void SDLImage::setFlagColor(PlayerColor player)
|
void SDLImage::setFlagColor(PlayerColor player)
|
||||||
{
|
{
|
||||||
if(player < PlayerColor::PLAYER_LIMIT || player==PlayerColor::NEUTRAL)
|
if(player < PlayerColor::PLAYER_LIMIT || player==PlayerColor::NEUTRAL)
|
||||||
|
|||||||
@@ -37,15 +37,17 @@ public:
|
|||||||
//total size including borders
|
//total size including borders
|
||||||
Point fullSize;
|
Point fullSize;
|
||||||
|
|
||||||
|
EImageBlitMode blitMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Load image from def file
|
//Load image from def file
|
||||||
SDLImage(CDefFile *data, size_t frame, size_t group=0);
|
SDLImage(CDefFile *data, size_t frame, size_t group=0);
|
||||||
//Load from bitmap file
|
//Load from bitmap file
|
||||||
SDLImage(std::string filename);
|
SDLImage(std::string filename, EImageBlitMode blitMode);
|
||||||
|
|
||||||
SDLImage(const JsonNode & conf);
|
SDLImage(const JsonNode & conf, EImageBlitMode blitMode);
|
||||||
//Create using existing surface, extraRef will increase refcount on SDL_Surface
|
//Create using existing surface, extraRef will increase refcount on SDL_Surface
|
||||||
SDLImage(SDL_Surface * from, bool extraRef);
|
SDLImage(SDL_Surface * from, EImageBlitMode blitMode);
|
||||||
~SDLImage();
|
~SDLImage();
|
||||||
|
|
||||||
// Keep the original palette, in order to do color switching operation
|
// Keep the original palette, in order to do color switching operation
|
||||||
@@ -69,6 +71,7 @@ public:
|
|||||||
void resetPalette() override;
|
void resetPalette() override;
|
||||||
|
|
||||||
void setAlpha(uint8_t value) override;
|
void setAlpha(uint8_t value) override;
|
||||||
|
void setBlitMode(EImageBlitMode mode) override;
|
||||||
|
|
||||||
void setSpecialPallete(const SpecialPalette & SpecialPalette) override;
|
void setSpecialPallete(const SpecialPalette & SpecialPalette) override;
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
|||||||
parent(Par),
|
parent(Par),
|
||||||
town(Town),
|
town(Town),
|
||||||
str(Str),
|
str(Str),
|
||||||
|
border(nullptr),
|
||||||
|
area(nullptr),
|
||||||
stateTimeCounter(BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
stateTimeCounter(BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
||||||
{
|
{
|
||||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||||
@@ -83,13 +85,9 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
|||||||
|
|
||||||
if(!str->borderName.empty())
|
if(!str->borderName.empty())
|
||||||
border = IImage::createFromFile(str->borderName);
|
border = IImage::createFromFile(str->borderName);
|
||||||
else
|
|
||||||
border = nullptr;
|
|
||||||
|
|
||||||
if(!str->areaName.empty())
|
if(!str->areaName.empty())
|
||||||
area = IImage::createFromFile(str->areaName);
|
area = IImage::createFromFile(str->areaName);
|
||||||
else
|
|
||||||
area = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CBuilding * CBuildingRect::getBuilding()
|
const CBuilding * CBuildingRect::getBuilding()
|
||||||
@@ -565,6 +563,8 @@ CCastleBuildings::CCastleBuildings(const CGTownInstance* Town):
|
|||||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||||
|
|
||||||
background = std::make_shared<CPicture>(town->town->clientInfo.townBackground);
|
background = std::make_shared<CPicture>(town->town->clientInfo.townBackground);
|
||||||
|
background->needRefresh = true;
|
||||||
|
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
||||||
pos.w = background->pos.w;
|
pos.w = background->pos.w;
|
||||||
pos.h = background->pos.h;
|
pos.h = background->pos.h;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user