Fix rotation on triangles
This commit is contained in:
parent
51342122b9
commit
3ec64da44c
@ -46,6 +46,8 @@ typedef struct DRState
|
||||
typedef struct DRDebug
|
||||
{
|
||||
DRFont *font;
|
||||
PlatformRenderBuffer *renderBuffer;
|
||||
|
||||
DqnV2 displayP;
|
||||
i32 displayYOffset;
|
||||
|
||||
@ -186,11 +188,13 @@ FILE_SCOPE void DrawText(PlatformRenderBuffer *const renderBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE void DebugPushText(PlatformRenderBuffer *const renderBuffer,
|
||||
const char *const formatStr, ...)
|
||||
FILE_SCOPE void DebugPushText(const char *const formatStr, ...)
|
||||
{
|
||||
#ifdef DR_DEBUG
|
||||
if (DR_DEBUG)
|
||||
{
|
||||
DRDebug *const debug = &globalDebug;
|
||||
if (!debug->renderBuffer) return;
|
||||
|
||||
char str[1024] = {};
|
||||
|
||||
va_list argList;
|
||||
@ -201,9 +205,9 @@ FILE_SCOPE void DebugPushText(PlatformRenderBuffer *const renderBuffer,
|
||||
}
|
||||
va_end(argList);
|
||||
|
||||
DrawText(renderBuffer, *debug->font, debug->displayP, str);
|
||||
DrawText(debug->renderBuffer, *debug->font, debug->displayP, str);
|
||||
debug->displayP.y += globalDebug.displayYOffset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE void DrawLine(PlatformRenderBuffer *const renderBuffer, DqnV2i a,
|
||||
@ -284,64 +288,50 @@ FILE_SCOPE void TransformVertexes(const DqnV2 origin, DqnV2 *const vertexList,
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE void DrawRectangle(PlatformRenderBuffer *const renderBuffer,
|
||||
DqnV2 min, DqnV2 max, DqnV4 color,
|
||||
const DqnV2 scale = DqnV2_1f(1.0f),
|
||||
const f32 rotation = 0,
|
||||
const DqnV2 anchor = DqnV2_1f(0.5f));
|
||||
|
||||
FILE_SCOPE void DrawTriangle(PlatformRenderBuffer *const renderBuffer, DqnV2 p1,
|
||||
DqnV2 p2, DqnV2 p3, DqnV4 color,
|
||||
DqnV2 scale = DqnV2_1f(1.0f), f32 rotation = 0,
|
||||
DqnV2 anchor = DqnV2_1f(0.5f))
|
||||
DqnV2 anchor = DqnV2_1f(0.33f))
|
||||
{
|
||||
f32 area2Times = ((p2.x - p1.x) * (p2.y + p1.y)) +
|
||||
((p3.x - p2.x) * (p3.y + p2.y)) +
|
||||
((p1.x - p3.x) * (p1.y + p3.y));
|
||||
if (area2Times < 0)
|
||||
{
|
||||
// Counter-clockwise, do nothing this is what we want.
|
||||
}
|
||||
else
|
||||
if (area2Times > 0)
|
||||
{
|
||||
// Clockwise swap any point to make it clockwise
|
||||
DQN_SWAP(DqnV2, p2, p3);
|
||||
}
|
||||
|
||||
// Transform vertexes
|
||||
#if 1
|
||||
{
|
||||
DqnV2 max = DqnV2_2f(DQN_MAX(DQN_MAX(p1.x, p2.x), p3.x),
|
||||
DQN_MAX(DQN_MAX(p1.y, p2.y), p3.y));
|
||||
DqnV2 min = DqnV2_2f(DQN_MIN(DQN_MIN(p1.x, p2.x), p3.x),
|
||||
DQN_MIN(DQN_MIN(p1.y, p2.y), p3.y));
|
||||
|
||||
DqnV2 boundsDim = DqnV2_2f(max.x - min.x, max.y - min.y);
|
||||
DQN_ASSERT(boundsDim.w > 0 && boundsDim.h > 0);
|
||||
DqnV2 origin = DqnV2_2f(min.x + (anchor.x * boundsDim.w), min.y + (anchor.y * boundsDim.h));
|
||||
DqnV2 p1p2 = p2 - p1;
|
||||
DqnV2 p1p3 = p3 - p1;
|
||||
DqnV2 p1p2Anchored = p1p2 * anchor;
|
||||
DqnV2 p1p3Anchored = p1p3 * anchor;
|
||||
|
||||
DqnV2 origin = p1 + p1p2Anchored + p1p3Anchored;
|
||||
DqnV2 vertexList[3] = {p1 - origin, p2 - origin, p3 - origin};
|
||||
TransformVertexes(origin, vertexList, DQN_ARRAY_COUNT(vertexList),
|
||||
scale, rotation);
|
||||
TransformVertexes(origin, vertexList, DQN_ARRAY_COUNT(vertexList), scale,
|
||||
rotation);
|
||||
p1 = vertexList[0];
|
||||
p2 = vertexList[1];
|
||||
p3 = vertexList[2];
|
||||
}
|
||||
#endif
|
||||
|
||||
color = PreMultiplyAlpha(color);
|
||||
DqnV2i max = DqnV2i_2f(DQN_MAX(DQN_MAX(p1.x, p2.x), p3.x),
|
||||
DQN_MAX(DQN_MAX(p1.y, p2.y), p3.y));
|
||||
DqnV2i min = DqnV2i_2f(DQN_MIN(DQN_MIN(p1.x, p2.x), p3.x),
|
||||
DQN_MIN(DQN_MIN(p1.y, p2.y), p3.y));
|
||||
|
||||
min.x = DQN_MAX(min.x, 0);
|
||||
min.y = DQN_MAX(min.y, 0);
|
||||
|
||||
max.x = DQN_MIN(max.x, renderBuffer->width - 1);
|
||||
max.y = DQN_MIN(max.y, renderBuffer->height - 1);
|
||||
|
||||
#if 1
|
||||
DrawLine(renderBuffer, DqnV2i_2i(min.x, min.y), DqnV2i_2i(min.x, max.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(min.x, max.y), DqnV2i_2i(max.x, max.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(max.x, max.y), DqnV2i_2i(max.x, min.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(max.x, min.y), DqnV2i_2i(min.x, min.y), color);
|
||||
#endif
|
||||
|
||||
/*
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Rearranging the Determinant
|
||||
@ -350,12 +340,6 @@ FILE_SCOPE void DrawTriangle(PlatformRenderBuffer *const renderBuffer, DqnV2 p1,
|
||||
determine whether a point lies on the line, or is to the left or right of
|
||||
a the line.
|
||||
|
||||
Then you can imagine if we iterate over the triangle vertexes, 2 at at
|
||||
time and a last point P, being the point we want to test if it's inside
|
||||
the triangle, then if the point is considered to lie on the side of the
|
||||
line forming the interior of the triangle for all 3 vertexes then the
|
||||
point is inside the triangle. We can do this using the determinant.
|
||||
|
||||
First forming a 3x3 matrix of our terms with a, b being from the triangle
|
||||
and test point c, we can derive a 2x2 matrix by subtracting the 1st
|
||||
column from the 2nd and 1st column from the third.
|
||||
@ -491,41 +475,43 @@ FILE_SCOPE void DrawTriangle(PlatformRenderBuffer *const renderBuffer, DqnV2 p1,
|
||||
signedArea3 += signedArea3DeltaY;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (DR_DEBUG)
|
||||
{
|
||||
// Draw Bounding box
|
||||
{
|
||||
DrawLine(renderBuffer, DqnV2i_2i(min.x, min.y), DqnV2i_2i(min.x, max.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(min.x, max.y), DqnV2i_2i(max.x, max.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(max.x, max.y), DqnV2i_2i(max.x, min.y), color);
|
||||
DrawLine(renderBuffer, DqnV2i_2i(max.x, min.y), DqnV2i_2i(min.x, min.y), color);
|
||||
}
|
||||
|
||||
// Draw Triangle Coordinate Basis
|
||||
{
|
||||
DqnV2 xAxis = DqnV2_2f(cosf(rotation), sinf(rotation)) * scale.x;
|
||||
DqnV2 yAxis = DqnV2_2f(-xAxis.y, xAxis.x) * scale.y;
|
||||
|
||||
DqnV2 vertexList[3] = {p1, p2, p3};
|
||||
DqnRect bounds = {};
|
||||
bounds.min = vertexList[0];
|
||||
bounds.max = vertexList[0];
|
||||
for (i32 i = 1; i < DQN_ARRAY_COUNT(vertexList); i++)
|
||||
{
|
||||
const DqnV2 p = vertexList[i];
|
||||
bounds.min = DqnV2_2f(DQN_MIN(p.x, bounds.min.x),
|
||||
DQN_MIN(p.y, bounds.min.y));
|
||||
bounds.max = DqnV2_2f(DQN_MAX(p.x, bounds.max.x),
|
||||
DQN_MAX(p.y, bounds.max.y));
|
||||
}
|
||||
|
||||
DqnV2 boundsDim = DqnRect_GetSizeV2(bounds);
|
||||
DqnV2 origin = DqnV2_2f(bounds.min.x + (anchor.x * boundsDim.w),
|
||||
bounds.min.y + (anchor.y * boundsDim.h));
|
||||
|
||||
DqnV4 coordSysColor = DqnV4_4f(0, 255, 255, 255);
|
||||
i32 axisLen = 50;
|
||||
DrawLine(renderBuffer, DqnV2i_V2(origin), DqnV2i_V2(origin) + DqnV2i_V2(xAxis * axisLen), coordSysColor);
|
||||
DrawLine(renderBuffer, DqnV2i_V2(origin), DqnV2i_V2(origin) + DqnV2i_V2(yAxis * axisLen), coordSysColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draw axis point
|
||||
{
|
||||
DqnV4 green = DqnV4_4f(0, 255, 0, 255);
|
||||
DqnV4 blue = DqnV4_4f(0, 0, 255, 255);
|
||||
DqnV4 purple = DqnV4_4f(255, 0, 255, 255);
|
||||
|
||||
DrawRectangle(renderBuffer, p1 - DqnV2_1f(5), p1 + DqnV2_1f(5), green);
|
||||
DrawRectangle(renderBuffer, p2 - DqnV2_1f(5), p2 + DqnV2_1f(5), blue);
|
||||
DrawRectangle(renderBuffer, p3 - DqnV2_1f(5), p3 + DqnV2_1f(5), purple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE void DrawRectangle(PlatformRenderBuffer *const renderBuffer,
|
||||
DqnV2 min, DqnV2 max, DqnV4 color,
|
||||
const DqnV2 scale = DqnV2_1f(1.0f),
|
||||
const f32 rotation = 0,
|
||||
const DqnV2 anchor = DqnV2_1f(0.5f))
|
||||
const DqnV2 scale, const f32 rotation,
|
||||
const DqnV2 anchor)
|
||||
{
|
||||
// TODO(doyle): Do edge test for quads
|
||||
if (rotation > 0)
|
||||
@ -562,7 +548,6 @@ FILE_SCOPE void DrawRectangle(PlatformRenderBuffer *const renderBuffer,
|
||||
DqnRect clippedRect = DqnRect_ClipRect(rect, clip);
|
||||
DqnV2 clippedSize = DqnRect_GetSizeV2(clippedRect);
|
||||
|
||||
DebugPushText(renderBuffer, "ClippedSized: %5.2f, %5.2f", clippedSize.w, clippedSize.h);
|
||||
for (i32 y = 0; y < clippedSize.w; y++)
|
||||
{
|
||||
i32 bufferY = (i32)clippedRect.min.y + y;
|
||||
@ -622,9 +607,7 @@ FILE_SCOPE void BitmapFontCreate(const PlatformAPI api,
|
||||
|
||||
stbtt_fontinfo fontInfo = {};
|
||||
DQN_ASSERT(stbtt_InitFont(&fontInfo, fontBuf, 0) != 0);
|
||||
#if DR_DEBUG
|
||||
DQN_ASSERT(stbtt_GetNumberOfFonts(fontBuf) == 1);
|
||||
#endif
|
||||
if (DR_DEBUG) DQN_ASSERT(stbtt_GetNumberOfFonts(fontBuf) == 1);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Pack font data to bitmap
|
||||
@ -806,12 +789,23 @@ void DebugDisplayMemBuffer(PlatformRenderBuffer *const renderBuffer,
|
||||
debugP->y += globalDebug.displayYOffset;
|
||||
}
|
||||
|
||||
void DebugUpdate(PlatformRenderBuffer *const renderBuffer,
|
||||
void DebugUpdate(DRState *const state, PlatformRenderBuffer *const renderBuffer,
|
||||
PlatformInput *const input, PlatformMemory *const memory)
|
||||
{
|
||||
#ifdef DR_DEBUG
|
||||
if (DR_DEBUG)
|
||||
{
|
||||
DRDebug *const debug = &globalDebug;
|
||||
|
||||
if (input->executableReloaded || !memory->isInit)
|
||||
{
|
||||
debug->font = &state->font;
|
||||
debug->displayYOffset = -(i32)(state->font.sizeInPt + 0.5f);
|
||||
debug->displayP =
|
||||
DqnV2_2i(0, renderBuffer->height + globalDebug.displayYOffset);
|
||||
DQN_ASSERT(globalDebug.displayYOffset < 0);
|
||||
debug->renderBuffer = renderBuffer;
|
||||
}
|
||||
|
||||
debug->totalSetPixels += debug->setPixelsPerFrame;
|
||||
debug->totalSetPixels = DQN_MAX(0, debug->totalSetPixels);
|
||||
|
||||
@ -819,7 +813,7 @@ void DebugUpdate(PlatformRenderBuffer *const renderBuffer,
|
||||
{
|
||||
char str[128] = {};
|
||||
Dqn_sprintf(str, "%s: %'lld", "TotalSetPixels", debug->totalSetPixels);
|
||||
DrawText(renderBuffer, *debug->font, debug->displayP, str);
|
||||
DrawText(debug->renderBuffer, *debug->font, debug->displayP, str);
|
||||
debug->displayP.y += globalDebug.displayYOffset;
|
||||
}
|
||||
|
||||
@ -827,22 +821,22 @@ void DebugUpdate(PlatformRenderBuffer *const renderBuffer,
|
||||
{
|
||||
char str[128] = {};
|
||||
Dqn_sprintf(str, "%s: %'lld", "SetPixelsPerFrame", debug->setPixelsPerFrame);
|
||||
DrawText(renderBuffer, *debug->font, debug->displayP, str);
|
||||
DrawText(debug->renderBuffer, *debug->font, debug->displayP, str);
|
||||
debug->displayP.y += globalDebug.displayYOffset;
|
||||
}
|
||||
|
||||
// memory
|
||||
{
|
||||
DebugDisplayMemBuffer(renderBuffer, "PermBuffer",
|
||||
DebugDisplayMemBuffer(debug->renderBuffer, "PermBuffer",
|
||||
&memory->permanentBuffer, &debug->displayP, *debug->font);
|
||||
DebugDisplayMemBuffer(renderBuffer, "TransBuffer",
|
||||
DebugDisplayMemBuffer(debug->renderBuffer, "TransBuffer",
|
||||
&memory->transientBuffer, &debug->displayP, *debug->font);
|
||||
}
|
||||
|
||||
debug->setPixelsPerFrame = 0;
|
||||
debug->displayP =
|
||||
DqnV2_2i(0, renderBuffer->height + globalDebug.displayYOffset);
|
||||
#endif
|
||||
DqnV2_2i(0, debug->renderBuffer->height + globalDebug.displayYOffset);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void DR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
@ -865,20 +859,10 @@ extern "C" void DR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
&memory->transientBuffer));
|
||||
}
|
||||
|
||||
#ifdef DR_DEBUG
|
||||
if (input->executableReloaded || !memory->isInit)
|
||||
{
|
||||
globalDebug.font = &state->font;
|
||||
globalDebug.displayYOffset = -(i32)(state->font.sizeInPt + 0.5f);
|
||||
globalDebug.displayP =
|
||||
DqnV2_2i(0, renderBuffer->height + globalDebug.displayYOffset);
|
||||
DQN_ASSERT(globalDebug.displayYOffset < 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
ClearRenderBuffer(renderBuffer, DqnV3_3f(0, 0, 0));
|
||||
DqnV4 colorRed = DqnV4_4i(50, 0, 0, 255);
|
||||
DqnV2i bufferMidP = DqnV2i_2f(renderBuffer->width * 0.5f, renderBuffer->height * 0.5f);
|
||||
DqnV2i bufferMidP =
|
||||
DqnV2i_2f(renderBuffer->width * 0.5f, renderBuffer->height * 0.5f);
|
||||
i32 boundsOffset = 100;
|
||||
|
||||
DqnV2 t0[3] = {DqnV2_2i(10, 70), DqnV2_2i(50, 160), DqnV2_2i(70, 80)};
|
||||
@ -889,41 +873,24 @@ extern "C" void DR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||
DqnV2_2i(bufferMidP.w, renderBuffer->height - boundsOffset),
|
||||
DqnV2_2i(renderBuffer->width - boundsOffset, boundsOffset)};
|
||||
|
||||
f32 minX = (f32)(renderBuffer->width - 1);
|
||||
f32 maxX = 0;
|
||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(t3); i++)
|
||||
{
|
||||
// t3[i].x += input->deltaForFrame * 2.0f;
|
||||
minX = DQN_MIN(t3[i].x, minX);
|
||||
maxX = DQN_MAX(t3[i].x, maxX);
|
||||
}
|
||||
|
||||
if (minX >= renderBuffer->width - 1)
|
||||
{
|
||||
f32 triangleWidth = maxX - minX;
|
||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(t3); i++)
|
||||
{
|
||||
t3[i].x -= (minX + triangleWidth);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
DrawTriangle(renderBuffer, t0[0], t0[1], t0[2], colorRed);
|
||||
DrawTriangle(renderBuffer, t1[0], t1[1], t1[2], colorRed);
|
||||
DrawTriangle(renderBuffer, t2[0], t2[1], t2[2], colorRed);
|
||||
#endif
|
||||
|
||||
DqnV4 colorRedHalfA = DqnV4_4i(255, 0, 0, 190);
|
||||
LOCAL_PERSIST f32 rotation = 0;
|
||||
rotation += input->deltaForFrame * 0.25f;
|
||||
DqnV2 scale = DqnV2_1f(1.0f);
|
||||
DrawTriangle(renderBuffer, t3[0], t3[1], t3[2], colorRedHalfA, scale,
|
||||
rotation, DqnV2_1f(0.5f));
|
||||
DrawTriangle(renderBuffer, t3[0], t3[1], t3[2], colorRedHalfA,
|
||||
DqnV2_1f(1.0f), rotation, DqnV2_2f(0.33f, 0.33f));
|
||||
|
||||
DrawRectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 20.0f), colorRed,
|
||||
DqnV2_1f(1.0f), rotation);
|
||||
DrawRectangle(renderBuffer, DqnV2_1f(300.0f), DqnV2_1f(300 + 20.0f),
|
||||
colorRed, DqnV2_1f(1.0f), rotation);
|
||||
|
||||
DqnV2 fontP = DqnV2_2i(200, 180);
|
||||
DrawText(renderBuffer, state->font, fontP, "hello world!");
|
||||
|
||||
DrawBitmap(renderBuffer, &state->bitmap, 300, 250);
|
||||
DebugUpdate(renderBuffer, input, memory);
|
||||
// DrawBitmap(renderBuffer, &state->bitmap, 300, 250);
|
||||
DebugUpdate(state, renderBuffer, input, memory);
|
||||
}
|
||||
|
13
src/dqn.h
13
src/dqn.h
@ -2282,25 +2282,24 @@ DQN_FILE_SCOPE DqnRect DqnRect_Init(DqnV2 origin, DqnV2 size)
|
||||
|
||||
DQN_FILE_SCOPE void DqnRect_GetSize2f(DqnRect rect, f32 *width, f32 *height)
|
||||
{
|
||||
*width = DQN_ABS(rect.max.x - rect.min.x);
|
||||
*height = DQN_ABS(rect.max.y - rect.min.y);
|
||||
*width = rect.max.x - rect.min.x;
|
||||
*height = rect.max.y - rect.min.y;
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE void DqnRect_GetSize2i(DqnRect rect, i32 *width, i32 *height)
|
||||
{
|
||||
*width = (i32)DQN_ABS(rect.max.x - rect.min.x);
|
||||
*height = (i32)DQN_ABS(rect.max.y - rect.min.y);
|
||||
*width = (i32)(rect.max.x - rect.min.x);
|
||||
*height = (i32)(rect.max.y - rect.min.y);
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE DqnV2 DqnRect_GetSizeV2(DqnRect rect)
|
||||
{
|
||||
f32 width = DQN_ABS(rect.max.x - rect.min.x);
|
||||
f32 height = DQN_ABS(rect.max.y - rect.min.y);
|
||||
f32 width = rect.max.x - rect.min.x;
|
||||
f32 height = rect.max.y - rect.min.y;
|
||||
DqnV2 result = DqnV2_2f(width, height);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DQN_FILE_SCOPE DqnV2 DqnRect_GetCentre(DqnRect rect)
|
||||
{
|
||||
f32 sumX = rect.min.x + rect.max.x;
|
||||
|
Loading…
Reference in New Issue
Block a user