Add bilinear filtering for bitmaps

This commit is contained in:
Doyle Thai 2017-05-17 19:34:26 +10:00
parent ceb37ec4b0
commit e2ac14ffb7
3 changed files with 114 additions and 30 deletions

View File

@ -183,11 +183,18 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
state = (DTRState *)memory->context; state = (DTRState *)memory->context;
BitmapFontCreate(input->api, memory, &state->font, "Roboto-bold.ttf", BitmapFontCreate(input->api, memory, &state->font, "Roboto-bold.ttf",
DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 16); DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 16);
BitmapLoad(input->api, &state->bitmap, "lune_logo.png", BitmapLoad(input->api, &state->bitmap, "tree00.bmp",
&memory->transientBuffer); &memory->transientBuffer);
DTRBitmap test = {};
DqnTempBuffer tmp = DqnMemBuffer_BeginTempRegion(&memory->permanentBuffer);
BitmapLoad(input->api, &test, "byte_read_check.bmp",
&memory->transientBuffer);
int x = 5;
DqnMemBuffer_EndTempRegion(tmp);
} }
DTRRender_Clear(renderBuffer, DqnV3_3f(0, 0, 0)); DTRRender_Clear(renderBuffer, DqnV3_3f(128, 128, 128));
DqnV4 colorRed = DqnV4_4i(180, 0, 0, 255); DqnV4 colorRed = DqnV4_4i(180, 0, 0, 255);
DqnV2i bufferMidP = DqnV2i bufferMidP =
DqnV2i_2f(renderBuffer->width * 0.5f, renderBuffer->height * 0.5f); DqnV2i_2f(renderBuffer->width * 0.5f, renderBuffer->height * 0.5f);
@ -210,17 +217,22 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
DqnV4 colorRedHalfA = DqnV4_4i(255, 0, 0, 64); DqnV4 colorRedHalfA = DqnV4_4i(255, 0, 0, 64);
LOCAL_PERSIST f32 rotation = 0; LOCAL_PERSIST f32 rotation = 0;
rotation += input->deltaForFrame * 0.25f; rotation += input->deltaForFrame * 0.25f;
DTRRender_Triangle(renderBuffer, t3[0], t3[1], t3[2], colorRedHalfA, DTRRender_Triangle(renderBuffer, t3[0], t3[1], t3[2], colorRedHalfA, DqnV2_1f(1.0f), rotation,
DqnV2_1f(1.0f), rotation, DqnV2_2f(0.33f, 0.33f)); DqnV2_2f(0.33f, 0.33f));
DTRRender_Rectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 20.0f), DTRRender_Rectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 20.0f), colorRed,
colorRed, DqnV2_1f(1.0f), 45 + rotation); DqnV2_1f(1.0f), 45 + rotation);
DqnV2 fontP = DqnV2_2i(200, 180); DqnV2 fontP = DqnV2_2i(200, 180);
DTRRender_Text(renderBuffer, state->font, fontP, "hello world!"); DTRRender_Text(renderBuffer, state->font, fontP, "hello world!");
DTRRenderTransform transform = DTRRender_DefaultTransform(); DTRRenderTransform transform = DTRRender_DefaultTransform();
transform.rotation = rotation; transform.rotation = rotation * 2.0f;
DTRRender_Bitmap(renderBuffer, &state->bitmap, DqnV2i_2i(200, 300), transform); transform.scale = DqnV2_1f(5.0f);
LOCAL_PERSIST DqnV2 bitmapP = DqnV2_2f(300, 250);
bitmapP.x += 3.0f * sinf((f32)input->timeNowInS * 0.5f);
DTRRender_Bitmap(renderBuffer, &state->bitmap, bitmapP, transform);
DTRDebug_Update(state, renderBuffer, input, memory); DTRDebug_Update(state, renderBuffer, input, memory);
} }

View File

