mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Use SDL BlitMode's to speed up image rendering
This commit is contained in:
parent
40413ee6be
commit
def1e35836
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
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <numeric>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
//The only available version is 3, as of Boost 1.50
|
||||
#include <boost/version.hpp>
|
||||
|
@ -162,6 +162,7 @@ void MapRendererTerrain::renderTile(const IMapRendererContext & context, Canvas
|
||||
image->shiftPalette(242, 14, context.terrainImageIndex(14));
|
||||
}
|
||||
|
||||
image->setBlitMode(EImageBlitMode::OPAQUE);
|
||||
target.draw(image, Point(0, 0));
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ public:
|
||||
/// returns animation frame for terrain
|
||||
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
|
||||
virtual Point getTileSize() const = 0;
|
||||
// /// returns size of ouput tile, in pixels. 32x32 for "standard" map, may be smaller for world view mode
|
||||
// virtual Point getTileSize() const = 0;
|
||||
|
||||
/// if true, map grid should be visible on map
|
||||
virtual bool showGrid() const = 0;
|
||||
|
@ -189,14 +189,14 @@ size_t MapRendererContext::terrainImageIndex(size_t groupSize) const
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
Point MapRendererContext::getTileSize() const
|
||||
{
|
||||
return Point(32, 32);
|
||||
}
|
||||
//Point MapRendererContext::getTileSize() const
|
||||
//{
|
||||
// return Point(32, 32);
|
||||
//}
|
||||
|
||||
bool MapRendererContext::showGrid() const
|
||||
{
|
||||
return true; // settings["gameTweaks"]["showGrid"].Bool();
|
||||
return settings["gameTweaks"]["showGrid"].Bool();
|
||||
}
|
||||
|
||||
bool MapRendererContext::showVisitable() const
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
double objectTransparency(ObjectInstanceID objectID) const override;
|
||||
size_t objectImageIndex(ObjectInstanceID objectID, 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 showVisitable() const override;
|
||||
bool showBlockable() const override;
|
||||
|
@ -41,27 +41,31 @@ class IImage;
|
||||
class CMapHandler;
|
||||
class IMapObjectObserver;
|
||||
|
||||
// from VwSymbol.def
|
||||
enum class EWorldViewIcon
|
||||
{
|
||||
TOWN = 0,
|
||||
HERO,
|
||||
ARTIFACT,
|
||||
TELEPORT,
|
||||
GATE,
|
||||
MINE_WOOD,
|
||||
MINE_MERCURY,
|
||||
MINE_STONE,
|
||||
MINE_SULFUR,
|
||||
MINE_CRYSTAL,
|
||||
MINE_GEM,
|
||||
MINE_GOLD,
|
||||
RES_WOOD,
|
||||
RES_MERCURY,
|
||||
RES_STONE,
|
||||
RES_SULFUR,
|
||||
RES_CRYSTAL,
|
||||
RES_GEM,
|
||||
RES_GOLD,
|
||||
HERO = 1,
|
||||
ARTIFACT = 2,
|
||||
TELEPORT = 3,
|
||||
GATE = 4,
|
||||
MINE_WOOD = 5,
|
||||
MINE_MERCURY = 6,
|
||||
MINE_STONE = 7,
|
||||
MINE_SULFUR = 8,
|
||||
MINE_CRYSTAL = 9,
|
||||
MINE_GEM = 10,
|
||||
MINE_GOLD = 11,
|
||||
RES_WOOD = 12,
|
||||
RES_MERCURY = 13,
|
||||
RES_STONE = 14,
|
||||
RES_SULFUR = 15,
|
||||
RES_CRYSTAL = 16,
|
||||
RES_GEM = 17,
|
||||
RES_GOLD = 18,
|
||||
|
||||
ICONS_PER_PLAYER = 19,
|
||||
ICONS_TOTAL = 19 * 9 // 8 players + neutral set at the end
|
||||
};
|
||||
|
||||
class CMapHandler
|
||||
|
@ -69,13 +69,13 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
|
||||
// still here? image is missing
|
||||
|
||||
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
|
||||
{
|
||||
auto img = getFromExtraDef(source[group][frame]["file"].String());
|
||||
if(!img)
|
||||
img = std::make_shared<SDLImage>(source[group][frame]);
|
||||
img = std::make_shared<SDLImage>(source[group][frame], EImageBlitMode::ALPHA);
|
||||
|
||||
images[group][frame] = img;
|
||||
return true;
|
||||
|
@ -21,6 +21,19 @@ struct SDL_Surface;
|
||||
struct SDL_Color;
|
||||
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
|
||||
*/
|
||||
@ -57,6 +70,7 @@ public:
|
||||
virtual void resetPalette() = 0;
|
||||
|
||||
virtual void setAlpha(uint8_t value) = 0;
|
||||
virtual void setBlitMode(EImageBlitMode mode) = 0;
|
||||
|
||||
//only indexed bitmaps with 7 special colors
|
||||
virtual void setSpecialPallete(const SpecialPalette & SpecialPalette) = 0;
|
||||
@ -69,6 +83,7 @@ public:
|
||||
|
||||
/// 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, EImageBlitMode mode );
|
||||
|
||||
/// temporary compatibility method. Creates IImage from existing SDL_Surface
|
||||
/// 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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
return std::shared_ptr<IImage>(new SDLImage(source, true));
|
||||
return std::shared_ptr<IImage>(new SDLImage(source, EImageBlitMode::ALPHA));
|
||||
}
|
||||
|
||||
IImage::IImage() = default;
|
||||
@ -57,9 +57,10 @@ SDLImage::SDLImage(CDefFile * data, size_t frame, size_t group)
|
||||
data->loadFrame(frame, group, loader);
|
||||
|
||||
savePalette();
|
||||
setBlitMode(EImageBlitMode::ALPHA);
|
||||
}
|
||||
|
||||
SDLImage::SDLImage(SDL_Surface * from, bool extraRef)
|
||||
SDLImage::SDLImage(SDL_Surface * from, EImageBlitMode mode)
|
||||
: surf(nullptr),
|
||||
margins(0, 0),
|
||||
fullSize(0, 0),
|
||||
@ -70,14 +71,14 @@ SDLImage::SDLImage(SDL_Surface * from, bool extraRef)
|
||||
return;
|
||||
|
||||
savePalette();
|
||||
setBlitMode(mode);
|
||||
|
||||
if (extraRef)
|
||||
surf->refcount++;
|
||||
surf->refcount++;
|
||||
fullSize.x = surf->w;
|
||||
fullSize.y = surf->h;
|
||||
}
|
||||
|
||||
SDLImage::SDLImage(const JsonNode & conf)
|
||||
SDLImage::SDLImage(const JsonNode & conf, EImageBlitMode mode)
|
||||
: surf(nullptr),
|
||||
margins(0, 0),
|
||||
fullSize(0, 0),
|
||||
@ -91,6 +92,7 @@ SDLImage::SDLImage(const JsonNode & conf)
|
||||
return;
|
||||
|
||||
savePalette();
|
||||
setBlitMode(mode);
|
||||
|
||||
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),
|
||||
margins(0, 0),
|
||||
fullSize(0, 0),
|
||||
@ -127,6 +129,7 @@ SDLImage::SDLImage(std::string filename)
|
||||
else
|
||||
{
|
||||
savePalette();
|
||||
setBlitMode(mode);
|
||||
fullSize.x = surf->w;
|
||||
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)
|
||||
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);
|
||||
}
|
||||
@ -196,7 +199,7 @@ std::shared_ptr<IImage> SDLImage::scaleFast(const Point & size) const
|
||||
else
|
||||
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.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.y = (int) round((float)margins.y * scaleY);
|
||||
|
||||
// erase our own reference
|
||||
SDL_FreeSurface(scaled);
|
||||
|
||||
return std::shared_ptr<IImage>(ret);
|
||||
}
|
||||
|
||||
@ -220,7 +226,18 @@ void SDLImage::playerColored(PlayerColor player)
|
||||
void SDLImage::setAlpha(uint8_t value)
|
||||
{
|
||||
CSDL_Ext::setAlpha (surf, value);
|
||||
SDL_SetSurfaceBlendMode(surf, SDL_BLENDMODE_BLEND);
|
||||
if (value != 255)
|
||||
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)
|
||||
|
@ -37,15 +37,17 @@ public:
|
||||
//total size including borders
|
||||
Point fullSize;
|
||||
|
||||
EImageBlitMode blitMode;
|
||||
|
||||
public:
|
||||
//Load image from def file
|
||||
SDLImage(CDefFile *data, size_t frame, size_t group=0);
|
||||
//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
|
||||
SDLImage(SDL_Surface * from, bool extraRef);
|
||||
SDLImage(SDL_Surface * from, EImageBlitMode blitMode);
|
||||
~SDLImage();
|
||||
|
||||
// Keep the original palette, in order to do color switching operation
|
||||
@ -69,6 +71,7 @@ public:
|
||||
void resetPalette() override;
|
||||
|
||||
void setAlpha(uint8_t value) override;
|
||||
void setBlitMode(EImageBlitMode mode) override;
|
||||
|
||||
void setSpecialPallete(const SpecialPalette & SpecialPalette) override;
|
||||
|
||||
|
@ -61,6 +61,8 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
||||
parent(Par),
|
||||
town(Town),
|
||||
str(Str),
|
||||
border(nullptr),
|
||||
area(nullptr),
|
||||
stateTimeCounter(BUILD_ANIMATION_FINISHED_TIMEPOINT)
|
||||
{
|
||||
addUsedEvents(LCLICK | RCLICK | HOVER);
|
||||
@ -83,13 +85,9 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
|
||||
|
||||
if(!str->borderName.empty())
|
||||
border = IImage::createFromFile(str->borderName);
|
||||
else
|
||||
border = nullptr;
|
||||
|
||||
if(!str->areaName.empty())
|
||||
area = IImage::createFromFile(str->areaName);
|
||||
else
|
||||
area = nullptr;
|
||||
}
|
||||
|
||||
const CBuilding * CBuildingRect::getBuilding()
|
||||
@ -565,6 +563,8 @@ CCastleBuildings::CCastleBuildings(const CGTownInstance* Town):
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
background = std::make_shared<CPicture>(town->town->clientInfo.townBackground);
|
||||
background->needRefresh = true;
|
||||
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
||||
pos.w = background->pos.w;
|
||||
pos.h = background->pos.h;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user