Add line rendering
This commit is contained in:
parent
0d5f4c6223
commit
d9ce1e1079
29
Win32DRenderer.sln
Normal file
29
Win32DRenderer.sln
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26403.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "Win32DRenderer", "bin\Win32DRenderer.exe", "{6A9F3AE0-4D5E-4F89-8572-B868AC43C38A}"
|
||||
ProjectSection(DebuggerProjectSystem) = preProject
|
||||
PortSupplier = 00000000-0000-0000-0000-000000000000
|
||||
Executable = C:\git\drenderer\bin\Win32DRenderer.exe
|
||||
RemoteMachine = THAI-PC
|
||||
StartingDirectory = C:\git\drenderer\bin
|
||||
Environment = Default
|
||||
LaunchingEngine = 00000000-0000-0000-0000-000000000000
|
||||
UseLegacyDebugEngines = No
|
||||
LaunchSQLEngine = No
|
||||
AttachLaunchAction = No
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6A9F3AE0-4D5E-4F89-8572-B868AC43C38A}.Release|x64.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,22 +1,132 @@
|
||||
#include "DRenderer.h"
|
||||
|
||||
#include "DRendererPlatform.h"
|
||||
|
||||
#define DQN_IMPLEMENTATION
|
||||
#include "dqn.h"
|
||||
|
||||
#include <math.h>
|
||||
FILE_SCOPE void DR_DrawLine(PlatformRenderBuffer *const renderBuffer, DqnV2i a,
|
||||
DqnV2i b, DqnV3 color)
|
||||
{
|
||||
if (!renderBuffer) return;
|
||||
|
||||
bool yTallerThanX = false;
|
||||
if (DQN_ABS(a.x - b.x) < DQN_ABS(a.y - b.y))
|
||||
{
|
||||
// NOTE(doyle): Enforce that the X component is always longer than the
|
||||
// Y component. When drawing this we just reverse the order back.
|
||||
// This is to ensure that the gradient is always < 1, such that we can
|
||||
// use the gradient to calculate the distance from the pixel origin, and
|
||||
// at which point we want to increment the y.
|
||||
yTallerThanX = true;
|
||||
DQN_SWAP(i32, a.x, a.y);
|
||||
DQN_SWAP(i32, b.x, b.y);
|
||||
}
|
||||
|
||||
if (b.x < a.x) DQN_SWAP(DqnV2i, a, b);
|
||||
|
||||
i32 rise = b.y - a.y;
|
||||
i32 run = b.x - a.x;
|
||||
|
||||
i32 delta = (b.y > a.y) ? 1 : -1;
|
||||
i32 numIterations = b.x - a.x;
|
||||
|
||||
i32 distFromPixelOrigin = DQN_ABS(rise) * 2;
|
||||
i32 distAccumulator = 0;
|
||||
|
||||
i32 newX = a.x;
|
||||
i32 newY = a.y;
|
||||
|
||||
// Unflip the points if we did for plotting the pixels
|
||||
i32 *plotX, *plotY;
|
||||
if (yTallerThanX)
|
||||
{
|
||||
plotX = &newY;
|
||||
plotY = &newX;
|
||||
}
|
||||
else
|
||||
{
|
||||
plotX = &newX;
|
||||
plotY = &newY;
|
||||
}
|
||||
|
||||
const u32 pitchInU32 =
|
||||
(renderBuffer->width * renderBuffer->bytesPerPixel) / 4;
|
||||
u32 *const bitmapPtr = (u32 *)renderBuffer->memory;
|
||||
u32 pixel = ((i32)color.r << 16) | ((i32)color.g << 8) | ((i32)color.b << 0);
|
||||
for (i32 iterateX = 0; iterateX < numIterations; iterateX++)
|
||||
{
|
||||
newX = a.x + iterateX;
|
||||
bitmapPtr[*plotX + (*plotY * pitchInU32)] = pixel;
|
||||
|
||||
distAccumulator += distFromPixelOrigin;
|
||||
if (distAccumulator > run)
|
||||
{
|
||||
newY += delta;
|
||||
distAccumulator -= (run * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE void DR_DrawTriangle(PlatformRenderBuffer *const renderBuffer,
|
||||
DqnV2 p1, DqnV2 p2, DqnV2 p3, DqnV3 color)
|
||||
{
|
||||
DR_DrawLine(renderBuffer, p1, p2, color);
|
||||
DR_DrawLine(renderBuffer, p2, p3, color);
|
||||
DR_DrawLine(renderBuffer, p3, p1, color);
|
||||
|
||||
// NOTE(doyle): This is just an desc sort using bubble sort on 3 elements
|
||||
if (p1.y < p2.y) DQN_SWAP(DqnV2i, p1, p2);
|
||||
if (p2.y < p3.y) DQN_SWAP(DqnV2i, p1, p3);
|
||||
if (p1.y < p2.y) DQN_SWAP(DqnV2i, p2, p3);
|
||||
|
||||
i32 y1i = (i32)(p1.y + 0.5f);
|
||||
i32 y2i = (i32)(p2.y + 0.5f);
|
||||
i32 y3i = (i32)(p3.y + 0.5f);
|
||||
|
||||
if (y1i == y3i) return; // Zero height triangle
|
||||
}
|
||||
|
||||
FILE_SCOPE void DR_ClearRenderBuffer(PlatformRenderBuffer *const renderBuffer, DqnV3 color)
|
||||
{
|
||||
if (!renderBuffer) return;
|
||||
|
||||
DQN_ASSERT(color.r >= 0.0f && color.r <= 255.0f);
|
||||
DQN_ASSERT(color.g >= 0.0f && color.g <= 255.0f);
|
||||
DQN_ASSERT(color.b >= 0.0f && color.b <= 255.0f);
|
||||
|
||||
u32 *const bitmapPtr = (u32 *)renderBuffer->memory;
|
||||
for (i32 y = 0; y < renderBuffer->height; y++)
|
||||
{
|
||||
for (i32 x = 0; x < renderBuffer->width; x++)
|
||||
{
|
||||
u32 pixel = ((i32)color.r << 16) | ((i32)color.g << 8) |
|
||||
((i32)color.b << 0);
|
||||
bitmapPtr[x + (y * renderBuffer->width)] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void DR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
PlatformInput *const input,
|
||||
PlatformMemory *const memory)
|
||||
{
|
||||
u32 *bitmapPtr = (u32 *)renderBuffer->memory;
|
||||
for (i32 y = 0; y < renderBuffer->height; y++)
|
||||
{
|
||||
for (i32 x = 0; x < renderBuffer->width; x++)
|
||||
{
|
||||
u8 red = 255;
|
||||
u8 green = 0;
|
||||
u8 blue = 0;
|
||||
DR_ClearRenderBuffer(renderBuffer, DqnV3_3f(0, 0, 0));
|
||||
|
||||
u32 color = (red << 16) | (green << 8) | (blue << 0);
|
||||
bitmapPtr[x + (y * renderBuffer->width)] = color;
|
||||
}
|
||||
}
|
||||
DqnV3 colorRed = DqnV3_3i(255, 0, 0);
|
||||
DqnV2i bufferMidP = DqnV2i_2f(renderBuffer->width * 0.5f, renderBuffer->height * 0.5f);
|
||||
i32 boundsOffset = 50;
|
||||
|
||||
DqnV2 t0[3] = {DqnV2_2i(10, 70), DqnV2_2i(50, 160), DqnV2_2i(70, 80)};
|
||||
DqnV2 t1[3] = {DqnV2_2i(180, 50), DqnV2_2i(150, 1), DqnV2_2i(70, 180)};
|
||||
DqnV2 t2[3] = {DqnV2_2i(180, 150), DqnV2_2i(120, 160), DqnV2_2i(130, 180)};
|
||||
DqnV2 t3[3] = {
|
||||
DqnV2_2i(boundsOffset, boundsOffset),
|
||||
DqnV2_2i(bufferMidP.w, renderBuffer->height - boundsOffset),
|
||||
DqnV2_2i(renderBuffer->width - boundsOffset, boundsOffset)};
|
||||
|
||||
DR_DrawTriangle(renderBuffer, t0[0], t0[1], t0[2], colorRed);
|
||||
// DR_DrawTriangle(renderBuffer, t1[0], t1[1], t1[2], colorRed);
|
||||
// DR_DrawTriangle(renderBuffer, t2[0], t2[1], t2[2], colorRed);
|
||||
// DR_DrawTriangle(renderBuffer, t3[0], t3[1], t3[2], colorRed);
|
||||
}
|
||||
|
@ -375,6 +375,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
DqnWin32_DisplayLastError("CreateDIBSection() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Make DLL Path
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -393,7 +394,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
|
||||
numCopied =
|
||||
Dqn_sprintf(dllTmpPath, "%s%s", exeDir, "drenderer_temp.dll");
|
||||
DQN_ASSERT(numCopied < DQN_ARRAY_COUNT(dllPath));
|
||||
DQN_ASSERT(numCopied < DQN_ARRAY_COUNT(dllTmpPath));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -39,7 +39,12 @@ REM wd4505 unreferenced local function not used will be removed
|
||||
set CompileFlags=-EHa- -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -Od -FAsc
|
||||
set DLLFlags=/Fm%ProjectName% /Fo%ProjectName% /Fa%ProjectName% /Fe%ProjectName%
|
||||
set Win32Flags=/FmWin32DRenderer /FeWin32DRenderer
|
||||
set TimeStamp=%date:~10,4%%date:~7,2%%date:~4,2%_%time:~0,2%%time:~3,2%%time:~6,2%
|
||||
|
||||
REM Clean time necessary for hours <10, which produces H:MM:SS.SS where the
|
||||
REM first character of time is an empty space. CleanTime will pad a 0 if
|
||||
REM necessary.
|
||||
set CleanTime=%time: =0%
|
||||
set TimeStamp=%date:~10,4%%date:~7,2%%date:~4,2%_%CleanTime:~0,2%%CleanTime:~3,2%%CleanTime:~6,2%
|
||||
|
||||
REM Link libraries
|
||||
set LinkLibraries=user32.lib kernel32.lib gdi32.lib
|
||||
|
@ -48,14 +48,14 @@ typedef float f32;
|
||||
#define DQN_ASSERT(expr) if (!(expr)) { (*((i32 *)0)) = 0; }
|
||||
|
||||
#define DQN_PI 3.14159265359f
|
||||
|
||||
#define DQN_SQUARED(x) ((x) * (x))
|
||||
#define DQN_ABS(x) (((x) < 0) ? (-(x)) : (x))
|
||||
#define DQN_DEGREES_TO_RADIANS(x) ((x * (DQN_PI / 180.0f)))
|
||||
#define DQN_RADIANS_TO_DEGREES(x) ((x * (180.0f / DQN_PI)))
|
||||
|
||||
#define DQN_MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
#define DQN_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define DQN_SQUARED(x) ((x) * (x))
|
||||
|
||||
#define DQN_SWAP(type, a, b) do { type tmp = a; a = b; b = tmp; } while(0)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DqnMem - Memory
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user