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)
|
PlatformMemory *const memory)
|
||||||
{
|
{
|
||||||
DTRState *state = (DTRState *)memory->context;
|
DTRState *state = (DTRState *)memory->context;
|
||||||
|
if (input->executableReloaded)
|
||||||
|
{
|
||||||
|
DTR_DEBUG_PROFILE_END();
|
||||||
|
DTR_DEBUG_PROFILE_START();
|
||||||
|
}
|
||||||
|
|
||||||
|
DTR_DEBUG_TIMED_FUNCTION();
|
||||||
if (!memory->isInit)
|
if (!memory->isInit)
|
||||||
{
|
{
|
||||||
DTR_DEBUG_PROFILE_START();
|
DTR_DEBUG_TIMED_BLOCK("DTR_Update Memory Initialisation");
|
||||||
// NOTE(doyle): Do premultiply ourselves
|
// NOTE(doyle): Do premultiply ourselves
|
||||||
stbi_set_unpremultiply_on_load(true);
|
stbi_set_unpremultiply_on_load(true);
|
||||||
stbi_set_flip_vertically_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;
|
int x = 5;
|
||||||
DqnMemBuffer_EndTempRegion(tmp);
|
DqnMemBuffer_EndTempRegion(tmp);
|
||||||
}
|
}
|
||||||
DTR_DEBUG_TIMED_FUNCTION();
|
|
||||||
|
|
||||||
DTRRender_Clear(renderBuffer, DqnV3_3f(0, 0, 0));
|
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;
|
LOCAL_PERSIST f32 rotation = 0;
|
||||||
rotation += input->deltaForFrame * 0.25f;
|
rotation += input->deltaForFrame * 0.25f;
|
||||||
|
|
||||||
|
#if 1
|
||||||
DTRRenderTransform defaultTransform = DTRRender_DefaultTransform();
|
DTRRenderTransform defaultTransform = DTRRender_DefaultTransform();
|
||||||
defaultTransform.rotation = rotation + 45;
|
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);
|
defaultTransform);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Rotating triangle
|
// 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));
|
DTRRender_Text(renderBuffer, state->font, fontP, "hello world!", DqnV4_4f(0, 0, 0, 1));
|
||||||
|
|
||||||
DTRRenderTransform transform = DTRRender_DefaultTransform();
|
DTRRenderTransform transform = DTRRender_DefaultTransform();
|
||||||
transform.rotation = rotation * 2.0f;
|
transform.rotation = 0;
|
||||||
transform.scale = DqnV2_1f(2.0f);
|
transform.scale = DqnV2_1f(2.0f);
|
||||||
|
|
||||||
LOCAL_PERSIST DqnV2 bitmapP = DqnV2_2f(300, 250);
|
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;
|
f32 cAngle = (f32)input->timeNowInS;
|
||||||
DqnV4 color = DqnV4_4f(0.5f + 0.5f * sinf(cAngle), 0.5f + 0.5f * sinf(2.9f * cAngle),
|
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);
|
DTRRender_Bitmap(renderBuffer, &state->bitmap, bitmapP, transform, color);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -83,23 +83,8 @@ void DTRDebug_Update(DTRState *const state,
|
|||||||
debug->totalSetPixels += debug->setPixelsPerFrame;
|
debug->totalSetPixels += debug->setPixelsPerFrame;
|
||||||
debug->totalSetPixels = DQN_MAX(0, debug->totalSetPixels);
|
debug->totalSetPixels = DQN_MAX(0, debug->totalSetPixels);
|
||||||
|
|
||||||
// totalSetPixels
|
DTRDebug_PushText("TotalSetPixels: %'lld", debug->totalSetPixels);
|
||||||
{
|
DTRDebug_PushText("SetPixelsPerFrame: %'lld", debug->setPixelsPerFrame);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// memory
|
// memory
|
||||||
{
|
{
|
||||||
@ -107,6 +92,8 @@ void DTRDebug_Update(DTRState *const state,
|
|||||||
PushMemBufferText("TransBuffer", &memory->transientBuffer);
|
PushMemBufferText("TransBuffer", &memory->transientBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DTRDebug_PushText("SSE2Support: %s", (input->canUseSSE2) ? "true" : "false");
|
||||||
|
|
||||||
debug->setPixelsPerFrame = 0;
|
debug->setPixelsPerFrame = 0;
|
||||||
debug->displayP =
|
debug->displayP =
|
||||||
DqnV2_2i(0, debug->renderBuffer->height + globalDebug.displayYOffset);
|
DqnV2_2i(0, debug->renderBuffer->height + globalDebug.displayYOffset);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
#define DTR_DEBUG 1
|
#define DTR_DEBUG 1
|
||||||
#ifdef DTR_DEBUG
|
#ifdef DTR_DEBUG
|
||||||
#define DTR_DEBUG_RENDER 0
|
#define DTR_DEBUG_RENDER 1
|
||||||
|
|
||||||
#define DTR_DEBUG_PROFILING 1
|
#define DTR_DEBUG_PROFILING 1
|
||||||
#ifdef DTR_DEBUG_PROFILING
|
#ifdef DTR_DEBUG_PROFILING
|
||||||
|
@ -72,6 +72,7 @@ typedef struct PlatformInput
|
|||||||
f32 deltaForFrame;
|
f32 deltaForFrame;
|
||||||
f64 timeNowInS;
|
f64 timeNowInS;
|
||||||
bool executableReloaded;
|
bool executableReloaded;
|
||||||
|
bool canUseSSE2;
|
||||||
|
|
||||||
PlatformAPI api;
|
PlatformAPI api;
|
||||||
union {
|
union {
|
||||||
|
@ -160,9 +160,10 @@ FILE_SCOPE inline void SetPixel(PlatformRenderBuffer *const renderBuffer, const
|
|||||||
destB = 255;
|
destB = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 pixel = ((u32)(destR) << 16 |
|
u32 pixel = // ((u32)(destA) << 24 |
|
||||||
|
(u32)(destR) << 16 |
|
||||||
(u32)(destG) << 8 |
|
(u32)(destG) << 8 |
|
||||||
(u32)(destB) << 0);
|
(u32)(destB) << 0;
|
||||||
bitmapPtr[x + (y * pitchInU32)] = pixel;
|
bitmapPtr[x + (y * pitchInU32)] = pixel;
|
||||||
|
|
||||||
globalDebug.setPixelsPerFrame++;
|
globalDebug.setPixelsPerFrame++;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
|
|
||||||
#define DTRRENDER_INV_255 0.00392156862f;
|
#define DTRRENDER_INV_255 1.0f/255.0f
|
||||||
|
|
||||||
typedef struct PlatformRenderBuffer PlatformRenderBuffer;
|
typedef struct PlatformRenderBuffer PlatformRenderBuffer;
|
||||||
typedef struct DTRBitmap DTRBitmap;
|
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) &&
|
DQN_ASSERT(DqnMemBuffer_Init(&globalPlatformMemory.permanentBuffer, DQN_MEGABYTE(1), true, 4) &&
|
||||||
DqnMemBuffer_Init(&globalPlatformMemory.transientBuffer, 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 platformAPI = {};
|
||||||
platformAPI.FileOpen = Platform_FileOpen;
|
platformAPI.FileOpen = Platform_FileOpen;
|
||||||
platformAPI.FileRead = Platform_FileRead;
|
platformAPI.FileRead = Platform_FileRead;
|
||||||
platformAPI.FileClose = Platform_FileClose;
|
platformAPI.FileClose = Platform_FileClose;
|
||||||
platformAPI.Print = Platform_Print;
|
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)
|
while (globalRunning)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@ -523,7 +530,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
f64 startFrameTimeInS = DqnTime_NowInS();
|
f64 startFrameTimeInS = DqnTime_NowInS();
|
||||||
|
|
||||||
PlatformInput platformInput = {};
|
|
||||||
FILETIME lastWriteTime = Win32GetLastWriteTime(dllPath);
|
FILETIME lastWriteTime = Win32GetLastWriteTime(dllPath);
|
||||||
if (CompareFileTime(&lastWriteTime, &dllCode.lastWriteTime) != 0)
|
if (CompareFileTime(&lastWriteTime, &dllCode.lastWriteTime) != 0)
|
||||||
{
|
{
|
||||||
@ -535,7 +541,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
{
|
{
|
||||||
platformInput.timeNowInS = DqnTime_NowInS();
|
platformInput.timeNowInS = DqnTime_NowInS();
|
||||||
platformInput.deltaForFrame = (f32)frameTimeInS;
|
platformInput.deltaForFrame = (f32)frameTimeInS;
|
||||||
platformInput.api = platformAPI;
|
|
||||||
Win32ProcessMessages(mainWindow, &platformInput);
|
Win32ProcessMessages(mainWindow, &platformInput);
|
||||||
|
|
||||||
PlatformRenderBuffer platformBuffer = {};
|
PlatformRenderBuffer platformBuffer = {};
|
||||||
|
Loading…
Reference in New Issue
Block a user