From 371ece0ce3de41d922ac0a00251fba5cd42723c4 Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Wed, 14 Jun 2017 12:22:14 +1000 Subject: [PATCH] Add naiive SSAA for primitive triangles only --- src/DTRenderer.cpp | 18 +++++++----- src/DTRendererDebug.cpp | 2 +- src/DTRendererRender.cpp | 59 ++++++++++++++++++++++++++++++++++++---- src/build.bat | 2 +- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/src/DTRenderer.cpp b/src/DTRenderer.cpp index c59ca87..db07f3b 100644 --- a/src/DTRenderer.cpp +++ b/src/DTRenderer.cpp @@ -904,8 +904,9 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer, // Init Assets //////////////////////////////////////////////////////////////////////// DTRAsset_InitGlobalState(); + const f32 FONT_SIZE = 14; DTRAsset_LoadFontToBitmap(input->api, &memory->mainStack, tempStack, &state->font, - "Roboto-bold.ttf", DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12); + "Roboto-bold.ttf", DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), FONT_SIZE); DTRAsset_LoadBitmap(input->api, assetStack, tempStack, &state->bitmap, "tree00.bmp"); @@ -959,7 +960,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer, //////////////////////////////////////////////////////////////////////////// // Update and Render //////////////////////////////////////////////////////////////////////////// - DTRRender_Clear(&renderBuffer, DqnV3_3f(0.5f, 0.0f, 1.0f)); + DTRRender_Clear(&renderBuffer, DqnV3_3f(0.0f, 0.0f, 0.0f)); #if 1 DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1); @@ -980,14 +981,17 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer, DqnV3 t4[3] = {DqnV3_3i(100, 150, 0), DqnV3_3i(200, 150, 0), DqnV3_3i(200, 250, 0)}; DqnV3 t5[3] = {DqnV3_3i(300, 150, 0), DqnV3_3i(201, 150, 0), DqnV3_3i(200, 250, 0)}; - DTRRenderTransform rotatingXform = DTRRender_DefaultTriangleTransform(); - rotatingXform.rotation = rotation; - if (1) { + + DTRRenderTransform rotatingXform = DTRRender_DefaultTriangleTransform(); + rotatingXform.rotation = rotation * 0.25f; + DTRDebug_BeginCycleCount("DTR_Update_RenderPrimitiveTriangles", DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles); + DTRRenderTransform scaleXform = DTRRender_DefaultTriangleTransform(); + scaleXform.scale = DqnV3_1f(5); DTRRender_Triangle(&renderBuffer, t0[0], t0[1], t0[2], colorRed); DTRRender_Triangle(&renderBuffer, t1[0], t1[1], t1[2], colorRed); DTRRender_Triangle(&renderBuffer, t3[0], t3[1], t3[2], colorRed, rotatingXform); @@ -997,7 +1001,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer, DTRDebug_EndCycleCount(DTRDebugCycleCount_DTR_Update_RenderPrimitiveTriangles); } - if (1) + if (0) { LOCAL_PERSIST bool runTinyRendererOnce = false; if (1 && runTinyRendererOnce) @@ -1016,7 +1020,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer, DqnV3 modelP = DqnV3_3f(0, 0, 0); LOCAL_PERSIST f32 modelRotation = 0; - modelRotation += (input->deltaForFrame * 20.0f); + modelRotation += (input->deltaForFrame * 80.0f); DqnV3 axis = DqnV3_3f(0, 1, 0); DTRRenderTransform transform = DTRRender_DefaultTransform(); diff --git a/src/DTRendererDebug.cpp b/src/DTRendererDebug.cpp index a5e2ae9..25d275d 100644 --- a/src/DTRendererDebug.cpp +++ b/src/DTRendererDebug.cpp @@ -216,7 +216,7 @@ void DTRDebug_Update(DTRState *const state, debug->renderBuffer = renderBuffer; debug->input = input; debug->font = &state->font; - debug->displayColor = DqnV4_4f(1, 1, 1, 1); + debug->displayColor = DqnV4_4f(1, 1, 1, 0.85f); if (debug->font->bitmap && debug->renderBuffer) { debug->displayYOffset = -(i32)(state->font.sizeInPt + 0.5f); diff --git a/src/DTRendererRender.cpp b/src/DTRendererRender.cpp index daf8689..9b0129a 100644 --- a/src/DTRendererRender.cpp +++ b/src/DTRendererRender.cpp @@ -1146,10 +1146,45 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1 for (i32 bufferX = min.x; bufferX < max.x; bufferX++) { - if (signedArea1 >= 0 && signedArea2 >= 0 && signedArea3 >= 0) + // TODO(doyle): Use signedArea1/2/3 and subsample increments from the signedAreaDeltas + const u32 NUM_SAMPLES_ALONG_AXIS = 2; + const u32 SAMPLES_PER_PIXEL = DQN_SQUARED(NUM_SAMPLES_ALONG_AXIS); + DQN_ASSERT((NUM_SAMPLES_ALONG_AXIS & 1) == 0); + + const f32 SAMPLE_COVERAGE_INCREMENT = 1 / (f32)SAMPLES_PER_PIXEL; + const f32 SAMPLE_XY_INCREMENT = 1 / (f32)NUM_SAMPLES_ALONG_AXIS; + + f32 subsampleCoverage = 0; + for (i32 sampleY = 0; sampleY < NUM_SAMPLES_ALONG_AXIS; sampleY++) + { + for (i32 sampleX = 0; sampleX < NUM_SAMPLES_ALONG_AXIS; sampleX++) + { + f32 granularX = sampleX * SAMPLE_XY_INCREMENT; + f32 granularY = sampleY * SAMPLE_XY_INCREMENT; + + DqnV2 subsample = DqnV2_2f((f32)bufferX + granularX, (f32)bufferY + granularY); + + f32 subsampleSignedArea1 = Triangle2TimesSignedArea(p2.xy, p3.xy, subsample); + f32 subsampleSignedArea2 = Triangle2TimesSignedArea(p3.xy, p1.xy, subsample); + f32 subsampleSignedArea3 = Triangle2TimesSignedArea(p1.xy, p2.xy, subsample); + + if (subsampleSignedArea1 >= 0 && subsampleSignedArea2 >= 0 && + subsampleSignedArea3 >= 0) + { + subsampleCoverage += SAMPLE_COVERAGE_INCREMENT; + } + } + } + DQN_ASSERT(subsampleCoverage >= 0.0f && subsampleCoverage <= 1.0f); + + // TODO(doyle): Crashes when using meshes, since we are now sampling + // outside the actual specified mesh, (i.e. pixels just before it + // for SSAA) the barycentric coordinates sample outside the texture. + // Naiive workarounds will cause color artifacts or gaps in rendered + // meshes. + if (subsampleCoverage > 0) { DEBUG_SLOW_AUTO_CHOOSE_BEGIN_CYCLE_COUNT(Triangle_RasterisePixel); - f32 barycentricA = signedArea1 * invSignedAreaParallelogram; f32 barycentricB = signedArea2 * invSignedAreaParallelogram; f32 barycentricC = signedArea3 * invSignedAreaParallelogram; @@ -1158,18 +1193,28 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1 f32 currZValue = renderBuffer->zBuffer[zBufferIndex]; DQN_ASSERT(zBufferIndex < (renderBuffer->width * renderBuffer->height)); - if (pixelZValue > currZValue) + if (pixelZValue >= currZValue) { renderBuffer->zBuffer[zBufferIndex] = pixelZValue; DqnV4 finalColor = color; + DQN_ASSERT(finalColor.x >= 0); + + // NOTE: Multiply everything by the coverage alpha since + // colors need to be premultiplied alpha. + finalColor *= subsampleCoverage; + DQN_ASSERT(finalColor.x >= 0); if (!ignoreLight) { - DqnV3 light = (p1Light * barycentricA) + (p2Light * barycentricB) + + f32 barycentricA = signedArea1 * invSignedAreaParallelogram; + DqnV3 light = (p1Light * barycentricA) + (p2Light * barycentricB) + (p3Light * barycentricC); finalColor.rgb *= light; + DQN_ASSERT(finalColor.x >= 0); } + DQN_ASSERT(finalColor.x >= 0); + if (texture) { DqnV2 uv = uv1 + (uv2SubUv1 * barycentricB) + (uv3SubUv1 * barycentricC); @@ -1200,9 +1245,13 @@ FILE_SCOPE void SlowTriangle(DTRRenderBuffer *const renderBuffer, const DqnV3 p1 color1 *= INV_255; color1 = DTRRender_SRGB1ToLinearSpaceV4(color1); finalColor *= color1; + + DQN_ASSERT(finalColor.x >= 0); } SetPixel(renderBuffer, bufferX, bufferY, finalColor, ColorSpace_Linear); + + int breakhere = 5; } DEBUG_SLOW_AUTO_CHOOSE_END_CYCLE_COUNT(Triangle_RasterisePixel); } @@ -1306,7 +1355,7 @@ FILE_SCOPE void TexturedTriangleInternal(DTRRenderBuffer *const renderBuffer, //////////////////////////////////////////////////////////////////////////// // SIMD/Slow Path //////////////////////////////////////////////////////////////////////////// - if (globalDTRPlatformFlags.canUseSSE2) + if (globalDTRPlatformFlags.canUseSSE2 && 0) { SIMDTriangle(renderBuffer, p1, p2, p3, uv1, uv2, uv3, lightIntensity1, lightIntensity2, lightIntensity3, ignoreLight, texture, color, min, max); diff --git a/src/build.bat b/src/build.bat index 9b76365..e7cd18c 100644 --- a/src/build.bat +++ b/src/build.bat @@ -39,7 +39,7 @@ REM wd4100 unused argument parameters REM wd4201 nonstandard extension used: nameless struct/union REM wd4189 local variable is initialised but not referenced REM wd4505 unreferenced local function not used will be removed -set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -O2 -FAsc /I..\src\external\ +set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -Od -FAsc /I..\src\external\ set DLLFlags=/Fm%ProjectName% /Fo%ProjectName% /Fa%ProjectName% /Fe%ProjectName% set Win32Flags=/FmWin32DTRenderer /FeWin32DTRenderer