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:
Doyle Thai 2017-05-19 20:45:18 +10:00
parent b6daf43f33
commit a25b50c501
7 changed files with 36 additions and 34 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -72,6 +72,7 @@ typedef struct PlatformInput
f32 deltaForFrame;
f64 timeNowInS;
bool executableReloaded;
bool canUseSSE2;
PlatformAPI api;
union {

View File

@ -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++;

View File

@ -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;

View File

@ -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 = {};