104 lines
2.6 KiB
C++
104 lines
2.6 KiB
C++
|
inline s32 RoundFloatToInt(float value)
|
||
|
{
|
||
|
return static_cast<s32>(value + 0.5);
|
||
|
}
|
||
|
|
||
|
struct V4: public ImVec4
|
||
|
{
|
||
|
using ImVec4::ImVec4;
|
||
|
float &a = ImVec4::w;
|
||
|
float &r = ImVec4::x;
|
||
|
float &g = ImVec4::y;
|
||
|
float &b = ImVec4::z;
|
||
|
};
|
||
|
|
||
|
inline u32 V4ToARGB(V4 c)
|
||
|
{
|
||
|
u32 result = ((RoundFloatToInt(c.a * 255.0) & 0xff) << 24
|
||
|
| (RoundFloatToInt(c.r * 255.0) & 0xff) << 16
|
||
|
| (RoundFloatToInt(c.g * 255.0) & 0xff) << 8
|
||
|
| (RoundFloatToInt(c.b * 255.0) & 0xff) << 0);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
struct OffscreenBuffer
|
||
|
{
|
||
|
s32 width;
|
||
|
s32 height;
|
||
|
u8 *pixels;
|
||
|
s32 pitch;
|
||
|
const int BytesPerPixel;
|
||
|
};
|
||
|
|
||
|
inline void PutPixelUnchecked(OffscreenBuffer *buffer, s32 x, s32 y, V4 color)
|
||
|
{
|
||
|
u32 *pixel = reinterpret_cast<u32 *>(buffer->pixels
|
||
|
+ y * buffer->pitch
|
||
|
+ x * buffer->BytesPerPixel);
|
||
|
*pixel = V4ToARGB(color);
|
||
|
}
|
||
|
|
||
|
inline void PutPixel(OffscreenBuffer *buffer, s32 x, s32 y, V4 color)
|
||
|
{
|
||
|
if (x >= 0 && x < buffer->width && y >= 0 && y < buffer->height)
|
||
|
{
|
||
|
PutPixelUnchecked(buffer, x, y, color);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DrawRectangle(OffscreenBuffer *buffer,
|
||
|
float realMinX, float realMinY,
|
||
|
float realMaxX, float realMaxY,
|
||
|
V4 color)
|
||
|
|
||
|
{
|
||
|
s32 minX = RoundFloatToInt(realMinX);
|
||
|
s32 minY = RoundFloatToInt(realMinY);
|
||
|
s32 maxX = RoundFloatToInt(realMaxX);
|
||
|
s32 maxY = RoundFloatToInt(realMaxY);
|
||
|
|
||
|
if (minX < 0)
|
||
|
minX = 0;
|
||
|
|
||
|
if (minY < 0)
|
||
|
minY = 0;
|
||
|
|
||
|
if (maxX > buffer->width)
|
||
|
maxX = buffer->width;
|
||
|
|
||
|
if (maxY > buffer->height)
|
||
|
maxY = buffer->height;
|
||
|
|
||
|
|
||
|
u8 *row = buffer->pixels + minY * buffer->pitch;
|
||
|
|
||
|
for (s32 y = minY; y < maxY; ++y)
|
||
|
{
|
||
|
u32 *dstPixel = reinterpret_cast<u32 *>(row + minX * buffer->BytesPerPixel);
|
||
|
|
||
|
for (s32 x = minX; x < maxX; ++x)
|
||
|
{
|
||
|
float a = color.a;
|
||
|
float srcR = color.r * 255.0;
|
||
|
float srcG = color.g * 255.0;
|
||
|
float srcB = color.b * 255.0;
|
||
|
|
||
|
float dstR = ((*dstPixel >> 16) & 0xff);
|
||
|
float dstG = ((*dstPixel >> 8) & 0xff);
|
||
|
float dstB = ((*dstPixel >> 0) & 0xff);
|
||
|
|
||
|
dstR = (1 - a) * dstR + a * srcR;
|
||
|
dstG = (1 - a) * dstG + a * srcG;
|
||
|
dstB = (1 - a) * dstB + a * srcB;
|
||
|
|
||
|
*dstPixel = (RoundFloatToInt(dstR) << 16 |
|
||
|
RoundFloatToInt(dstG) << 8 |
|
||
|
RoundFloatToInt(dstB) << 0);
|
||
|
|
||
|
++dstPixel;
|
||
|
}
|
||
|
|
||
|
row += buffer->pitch;
|
||
|
}
|
||
|
}
|