@ -53,9 +53,28 @@ FILE_SCOPE inline void SetPixel(PlatformRenderBuffer *const renderBuffer,
f32 destG = newG + (invANorm * srcG); f32 destG = newG + (invANorm * srcG);
f32 destB = newB + (invANorm * srcB); f32 destB = newB + (invANorm * srcB);
DQN_ASSERT(destR >= 0 && destR <= 255.0f); DQN_ASSERT(destR >= 0);
DQN_ASSERT(destG >= 0 && destG <= 255.0f); DQN_ASSERT(destG >= 0);
DQN_ASSERT(destB >= 0 && destB <= 255.0f); DQN_ASSERT(destB >= 0);
const f32 COLOR_EPSILON = 0.1f;
if (destR > 255.0f)
{
DQN_ASSERT((destR - 255.0f) < COLOR_EPSILON);
destR = 255;
}
if (destG > 255.0f)
{
DQN_ASSERT((destG - 255.0f) < COLOR_EPSILON);
destG = 255;
}
if (destB > 255.0f)
{
DQN_ASSERT((destB - 255.0f) < COLOR_EPSILON);
destB = 255;
}
u32 pixel = ((u32)(destR) << 16 | u32 pixel = ((u32)(destR) << 16 |
(u32)(destG) << 8 | (u32)(destG) << 8 |
@ -599,7 +618,7 @@ void DTRRender_Triangle(PlatformRenderBuffer *const renderBuffer, DqnV2 p1,
} }
void DTRRender_Bitmap(PlatformRenderBuffer *const renderBuffer, void DTRRender_Bitmap(PlatformRenderBuffer *const renderBuffer,
DTRBitmap *const bitmap, DqnV2i pos, DTRBitmap *const bitmap, DqnV2 pos,
DTRRenderTransform transform) DTRRenderTransform transform)
{ {
if (!bitmap || !bitmap->memory || !renderBuffer) return; if (!bitmap || !bitmap->memory || !renderBuffer) return;
@ -607,7 +626,7 @@ void DTRRender_Bitmap(PlatformRenderBuffer *const renderBuffer,
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Transform vertexes // Transform vertexes
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
DqnV2 min = DqnV2_V2i(pos); DqnV2 min = pos;
DqnV2 max = min + DqnV2_V2i(bitmap->dim); DqnV2 max = min + DqnV2_V2i(bitmap->dim);
DTRDebug_PushText("OldRect: (%5.2f, %5.2f), (%5.2f, %5.2f)", min.x, min.y, max.x, max.y); DTRDebug_PushText("OldRect: (%5.2f, %5.2f), (%5.2f, %5.2f)", min.x, min.y, max.x, max.y);
@ -632,7 +651,7 @@ void DTRRender_Bitmap(PlatformRenderBuffer *const renderBuffer,
DTRDebug_PushText("ClippedSize: (%5.2f, %5.2f)", clippedSize.w, clippedSize.h); DTRDebug_PushText("ClippedSize: (%5.2f, %5.2f)", clippedSize.w, clippedSize.h);
DTRDebug_PushText("DrawRect: (%5.2f, %5.2f), (%5.2f, %5.2f)", drawRect.min.x, drawRect.min.y, drawRect.max.x, drawRect.max.y); DTRDebug_PushText("DrawRect: (%5.2f, %5.2f), (%5.2f, %5.2f)", drawRect.min.x, drawRect.min.y, drawRect.max.x, drawRect.max.y);
const i32 pitch = bitmap->dim.w * bitmap->bytesPerPixel; const i32 pitch = bitmap->dim.w * bitmap->bytesPerPixel;
u32 *const pixelPtr = (u32 *)bitmap->memory; u8 *const bitmapPtr = (u8 *)bitmap->memory;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Setup Texture Mapping // Setup Texture Mapping
@ -686,24 +705,77 @@ void DTRRender_Bitmap(PlatformRenderBuffer *const renderBuffer,
u = DqnMath_Clampf(u, 0.0f, 1.0f); u = DqnMath_Clampf(u, 0.0f, 1.0f);
v = DqnMath_Clampf(v, 0.0f, 1.0f); v = DqnMath_Clampf(v, 0.0f, 1.0f);
i32 texelX = (i32)(u * (f32)(bitmap->dim.w - 1)); f32 texelXf = u * (f32)(bitmap->dim.w - 1);
i32 texelY = (i32)(v * (f32)(bitmap->dim.h - 1)); f32 texelYf = v * (f32)(bitmap->dim.h - 1);
DQN_ASSERT(texelX >= 0 && texelX < bitmap->dim.w); DQN_ASSERT(texelXf >= 0 && texelXf < bitmap->dim.w);
DQN_ASSERT(texelX >= 0 && texelY < bitmap->dim.h); DQN_ASSERT(texelYf >= 0 && texelYf < bitmap->dim.h);
#if 1 i32 texelX = (i32)texelXf;
u32 pixel = pixelPtr[texelX + (texelY * bitmap->dim.w)]; i32 texelY = (i32)texelYf;
DqnV4 color = {}; f32 texelFractionalX = texelXf - texelX;
color.a = (f32)(pixel >> 24); f32 texelFractionalY = texelYf - texelY;
color.b = (f32)((pixel >> 16) & 0xFF);
color.g = (f32)((pixel >> 8) & 0xFF); i32 texel1X = texelX;
color.r = (f32)((pixel >> 0) & 0xFF); i32 texel1Y = texelY;
i32 texel2X = DQN_MIN((texelX + 1), bitmap->dim.w - 1);
i32 texel2Y = texelY;
i32 texel3X = texelX;
i32 texel3Y = DQN_MIN((texelY + 1), bitmap->dim.h - 1);
i32 texel4X = DQN_MIN((texelX + 1), bitmap->dim.w - 1);
i32 texel4Y = DQN_MIN((texelY + 1), bitmap->dim.h - 1);
u32 texel1 = *(u32 *)(bitmapPtr + ((texel1X * bitmap->bytesPerPixel) + (texel1Y * pitch)));
u32 texel2 = *(u32 *)(bitmapPtr + ((texel2X * bitmap->bytesPerPixel) + (texel2Y * pitch)));
u32 texel3 = *(u32 *)(bitmapPtr + ((texel3X * bitmap->bytesPerPixel) + (texel3Y * pitch)));
u32 texel4 = *(u32 *)(bitmapPtr + ((texel4X * bitmap->bytesPerPixel) + (texel4Y * pitch)));
DqnV4 color1;
color1.a = (f32)(texel1 >> 24);
color1.b = (f32)((texel1 >> 16) & 0xFF);
color1.g = (f32)((texel1 >> 8) & 0xFF);
color1.r = (f32)((texel1 >> 0) & 0xFF);
DqnV4 color2;
color2.a = (f32)(texel2 >> 24);
color2.b = (f32)((texel2 >> 16) & 0xFF);
color2.g = (f32)((texel2 >> 8) & 0xFF);
color2.r = (f32)((texel2 >> 0) & 0xFF);
DqnV4 color3;
color3.a = (f32)(texel3 >> 24);
color3.b = (f32)((texel3 >> 16) & 0xFF);
color3.g = (f32)((texel3 >> 8) & 0xFF);
color3.r = (f32)((texel3 >> 0) & 0xFF);
DqnV4 color4;
color4.a = (f32)(texel4 >> 24);
color4.b = (f32)((texel4 >> 16) & 0xFF);
color4.g = (f32)((texel4 >> 8) & 0xFF);
color4.r = (f32)((texel4 >> 0) & 0xFF);
DqnV4 color12;
color12.a = DqnMath_Lerp(color1.a, texelFractionalX, color2.a);
color12.b = DqnMath_Lerp(color1.b, texelFractionalX, color2.b);
color12.g = DqnMath_Lerp(color1.g, texelFractionalX, color2.g);
color12.r = DqnMath_Lerp(color1.r, texelFractionalX, color2.r);
DqnV4 color34;
color34.a = DqnMath_Lerp(color3.a, texelFractionalX, color4.a);
color34.b = DqnMath_Lerp(color3.b, texelFractionalX, color4.b);
color34.g = DqnMath_Lerp(color3.g, texelFractionalX, color4.g);
color34.r = DqnMath_Lerp(color3.r, texelFractionalX, color4.r);
DqnV4 color;
color.a = DqnMath_Lerp(color12.a, texelFractionalY, color34.a);
color.b = DqnMath_Lerp(color12.b, texelFractionalY, color34.b);
color.g = DqnMath_Lerp(color12.g, texelFractionalY, color34.g);
color.r = DqnMath_Lerp(color12.r, texelFractionalY, color34.r);
SetPixel(renderBuffer, bufferX, bufferY, color); SetPixel(renderBuffer, bufferX, bufferY, color);
#endif #endif
int yo = 5;
#endif
} }
} }
} }

View File

@ -36,7 +36,7 @@ void DTRRender_Rectangle(PlatformRenderBuffer *const renderBuffer, DqnV2 min, Dq
DqnV4 color, const DqnV2 scale = DqnV2_1f(1.0f), const f32 rotation = 0, const DqnV2 anchor = DqnV2_1f(0.5f)); DqnV4 color, const DqnV2 scale = DqnV2_1f(1.0f), const f32 rotation = 0, const DqnV2 anchor = DqnV2_1f(0.5f));
void DTRRender_Triangle (PlatformRenderBuffer *const renderBuffer, DqnV2 p1, DqnV2 p2, DqnV2 p3, void DTRRender_Triangle (PlatformRenderBuffer *const renderBuffer, DqnV2 p1, DqnV2 p2, DqnV2 p3,
DqnV4 color, const DqnV2 scale = DqnV2_1f(1.0f), const f32 rotation = 0, const DqnV2 anchor = DqnV2_1f(0.33f)); DqnV4 color, const DqnV2 scale = DqnV2_1f(1.0f), const f32 rotation = 0, const DqnV2 anchor = DqnV2_1f(0.33f));
void DTRRender_Bitmap (PlatformRenderBuffer *const renderBuffer, DTRBitmap *const bitmap, DqnV2i pos, void DTRRender_Bitmap (PlatformRenderBuffer *const renderBuffer, DTRBitmap *const bitmap, DqnV2 pos,
DTRRenderTransform transform = DTRRender_DefaultTransform()); DTRRenderTransform transform = DTRRender_DefaultTransform());
void DTRRender_Clear (PlatformRenderBuffer *const renderBuffer, const DqnV3 color); void DTRRender_Clear (PlatformRenderBuffer *const renderBuffer, const DqnV3 color);