Fix color modulation alpha bug
Phasing color modulation over time would make bitmaps become transparent and show layers underneath even if alpha was set to 1. This was caused by the precomputed 1/255 calculation #defined in DTRRender which was missing the precision required so floating point errors began to accumulate causing erroneous colours.
This commit is contained in:
parent
b6daf43f33
commit
a25b50c501
@ -1036,9 +1036,16 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
PlatformMemory *const memory)
|
||||
{
|
||||
DTRState *state = (DTRState *)memory->context;
|
||||
if (input->executableReloaded)
|
||||
{
|
||||
DTR_DEBUG_PROFILE_END();
|
||||
DTR_DEBUG_PROFILE_START();
|
||||
}
|
||||
|
||||
DTR_DEBUG_TIMED_FUNCTION();
|
||||
if (!memory->isInit)
|
||||
{
|
||||
DTR_DEBUG_PROFILE_START();
|
||||
DTR_DEBUG_TIMED_BLOCK("DTR_Update Memory Initialisation");
|
||||
// NOTE(doyle): Do premultiply ourselves
|
||||
stbi_set_unpremultiply_on_load(true);
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
@ -1061,7 +1068,6 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
int x = 5;
|
||||
DqnMemBuffer_EndTempRegion(tmp);
|
||||
}
|
||||
DTR_DEBUG_TIMED_FUNCTION();
|
||||
|
||||
DTRRender_Clear(renderBuffer, DqnV3_3f(0, 0, 0));
|
||||
|
||||
@ -1087,10 +1093,12 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
LOCAL_PERSIST f32 rotation = 0;
|
||||
rotation += input->deltaForFrame * 0.25f;
|
||||
|
||||
#if 1
|
||||
DTRRenderTransform defaultTransform = DTRRender_DefaultTransform();
|
||||
defaultTransform.rotation = rotation + 45;
|
||||
DTRRender_Rectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 20.0f), DqnV4_4f(0, 1.0f, 1.0f, 1.0f),
|
||||
DTRRender_Rectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 100.0f), DqnV4_4f(0, 1.0f, 1.0f, 1.0f),
|
||||
defaultTransform);
|
||||
#endif
|
||||
|
||||
// Rotating triangle
|
||||
{
|
||||
@ -1104,7 +1112,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
DTRRender_Text(renderBuffer, state->font, fontP, "hello world!", DqnV4_4f(0, 0, 0, 1));
|
||||
|
||||
DTRRenderTransform transform = DTRRender_DefaultTransform();
|
||||
transform.rotation = rotation * 2.0f;
|
||||
transform.rotation = 0;
|
||||
transform.scale = DqnV2_1f(2.0f);
|
||||
|
||||
LOCAL_PERSIST DqnV2 bitmapP = DqnV2_2f(300, 250);
|
||||
@ -1112,7 +1120,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
|
||||
f32 cAngle = (f32)input->timeNowInS;
|
||||
DqnV4 color = DqnV4_4f(0.5f + 0.5f * sinf(cAngle), 0.5f + 0.5f * sinf(2.9f * cAngle),
|
||||
0.5f + 0.5f * cosf(9.9f * cAngle), 1.0f);
|
||||
0.5f + 0.5f * cosf(10.0f * cAngle), 1.0f);
|
||||
DTRRender_Bitmap(renderBuffer, &state->bitmap, bitmapP, transform, color);
|
||||
|
||||
#else
|
||||
|
@ -83,23 +83,8 @@ void DTRDebug_Update(DTRState *const state,
|
||||
debug->totalSetPixels += debug->setPixelsPerFrame;
|
||||
debug->totalSetPixels = DQN_MAX(0, debug->totalSetPixels);
|
||||
|
||||
// totalSetPixels
|
||||
{
|
||||
char str[128] = {};
|
||||
Dqn_sprintf(str, "%s: %'lld", "TotalSetPixels", debug->totalSetPixels);
|
||||
DTRRender_Text(debug->renderBuffer, *debug->font, debug->displayP, str,
|
||||
debug->displayColor);
|
||||
debug->displayP.y += globalDebug.displayYOffset;
|
||||
}
|
||||
|
||||
// setPixelsPerFrame
|
||||
{
|
||||
char str[128] = {};
|
||||
Dqn_sprintf(str, "%s: %'lld", "SetPixelsPerFrame", debug->setPixelsPerFrame);
|
||||
DTRRender_Text(debug->renderBuffer, *debug->font, debug->displayP, str,
|
||||
debug->displayColor);
|
||||
debug->displayP.y += globalDebug.displayYOffset;
|
||||
}
|
||||
DTRDebug_PushText("TotalSetPixels: %'lld", debug->totalSetPixels);
|
||||
DTRDebug_PushText("SetPixelsPerFrame: %'lld", debug->setPixelsPerFrame);
|
||||
|
||||
// memory
|
||||
{
|
||||
@ -107,6 +92,8 @@ void DTRDebug_Update(DTRState *const state,
|
||||
PushMemBufferText("TransBuffer", &memory->transientBuffer);
|
||||
}
|
||||
|
||||
DTRDebug_PushText("SSE2Support: %s", (input->canUseSSE2) ? "true" : "false");
|
||||
|
||||
debug->setPixelsPerFrame = 0;
|
||||
debug->displayP =
|
||||
DqnV2_2i(0, debug->renderBuffer->height + globalDebug.displayYOffset);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "dqn.h"
|
||||
#define DTR_DEBUG 1
|
||||
#ifdef DTR_DEBUG
|
||||
#define DTR_DEBUG_RENDER 0
|
||||
#define DTR_DEBUG_RENDER 1
|
||||
|
||||
#define DTR_DEBUG_PROFILING 1
|
||||
#ifdef DTR_DEBUG_PROFILING
|
||||
|
@ -72,6 +72,7 @@ typedef struct PlatformInput
|
||||
f32 deltaForFrame;
|
||||
f64 timeNowInS;
|
||||
bool executableReloaded;
|
||||
bool canUseSSE2;
|
||||
|
||||
PlatformAPI api;
|
||||
union {
|
||||
|
@ -160,9 +160,10 @@ FILE_SCOPE inline void SetPixel(PlatformRenderBuffer *const renderBuffer, const
|
||||
destB = 255;
|
||||
}
|
||||
|
||||
u32 pixel = ((u32)(destR) << 16 |
|
||||
u32 pixel = // ((u32)(destA) << 24 |
|
||||
(u32)(destR) << 16 |
|
||||
(u32)(destG) << 8 |
|
||||
(u32)(destB) << 0);
|
||||
(u32)(destB) << 0;
|
||||
bitmapPtr[x + (y * pitchInU32)] = pixel;
|
||||
|
||||
globalDebug.setPixelsPerFrame++;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "dqn.h"
|
||||
|
||||
#define DTRRENDER_INV_255 0.00392156862f;
|
||||
#define DTRRENDER_INV_255 1.0f/255.0f
|
||||
|
||||
typedef struct PlatformRenderBuffer PlatformRenderBuffer;
|
||||
typedef struct DTRBitmap DTRBitmap;
|
||||
|
@ -500,22 +500,29 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Update Loop
|
||||
// Platform Data Pre-amble
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DQN_ASSERT(DqnMemBuffer_Init(&globalPlatformMemory.permanentBuffer, DQN_MEGABYTE(1), true, 4) &&
|
||||
DqnMemBuffer_Init(&globalPlatformMemory.transientBuffer, DQN_MEGABYTE(1), true, 4));
|
||||
|
||||
const f32 TARGET_FRAMES_PER_S = 60.0f;
|
||||
f32 targetSecondsPerFrame = 1 / TARGET_FRAMES_PER_S;
|
||||
f64 frameTimeInS = 0.0f;
|
||||
globalRunning = true;
|
||||
|
||||
PlatformAPI platformAPI = {};
|
||||
platformAPI.FileOpen = Platform_FileOpen;
|
||||
platformAPI.FileRead = Platform_FileRead;
|
||||
platformAPI.FileClose = Platform_FileClose;
|
||||
platformAPI.Print = Platform_Print;
|
||||
|
||||
PlatformInput platformInput = {};
|
||||
platformInput.canUseSSE2 = IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
|
||||
platformInput.api = platformAPI;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Update Loop
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
const f32 TARGET_FRAMES_PER_S = 60.0f;
|
||||
f32 targetSecondsPerFrame = 1 / TARGET_FRAMES_PER_S;
|
||||
f64 frameTimeInS = 0.0f;
|
||||
globalRunning = true;
|
||||
|
||||
while (globalRunning)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -523,7 +530,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
f64 startFrameTimeInS = DqnTime_NowInS();
|
||||
|
||||
PlatformInput platformInput = {};
|
||||
FILETIME lastWriteTime = Win32GetLastWriteTime(dllPath);
|
||||
if (CompareFileTime(&lastWriteTime, &dllCode.lastWriteTime) != 0)
|
||||
{
|
||||
@ -535,7 +541,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
{
|
||||
platformInput.timeNowInS = DqnTime_NowInS();
|
||||
platformInput.deltaForFrame = (f32)frameTimeInS;
|
||||
platformInput.api = platformAPI;
|
||||
Win32ProcessMessages(mainWindow, &platformInput);
|
||||
|
||||
PlatformRenderBuffer platformBuffer = {};
|
||||
|
Loading…
Reference in New Issue
Block a user