This commit is contained in:
EmsiaetKadosh
2025-02-05 15:13:02 +08:00
parent edcc095979
commit a086558f2d
19 changed files with 388 additions and 56 deletions
+68 -3
View File
@@ -4,7 +4,10 @@
#pragma once
#include <thread>
#include "def.h"
#include "exception.h"
class Game;
/**
@@ -22,18 +25,50 @@ interface ITickable {
virtual void tick() noexcept = 0;
};
class Renderer : public ITickable {
struct Color {
unsigned int inactive = 0xff777777;
unsigned int active = 0xff000000;
unsigned int hover = 0xff444444;
unsigned int clicked = 0xffeeeeee;
};
inline static constexpr Color TextColor = {
.inactive = 0xff333333,
.active = 0xffeeeeee,
.hover = 0xffeeeeee,
.clicked = 0xff000000
};
class Renderer final : public ITickable {
/**
* 后续可能用不到,可能可删
*/
Game* pGame = nullptr;
friend class Game;
inline static HDC MainDC;
inline static HDC assistDC;
inline static BLENDFUNCTION blendFunction = {
.BlendOp = AC_SRC_OVER,// Only
.BlendFlags = 0,// Must 0
.SourceConstantAlpha = 255,// 预乘
.AlphaFormat = AC_SRC_ALPHA,// Only
};
std::thread::id renderThread = std::this_thread::get_id();
int windowWidth = 0, windowHeight = 0;
int resizeTime = 0;
bool isRendering = false;
void gameStartRender() noexcept {
isRendering = true;
renderThread = std::this_thread::get_id();
}
void gameEndRender() noexcept { isRendering = false; }
public:
static void initialize() noexcept;
explicit Renderer() = default;
explicit Renderer() { Logger.put(L"Renderer created"); }
void resize(int width, int height) noexcept(false);
void setGame(Game& game) noexcept { pGame = &game; }
[[nodiscard]] int getWidth() const noexcept { return windowWidth; }
@@ -47,6 +82,36 @@ public:
resizeTime = -1;
}
}
/**
* @attention 会忽略A透明度值
* @param argb ARGB式颜色
* @return int BGR式颜色
*/
[[nodiscard]] static unsigned int changeColorFormat(const unsigned int argb) { return (argb & 0xff) << 16 | (argb & 0xff00) | (argb & 0xff0000) >> 16; }
void assertRendering() const noexcept(false) { if (!isRendering) throw InvalidOperationException(L"Operation should be done while rendering"); }
void assertRenderThread() const noexcept(false) { if (std::this_thread::get_id() != renderThread) throw InvalidOperationException(L"Operation should be done in render thread"); }
void fill(const int x, const int y, const int w, const int h, const unsigned int color) const {
assertRendering();
//assertRenderThread();
if (color & 0xff000000 == 0) return;
const RECT rect{
.left = x,
.top = y,
.right = x + w,
.bottom = y + h
};
HBRUSH clr = CreateSolidBrush(changeColorFormat(color));
if ((color & 0xff000000) == 0xff000000) FillRect(MainDC, &rect, clr);
else {
FillRect(assistDC, &rect, clr);
AlphaBlend(MainDC, x, y, w, h, assistDC, x, y, w, h, blendFunction);
}
DeleteObject(clr);
}
};
inline static Renderer renderer = Renderer();
extern Renderer renderer;