summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-01-04 18:30:56 -0500
committerFox Caminiti <fox@foxcam.net>2023-01-04 18:30:56 -0500
commiteebbdd012b0d156e9e92369585c6ad82ed3de371 (patch)
treebbaeec7569de49f68bf853158a95c095878cf825
parenta37ea807e93886e6a6ebc22a878a5649e97f015a (diff)
shapes; remove stencil buffer?
-rw-r--r--src/bezier.cpp39
-rw-r--r--src/createcalls.cpp39
-rw-r--r--src/gl_calls.cpp60
-rw-r--r--src/imgui_ui.cpp22
-rw-r--r--src/imgui_ui_properties.cpp21
-rw-r--r--src/imgui_ui_timeline.cpp2
-rw-r--r--src/imgui_ui_viewport.cpp173
-rw-r--r--src/include/debug.h2
-rw-r--r--src/include/defines.h3
-rw-r--r--src/include/functions.h6
-rw-r--r--src/include/main.h9
-rw-r--r--src/include/my_math.h10
-rw-r--r--src/layer.cpp20
-rw-r--r--src/main.cpp19
-rw-r--r--src/nanovg.cpp65
15 files changed, 350 insertions, 140 deletions
diff --git a/src/bezier.cpp b/src/bezier.cpp
index ac89ed3..420cae1 100644
--- a/src/bezier.cpp
+++ b/src/bezier.cpp
@@ -35,6 +35,19 @@ Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 Tar
}
static bezier_point *
+Bezier_LookupAddress(memory *Memory, uint16 *Block_Bezier_Index, uint16 Index, bool32 AssertExists)
+{
+ Assert(Index < (MAX_KEYFRAMES_PER_BLOCK * MAX_KEYFRAME_BLOCKS));
+ int SeekBlock = Index / MAX_KEYFRAMES_PER_BLOCK;
+ int SeekIndex = Index - (SeekBlock * MAX_KEYFRAMES_PER_BLOCK);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Block_Bezier_Index[SeekBlock], 0);
+ Assert(Bezier->Occupied);
+ if (AssertExists)
+ Assert(Bezier->Point[SeekIndex].Occupied);
+ return &Bezier->Point[SeekIndex];
+}
+
+static bezier_point *
Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists)
{
Assert(Index < MAX_KEYFRAMES_PER_BLOCK); // TODO(fox): Test multiple keyframe blocks!
@@ -65,6 +78,32 @@ Bezier_Interact_Evaluate(project_state *State, bezier_point *PointAddress, v2 *P
}
static void
+Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *Block_Bezier_Count,
+ uint16 *PointCount, bezier_point PointData)
+{
+ int k = 0;
+ for (;;) {
+ int SeekBlock = k / MAX_KEYFRAMES_PER_BLOCK;
+ if ((SeekBlock + 1) > *Block_Bezier_Count) {
+ Block_Bezier_Index[SeekBlock] = Memory_Block_AllocateNew(Memory, F_Bezier);
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Block_Bezier_Index[SeekBlock], 0);
+ Bezier->Occupied = true;
+ History_Action_Swap(Memory, TableName, sizeof(*Block_Bezier_Count), Block_Bezier_Count);
+ *Block_Bezier_Count += 1;
+ }
+ bezier_point *Point = Bezier_LookupAddress(Memory, Block_Bezier_Index, k, 0);
+ if (!Point->Occupied) {
+ History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
+ *Point = PointData;
+ History_Action_Swap(Memory, TableName, sizeof(*PointCount), PointCount);
+ *PointCount += 1;
+ return;
+ }
+ k++;
+ }
+}
+
+static void
Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation)
{
if (!Property->Block_Bezier_Count) {
diff --git a/src/createcalls.cpp b/src/createcalls.cpp
index 4bdd6d7..cd8f3d5 100644
--- a/src/createcalls.cpp
+++ b/src/createcalls.cpp
@@ -610,7 +610,7 @@ Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *Arr
}
static void
-Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory, v2 Point, v2 Vector)
+Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory)
{
int TopOffset = Layer_GetTopOffset(File, Memory);
block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
@@ -618,8 +618,6 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory,
History_Entry_Commit(Memory, "New shape layer");
block_layer *Layer = Layer_Init(File, Memory);
Layer->IsShapeLayer = true;
- Layer->x.CurrentValue = MainComp->Width / 2;
- Layer->y.CurrentValue = MainComp->Height / 2;
if (File->Layer_Count == 1) {
Layer->Vertical_Offset = 11 - 1;
} else {
@@ -629,17 +627,32 @@ Project_ShapeLayer_New(project_data *File, project_state *State, memory *Memory,
Layer->Frame_End = MainComp->Frame_End;
Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, Layer));
- Layer->Shape.Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier);
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0], 0);
- Bezier->Occupied = true;
- v2 BezierPoint[3] = { Point, V2(000, 000), V2(000, 000) };
- interpolation_type Type = interpolation_type_linear;
- if (Vector.x) {
- BezierPoint[1] = Vector;
- BezierPoint[2] = Vector * -1;
- Type = interpolation_type_bezier;
+ v2 Min = V2(10000, 10000);
+ v2 Max = V2(-10000, -10000);
+ shape_layer *Shape = &File->UI.Shape;
+ for (int i = 0; i < Shape->Point_Count; i++) {
+ bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ if (Point->Pos[0].x > Max.x)
+ Max.x = Point->Pos[0].x;
+ if (Point->Pos[0].x < Min.x)
+ Min.x = Point->Pos[0].x;
+ if (Point->Pos[0].y > Max.y)
+ Max.y = Point->Pos[0].y;
+ if (Point->Pos[0].y < Min.y)
+ Min.y = Point->Pos[0].y;
}
- Bezier->Point[0] = { 1, { BezierPoint[0], BezierPoint[1], BezierPoint[2] }, Type, 0 };
+ v2 ShapeSize = (Max - Min);
+ Layer->x.CurrentValue = Min.x + (ShapeSize.x / 2);
+ Layer->y.CurrentValue = Min.y + (ShapeSize.y / 2);
+ for (int i = 0; i < Shape->Point_Count; i++) {
+ bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ Point->Pos[0] = Point->Pos[0] - Min;
+ }
+
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->Shape), &Layer->Shape);
+ Layer->Shape = File->UI.Shape;
+ History_Action_Swap(Memory, F_File, sizeof(File->UI.Shape), &File->UI.Shape);
+ File->UI.Shape = {};
History_Entry_End(Memory);
State->UpdateFrame = true;
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
index 5007148..dbc0784 100644
--- a/src/gl_calls.cpp
+++ b/src/gl_calls.cpp
@@ -30,13 +30,14 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n"
"in vec2 TexCoord;\n"
"uniform sampler2D Texture;\n"
"uniform int FragmentMode;\n"
+"uniform vec3 InputCol;\n"
"void main()\n"
"{\n"
"vec4 Col = texture(Texture, TexCoord);\n"
" if (FragmentMode == 0) {\n"
" FragColor = Col;\n"
"} else {\n"
-" FragColor = vec4(vec3(1.0f), Col.a);\n"
+" FragColor = vec4(InputCol, Col.a);\n"
"}\n"
"}\0";
@@ -164,9 +165,9 @@ GL_DeleteHWBuffer(gl_effect_layer *Test)
Test->Initialized = true;
}
-void
-GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *PointData, uint32 GL_PointCount,
- layer_transforms T, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, int L_Width, int L_Height)
+static void
+GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount,
+ layer_transforms T, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, int L_Width, int L_Height, v4 Col, int RenderMode)
{
glBindTexture(GL_TEXTURE_2D, TestL->Texture);
int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16;
@@ -208,8 +209,18 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *PointDat
Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale");
glUniform1f(Uniform, T.scale);
+#if 0
+ void *PointData = NULL;
+ int PointCount = 0;
+ if (RenderMode == 0) {
+ PointData = FillData;
+ PointCount = FillCount;
+ } else {
+ PointData = StrokeData;
+ PointCount = StrokeCount;
+ }
glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * GL_PointCount, PointData, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * PointCount, PointData, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
@@ -220,15 +231,50 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *PointDat
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
glDisable(GL_CULL_FACE);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, GL_PointCount);
+ if (RenderMode == 0) {
+ glDrawArrays(GL_TRIANGLE_FAN, 0, PointCount);
+ } else {
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, PointCount);
+ }
// stencil buffer
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+#else
+ glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * FillCount, FillData, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
+
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
+ glDisable(GL_CULL_FACE);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
+
+ glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * StrokeCount, StrokeData, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
+
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
+ glDisable(GL_CULL_FACE);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, StrokeCount);
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+#endif
// default verts
glBindVertexArray(0);
Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
glUniform1i(Uniform, 0);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
+ glUniform3f(Uniform, Col.r, Col.g, Col.b);
glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
@@ -256,8 +302,6 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *PointDat
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, EffectBitmapAddress);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- // GL_DeleteHWBuffer(TestL);
- // GL_DeleteHWBuffer(TestM);
}
void
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 1feb1e5..c545e80 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -118,26 +118,6 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
static void
-ImGui_Opt_Shape(shape_options *Opt)
-{
- // TODO(fox): Combine with RGBA function?
- char *Names[3] = { "Fill only", "Stroke only", "Fill and stroke" };
- if (ImGui::BeginListBox("Shape render type")) {
- for (int i = 0; i < 3; i++) {
- if (ImGui::Selectable(Names[i], (Opt->Visibility == i))) {
- Opt->Visibility = i;
- }
- }
- ImGui::EndListBox();
- }
- ImGui::ColorEdit4("Fill color", (real32 *)&Opt->FillCol, ImGuiColorEditFlags_Float);
- ImGui::ColorEdit4("Stroke color", (real32 *)&Opt->StrokeCol, ImGuiColorEditFlags_Float);
- real32 StrokeWidthMin = 0;
- real32 StrokeWidthMax = 1024;
- ImGui::DragScalar("Stroke width", ImGuiDataType_Float, &Opt->StrokeWidth, 1, &StrokeWidthMin, &StrokeWidthMax, "%.3f");
-}
-
-static void
ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
{
ImGuiStyle& style = ImGui::GetStyle();
@@ -196,7 +176,7 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor
State_BindBrushTexture(Memory, &State->Brush, 4);
}
} else if (State->Tool == tool_pen && State->MostRecentlySelectedLayer == -1) {
- ImGui_Opt_Shape(&State->Pen.Opt);
+ // ImGui_Opt_Shape(&State->Pen.Opt);
}
ImGui::End();
diff --git a/src/imgui_ui_properties.cpp b/src/imgui_ui_properties.cpp
index c6b710c..d89f2f0 100644
--- a/src/imgui_ui_properties.cpp
+++ b/src/imgui_ui_properties.cpp
@@ -390,7 +390,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui_Properties_CurvesUI(State, Memory, io, Effect, Property, SortedPointStart);
c = EffectHeader->Property_Count; // Causes this loop to only iterate once.
} else if (EffectHeader->DisplayType == effect_display_type_levels) {
- ImGui::Text("Levels!");
+ ImGui::Text("Levels");
uint32 VisibleChannel = *(uint32 *)&Effect->ExtraData[0];
real32 *P_Left = 0, *P_Mid = 0, *P_Right = 0;
if (VisibleChannel == 0) {
@@ -431,6 +431,25 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
State->UpdateFrame = true;
}
}
+ if (Layer->IsShapeLayer) {
+ shape_options *Opt = &Layer->Shape.Opt;
+ // TODO(fox): Combine with RGBA function?
+ char *Names[3] = { "Fill only", "Stroke only", "Fill and stroke" };
+ if (ImGui::BeginListBox("Shape render type")) {
+ for (int i = 0; i < 3; i++) {
+ if (ImGui::Selectable(Names[i], (Opt->Visibility == i))) {
+ Opt->Visibility = i;
+ }
+ }
+ ImGui::EndListBox();
+ }
+ ImGui::ColorEdit4("Fill color", (real32 *)&Opt->FillCol, ImGuiColorEditFlags_Float);
+ ImGui::ColorEdit4("Stroke color", (real32 *)&Opt->StrokeCol, ImGuiColorEditFlags_Float);
+ real32 StrokeWidthMin = 0;
+ real32 StrokeWidthMax = 1024;
+ ImGui::DragScalar("Stroke width", ImGuiDataType_Float, &Opt->StrokeWidth, 1, &StrokeWidthMin, &StrokeWidthMax, "%.3f");
+ // State->UpdateFrame = true;
+ }
ImGui::End();
} else {
ImGui::Begin("Properties: empty###Properties");
diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp
index 92a08f6..3a5eca0 100644
--- a/src/imgui_ui_timeline.cpp
+++ b/src/imgui_ui_timeline.cpp
@@ -322,7 +322,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
Bezier_Interact_Evaluate(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment);
PointPos[0].x += Frame_Offset;
- ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[2]) };
+ ImVec2 Keyframe_LocalPos[3] = { ImVec2_(PointPos[0]), ImVec2_(PointPos[0] + PointPos[1]), ImVec2_(PointPos[0] + PointPos[2]) };
ImVec2 Keyframe_LocalPos_Ratio[3];
for (int b = 0; b < 3; b++) {
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index e21c1a6..9563d63 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -32,6 +32,66 @@ ImGui_Viewport_Toolbar(project_state *State, ImDrawList *draw_list)
}
static void
+ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, shape_layer *Shape, block_composition *MainComp, ImDrawList *draw_list)
+{
+ if (Shape->Point_Count) {
+ uint32 wcol = IM_COL32(00, 00, 80, 255);
+ v2 CompUV = State->LastClickedPoint;
+ ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
+ UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+ bezier_point *Point_0 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Shape->Point_Count - 1, 1);
+ bezier_point *Point_1 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, 0, 1);
+ Assert(Shape->Contiguous);
+ int i = 0;
+ while (i < Shape->Point_Count) {
+ ImVec2 CompDimensions = ImVec2(MainComp->Width, MainComp->Height);
+ ImVec2 ScreenPoint_0[3];
+ ImVec2 ScreenPoint_1[3];
+
+ for (int i = 0; i < 3; i++) {
+ ImVec2 Point = (i == 0) ? ImVec2_(Point_0->Pos[0]) : ImVec2_(Point_0->Pos[0] + Point_0->Pos[i]);
+ ImVec2 Point_Ratio = Point / CompDimensions;
+ ScreenPoint_0[i] = UI->CompPos + Point_Ratio * UI->CompZoom;
+ }
+ for (int i = 0; i < 3; i++) {
+ ImVec2 Point = (i == 0) ? ImVec2_(Point_1->Pos[0]) : ImVec2_(Point_1->Pos[0] + Point_1->Pos[i]);
+ ImVec2 Point_Ratio = Point / CompDimensions;
+ ScreenPoint_1[i] = UI->CompPos + Point_Ratio * UI->CompZoom;
+ }
+
+ if (Point_1->Type == interpolation_type_bezier)
+ draw_list->AddLine(ScreenPoint_0[1], ScreenPoint_0[2], wcol, 2.0f);
+ draw_list->AddNgon(ScreenPoint_0[0], 2, wcol, 8, 2.0f);
+
+ ImGui::PushID(i);
+ for (int a = 0; a < 3; a++) {
+ ImGui::PushID(a);
+ ImGui::SetCursorScreenPos(ScreenPoint_1[a]);
+ if (ImGui::Button("##bezhandle")) {
+ if (a == 0 && i == 0) {
+ History_Entry_Commit(Memory, "Close shape");
+ History_Action_Swap(Memory, F_File, sizeof(Shape->IsClosed), &Shape->IsClosed);
+ Shape->IsClosed = true;
+ History_Entry_End(Memory);
+ }
+ }
+ ImGui::PopID();
+ }
+ ImGui::PopID();
+ // draw_list->AddBezierCubic(ScreenPoint_0, ScreenPoint_R_0, ScreenPoint_L_1, ScreenPoint_1, IM_COL32(10, 10, 10, 255), 1.0f, 0);
+ // draw_list->AddLine(ScreenPoint_0, ScreenPoint_1, wcol, 2.0f);
+
+ i++;
+ if (i < Shape->Point_Count) {
+ Point_0 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i-1, 1);
+ Point_1 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ }
+ }
+ }
+}
+
+
+static void
ImGui_Viewport_BrushUI(project_state *State, memory *Memory, ImVec2 ViewportMin, ImVec2 ViewportMax, ImVec2 CompZoom, ImGuiIO io, uint16 Width, uint16 Height)
{
@@ -386,7 +446,8 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD
block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0]);
Data = Memory_PushScratch(Memory, sizeof(nvg_point) * 128);
int L_Width = 0, L_Height = 0;
- NumberOfVerts = NVG_FlattenPath(Memory, Bezier, 3, (nvg_point *)Data, &L_Width, &L_Height);
+ Assert(Layer->Shape.Contiguous);
+ NumberOfVerts = NVG_FlattenPath(Memory, &Layer->Shape, (nvg_point *)Data, &L_Width, &L_Height);
Width = L_Width;
Height = L_Height;
} else {
@@ -395,8 +456,6 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD
Height = Source->Height;
}
- v2 Point[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) };
-
layer_transforms T = Layer_GetTransforms(Layer);
if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) {
@@ -404,34 +463,39 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD
}
if (Layer->IsShapeLayer) {
+ /*
block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0]);
- // for (int i = 0; i < Layer->Shape.Point_Count; i++) {
- // v2 ThisPoint = Bezier->Point[i].Pos[0];
- // v2 Pos = TransformPoint(T, Width, Height, ThisPoint);
- // v2 CompUV = Pos / V2(MainComp->Width, MainComp->Height);
- // ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
- // UI->CompPos.y + CompUV.y * UI->CompZoom.y);
- // draw_list->AddNgon(ScreenPoint, 10, IM_COL32(10, 10, 10, 255), 8, 9.0f);
- // }
-
- // imgui code
-
- void *Data2 = Memory_PushScratch(Memory, sizeof(real32) * 3 * 256);
- uint32 GL_PointCount = NVG_ExpandStroke(Memory, Bezier, NumberOfVerts, (nvg_point *)Data, (real32 *)Data2);
-
- v2 L_Pos[4] = { Bezier->Point[0].Pos[0], Bezier->Point[0].Pos[2], Bezier->Point[1].Pos[1], Bezier->Point[1].Pos[0] };
- L_Pos[1] = L_Pos[1] + L_Pos[0];
- L_Pos[2] = L_Pos[2] + L_Pos[3];
- ImVec2 ScreenPoint[4];
- for (int i = 0; i < 4; i++) {
- v2 Pos = TransformPoint(T, Width, Height, L_Pos[i]);
+ for (int i = 0; i < Layer->Shape.Point_Count; i++) {
+ bezier_point Point = Bezier->Point[i];
+ v2 Pos = TransformPoint(T, Width, Height, Point.Pos[0]);
v2 CompUV = Pos / V2(MainComp->Width, MainComp->Height);
- ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
- UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+ ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
+ UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+ draw_list->AddNgon(ScreenPoint, 10, IM_COL32(10, 10, 10, 255), 8, 9.0f);
}
- draw_list->AddNgon(ScreenPoint[0], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f);
- draw_list->AddNgon(ScreenPoint[3], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f);
- draw_list->AddBezierCubic(ScreenPoint[0],ScreenPoint[1],ScreenPoint[2],ScreenPoint[3], IM_COL32(10, 10, 10, 255), 1.0f, 0);
+ for (int i = 1; i < Layer->Shape.Point_Count; i++) {
+ if (Bezier->Point[i].Type == interpolation_type_bezier) {
+ v2 L_Pos[4] = { Bezier->Point[i-1].Pos[0], Bezier->Point[i-1].Pos[2], Bezier->Point[i].Pos[1], Bezier->Point[i].Pos[0] };
+ L_Pos[1] = L_Pos[1] + L_Pos[0];
+ L_Pos[2] = L_Pos[2] + L_Pos[3];
+ ImVec2 ScreenPoint[4];
+ for (int i = 0; i < 4; i++) {
+ v2 Pos = TransformPoint(T, Width, Height, L_Pos[i]);
+ v2 CompUV = Pos / V2(MainComp->Width, MainComp->Height);
+ ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
+ UI->CompPos.y + CompUV.y * UI->CompZoom.y);
+ }
+ draw_list->AddNgon(ScreenPoint[0], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f);
+ draw_list->AddNgon(ScreenPoint[3], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f);
+ draw_list->AddBezierCubic(ScreenPoint[0],ScreenPoint[1],ScreenPoint[2],ScreenPoint[3], IM_COL32(10, 10, 10, 255), 1.0f, 0);
+ } else {
+ }
+ }
+ */
+ ImGui_Viewport_ShapeUI(State, Memory, UI, &Layer->Shape, MainComp, draw_list);
+
+ void *Data2 = Memory_PushScratch(Memory, sizeof(real32) * 3 * 256);
+ uint32 GL_PointCount = NVG_ExpandStroke(Memory, NumberOfVerts, Layer->Shape.Opt.StrokeWidth, Layer->Shape.IsClosed, (nvg_point *)Data, (real32 *)Data2);
// test code
@@ -456,9 +520,10 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD
Memory_PopScratch(Memory, sizeof(nvg_point) * 128);
}
+ v2 BoundingPoint[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) };
v2 NewPos[5];
for (int i = 0; i < 5; i++) {
- NewPos[i] = TransformPoint(T, Width, Height, Point[i]);
+ NewPos[i] = TransformPoint(T, Width, Height, BoundingPoint[i]);
}
int i = 0;
@@ -554,7 +619,9 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
}
-
+ shape_layer *Shape = &UI->Shape;
+ if (State->Tool == tool_pen && State->Interact_Active == interact_type_none && State->MostRecentlySelectedLayer == -1)
+ ImGui_Viewport_ShapeUI(State, Memory, UI, Shape, MainComp, draw_list);
// Interactions for dragging and zooming
ImGui::SetCursorScreenPos(ViewportMin);
@@ -573,7 +640,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
if (IsHovered && IsActivated && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
{
- State->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
+ State->LastClickedPoint = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
if (!ImGui::IsKeyDown(ImGuiKey_Z)) {
if (State->Tool == tool_brush && State->Interact_Active != interact_type_brush) {
@@ -654,21 +721,39 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
RenderQueue_AddBlit(State);
}
}
+
if (State->Tool == tool_pen && State->Interact_Active == interact_type_none && State->MostRecentlySelectedLayer == -1) {
- v2 CompUV = State->TempZoomRatio;
+ v2 CompUV = State->LastClickedPoint;
ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
UI->CompPos.y + CompUV.y * UI->CompZoom.y);
- ImVec2 Vector = io.MousePos - ScreenPoint;
- if (IsActive && !OtherActions) {
- uint32 wcol = IM_COL32(00, 00, 80, 255);
- draw_list->AddLine(ScreenPoint - Vector, io.MousePos, wcol, 2.0f);
- draw_list->AddNgon(ScreenPoint, 2, wcol, 8, 2.0f);
+ shape_layer *Shape = &UI->Shape;
+ ImGui::OpenPopupOnItemClick("shapecreate", ImGuiPopupFlags_MouseButtonRight);
+ if (ImGui::BeginPopup("shapecreate")) {
+ if (ImGui::Selectable("Create shape layer")) {
+ State->HotkeyInput = hotkey_newlayer_shape;
+ }
+ ImGui::EndPopup();
}
- if (IsDeactivated) {
- State->HotkeyInput = hotkey_newlayer_shape;
- if (fabs(Vector.x) > 5 && fabs(Vector.y) > 5) {
- State->HotkeyExtra[0] = Vector.x;
- State->HotkeyExtra[1] = Vector.y;
+ if (!Shape->IsClosed) {
+ if (IsHovered && IsActivated && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
+ {
+ }
+ ImVec2 Vector = io.MousePos - ScreenPoint;
+ uint32 wcol = IM_COL32(00, 00, 80, 255);
+ if (IsActive && !OtherActions) {
+ draw_list->AddLine(ScreenPoint - Vector, io.MousePos, wcol, 2.0f);
+ draw_list->AddNgon(ScreenPoint, 2, wcol, 8, 2.0f);
+ }
+ if (IsDeactivated && !OtherActions && !ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
+ interpolation_type Type = interpolation_type_bezier;
+ if (fabs(Vector.x) < 5 && fabs(Vector.y) < 5) {
+ Type = interpolation_type_linear;
+ Vector = ImVec2(0, 0);
+ }
+ bezier_point PointData = { 1, { CompUV * V2(MainComp->Width, MainComp->Height), V2(Vector.x, Vector.y), V2(-Vector.x, -Vector.y) }, Type, 0 };
+ History_Entry_Commit(Memory, "Bezier point");
+ Bezier_Add(Memory, F_File, Shape->Block_Bezier_Index, &Shape->Block_Bezier_Count, &Shape->Point_Count, PointData);
+ History_Entry_End(Memory);
}
}
}
@@ -693,8 +778,8 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
Distance *= -1;
UI->CompZoom.x += (Distance)*(real32)MainComp->Width/MainComp->Height;
UI->CompZoom.y += (Distance);
- UI->CompPos.x -= ((Distance)*(real32)MainComp->Width/MainComp->Height)*State->TempZoomRatio.x;
- UI->CompPos.y -= Distance*State->TempZoomRatio.y;
+ UI->CompPos.x -= ((Distance)*(real32)MainComp->Width/MainComp->Height)*State->LastClickedPoint.x;
+ UI->CompPos.y -= Distance*State->LastClickedPoint.y;
}
ImGui::SetCursorScreenPos(ImVec2(ViewportMin.x, ViewportMin.y + ViewportScale.y - FontSize*1.5));
diff --git a/src/include/debug.h b/src/include/debug.h
index 6321679..e1d8ccc 100644
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -37,7 +37,7 @@ struct project_debug
// NOTE(fox): Pixel count isn't thread safe; don't use with multithreading!
uint64 LayerCycleCount[64];
uint32 UndoState = 0;
- uint64 ScratchSize[6];
+ uint64 ScratchSize[32];
uint32 ScratchState = 0;
};
diff --git a/src/include/defines.h b/src/include/defines.h
index 8216f1c..1d4e147 100644
--- a/src/include/defines.h
+++ b/src/include/defines.h
@@ -36,7 +36,8 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like
#define MAX_MASKS 8
#define MAX_PROPERTIES_PER_EFFECT 80 // Kinda high since we want to support 8 xy points of Curves data across 5 channels.
#define MAX_KEYFRAME_BLOCKS 64
-#define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048
+// #define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048
+#define MAX_KEYFRAMES_PER_BLOCK 2
#define MAX_SELECTED_PROPERTIES 16
diff --git a/src/include/functions.h b/src/include/functions.h
index 53920cb..e7b5e44 100644
--- a/src/include/functions.h
+++ b/src/include/functions.h
@@ -12,15 +12,17 @@ static void Arbitrary_ShiftData(uint8 *Address_Start, uint8 *Address_End, uint64
static real32 Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 TargetX);
static bezier_point * Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists = 1);
+static bezier_point * Bezier_LookupAddress(memory *Memory, uint16 *Block_Bezier_Index, uint16 Index, bool32 AssertExists);
static void Bezier_Interact_Evaluate(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight = 1, real32 Y_Increment = 1);
// NOTE(fox): GraphZoomHeight and Y_Increment don't have to be specified if the Y value isn't needed, i.e. in Property_SortAll().
static void Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation);
+static void Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *Block_Bezier_Count, uint16 *PointCount, bezier_point PointData);
uint32 Bezier_CubicCalcPoints(v2 p1, v2 p2, v2 p3, v2 p4, void *Data, uint32 Size);
-void GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *PointData, uint32 GL_PointCount,
- layer_transforms T, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, int L_Width, int L_Height);
+static void GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount,
+ layer_transforms T, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, int L_Width, int L_Height, v4 Col, int RenderMode);
static void ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_file Sorted);
static void ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray);
diff --git a/src/include/main.h b/src/include/main.h
index 8590904..a39fe45 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -187,7 +187,7 @@ struct shape_options {
int Visibility;
v4 FillCol = {1, 1, 1, 1};
v4 StrokeCol = {1, 1, 1, 1};
- float StrokeWidth;
+ float StrokeWidth = 50;
};
struct shape_layer {
@@ -195,6 +195,7 @@ struct shape_layer {
uint16 Block_Bezier_Count;
uint16 Point_Count;
bool32 IsClosed;
+ bool32 Contiguous = 1; // No points have been deleted/added, so sorting isn't needed.
int Width;
int Height;
shape_options Opt;
@@ -207,7 +208,6 @@ enum timeline_mode
};
struct pen_state {
- shape_options Opt;
};
struct brush_state
@@ -378,7 +378,6 @@ struct project_state
int32 PreviewSource = -1;
hotkey_input HotkeyInput;
- real32 HotkeyExtra[4]; // bloat?
void *Dump1;
void *Dump2;
@@ -443,7 +442,7 @@ struct project_state
focused_window FocusedWindow; // Convenience for adding window-specific hotkeys.
bool32 SetFocus;
- v2 TempZoomRatio = V2(1, 1);
+ v2 LastClickedPoint = V2(1, 1);
};
// UI info that's saved to the file and is not part of the history tree
@@ -468,6 +467,8 @@ struct ui
bool32 StableEnabled = 0;
#endif
+ shape_layer Shape;
+
ImU32 LayerColors[16] = {
0xff8b1f1f,
0xffc25909,
diff --git a/src/include/my_math.h b/src/include/my_math.h
index 92d43b7..865f11c 100644
--- a/src/include/my_math.h
+++ b/src/include/my_math.h
@@ -66,14 +66,8 @@ inline v2 V2(ImVec2 A)
return(Result);
}
-inline ImVec2 V2(v2 A)
-{
- struct ImVec2 Result;
-
- Result.x = A.x;
- Result.y = A.y;
-
- return(Result);
+inline ImVec2 ImVec2_(v2 f) {
+ return { f.x, f.y };
}
inline v2i V2i(int32 x, int32 y)
diff --git a/src/layer.cpp b/src/layer.cpp
index c3d3d16..93db19d 100644
--- a/src/layer.cpp
+++ b/src/layer.cpp
@@ -107,16 +107,20 @@ Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memor
GL_UpdateTexture(&TestM, EffectBitmapAddress, Width, Height, BytesPerPixel, 1);
if (Layer->IsShapeLayer) {
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0]);
+ shape_layer *Shape = &Layer->Shape;
void *Data = Memory_PushScratch(Memory, sizeof(nvg_point) * 128);
- uint32 NumberOfVerts = NVG_FlattenPath(Memory, Bezier, 3, (nvg_point *)Data, L_Width, L_Height);
- void *Data2 = Memory_PushScratch(Memory, sizeof(real32) * 3 * 256);
- uint32 GL_PointCount = NVG_ExpandStroke(Memory, Bezier, NumberOfVerts, (nvg_point *)Data, (real32 *)Data2);
+ uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, L_Width, L_Height);
+ void *Data_Stroke = Memory_PushScratch(Memory, sizeof(real32) * 4 * 256);
+ uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, Shape->Opt.StrokeWidth, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke);
+ void *Data_Fill = Memory_PushScratch(Memory, sizeof(real32) * 4 * NumberOfVerts);
+ NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill);
layer_transforms T = Layer_GetTransforms(Layer);
- GL_RasterizeShape(&TestL, &TestM, Data2, GL_PointCount, T, Width, Height, BytesPerPixel, EffectBitmapAddress, *L_Width, *L_Height);
+ GL_RasterizeShape(&TestL, &TestM, Data_Stroke, Data_Fill, StrokeCount, NumberOfVerts, T,
+ Width, Height, BytesPerPixel, EffectBitmapAddress, *L_Width, *L_Height, Layer->Shape.Opt.StrokeCol, Shape->Opt.Visibility);
- Memory_PopScratch(Memory, sizeof(real32) * 3 * 256);
+ Memory_PopScratch(Memory, sizeof(real32) * 4 * NumberOfVerts);
+ Memory_PopScratch(Memory, sizeof(real32) * 4 * 256);
Memory_PopScratch(Memory, sizeof(nvg_point) * 128);
// Bitmap_StencilAlpha(SourceBitmapAddress, EffectBitmapAddress, Source->BytesPerPixel, Size);
@@ -350,7 +354,7 @@ Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_ar
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
layer_transforms T = Layer_GetTransforms(Layer);
- v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->TempZoomRatio);
+ v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->LastClickedPoint);
if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && Layer->IsSelected)
{
SelectionCount++;
@@ -364,7 +368,7 @@ Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_ar
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
layer_transforms T = Layer_GetTransforms(Layer);
- v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->TempZoomRatio);
+ v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Source->Width, Source->Height, State->LastClickedPoint);
if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected)
{
if (SelectionCount == 1) {
diff --git a/src/main.cpp b/src/main.cpp
index 9856143..27a985e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -783,11 +783,12 @@ int main(int argc, char *argv[]) {
#endif
#if DEBUG
-#if 0
+#if 1
sprintf(State->DummyName, "test");
- File_Open(File, State, &Memory, State->DummyName);
- State->UpdateFrame = true;
- // State->MostRecentlySelectedLayer = 0;
+ if (File_Open(File, State, &Memory, State->DummyName)) {
+ State->UpdateFrame = true;
+ State->MostRecentlySelectedLayer = 0;
+ }
#else
// uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/yu.webm");
// block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, SourceIndex);
@@ -877,15 +878,7 @@ int main(int argc, char *argv[]) {
} break;
case hotkey_newlayer_shape:
{
- block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(&Memory, F_Precomps, File->PrincipalCompIndex);
- v2 Point = State->TempZoomRatio * V2(MainComp->Width, MainComp->Height);
- v2 Vector = V2(0, 0);
- if (State->HotkeyExtra[0] != 0) {
- Vector = V2(State->HotkeyExtra[0], State->HotkeyExtra[1]);
- State->HotkeyExtra[0] = 0;
- State->HotkeyExtra[1] = 0;
- }
- Project_ShapeLayer_New(File, State, &Memory, Point, Vector);
+ Project_ShapeLayer_New(File, State, &Memory);
} break;
case hotkey_newlayer_source:
{
diff --git a/src/nanovg.cpp b/src/nanovg.cpp
index 06b2910..5627b5f 100644
--- a/src/nanovg.cpp
+++ b/src/nanovg.cpp
@@ -128,20 +128,23 @@ static real32 * NVG_RoundCap(nvg_point * Point, real32 *StrokeData,
// NOTE(fox): We only have to care about winding if we want to do HW accelerated
// shape subtraction with the stencil buffer (I think).
static uint32
-NVG_FlattenPath(void *Memory, block_bezier *Bezier, int PointCount, nvg_point *PointData, int *Width, int *Height)
+NVG_FlattenPath(memory *Memory, shape_layer *Shape, nvg_point *PointData, int *Width, int *Height)
{
uint32 NumberOfVerts = 0;
nvg_point *PointPlayhead = PointData;
- for (int i = 0; i < PointCount; i++) {
- if (i == 0 || Bezier->Point[i].Type == interpolation_type_linear) {
- *(v2 *)PointPlayhead = Bezier->Point[i].Pos[0];
- if (i != 0 && i != (PointCount - 1)) {
+ for (int i = 0; i < Shape->Point_Count; i++) {
+ bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+#if 0
+ if (i == 0 || Point->Type == interpolation_type_linear) {
+ *(v2 *)PointPlayhead = Point->Pos[0];
+ if (i != 0 && i != (Shape->Point_Count - 1)) {
PointPlayhead->Flags |= NVG_PT_CORNER;
}
PointPlayhead++;
NumberOfVerts++;
- } else if (Bezier->Point[i].Type == interpolation_type_bezier) {
- v2 Pos[4] = { Bezier->Point[i].Pos[0], Bezier->Point[i].Pos[1], Bezier->Point[i+1].Pos[2], Bezier->Point[i+1].Pos[0] };
+ } else if (Point->Type == interpolation_type_bezier) {
+ bezier_point *Point_1 = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i-1, 1);
+ v2 Pos[4] = { Point->Pos[0], Point->Pos[1], Point_1->Pos[2], Point_1->Pos[0] };
Pos[1] = Pos[1] + Pos[0];
Pos[2] = Pos[2] + Pos[3];
NumberOfVerts += Bezier_CubicCalcPoints(Pos[3], Pos[2], Pos[1], Pos[0], PointPlayhead, sizeof(nvg_point));
@@ -151,6 +154,14 @@ NVG_FlattenPath(void *Memory, block_bezier *Bezier, int PointCount, nvg_point *P
} else {
Assert(0);
}
+#else
+ *(v2 *)PointPlayhead = Point->Pos[0];
+ if (i != 0 && i != (Shape->Point_Count - 1)) {
+ PointPlayhead->Flags |= NVG_PT_CORNER;
+ }
+ PointPlayhead++;
+ NumberOfVerts++;
+#endif
}
nvg_point *Point = &PointData[NumberOfVerts - 1];
nvg_point *NextPoint = PointData;
@@ -178,17 +189,26 @@ NVG_FlattenPath(void *Memory, block_bezier *Bezier, int PointCount, nvg_point *P
real32 MiterLimit = 2.4f;
static uint32
-NVG_ExpandStroke(void *Memory, block_bezier *Bezier, int NumberOfVerts, nvg_point *PointData, real32 *StrokeData)
+NVG_ExpandStroke(void *Memory, int NumberOfVerts, real32 StartWidth, bool32 IsClosed, nvg_point *PointData, real32 *StrokeData)
{
- real32 Width = 50 * 0.5;
- nvg_point *Point = PointData;
- nvg_point *NextPoint = &PointData[1];
+ real32 Width = StartWidth * 0.5;
int ncap = 12;
real32 *StartingStrokeData = StrokeData;
- StrokeData = NVG_RoundCap(Point, StrokeData, Point->dx, Point->dy, Width, ncap, 0.5, 0.5, 0);
+ nvg_point *Point = &PointData[NumberOfVerts - 1];
+ nvg_point *NextPoint = PointData;
+ int Start = 0;
+ int LoopAmount = NumberOfVerts;
+
+ if (!IsClosed) {
+ Point = PointData;
+ NextPoint = &PointData[1];
+ Start = 1;
+ LoopAmount = NumberOfVerts - 1;
+ StrokeData = NVG_RoundCap(Point, StrokeData, Point->dx, Point->dy, Width, ncap, 0.5, 0.5, 0);
+ }
- for (int i = 1; i < (NumberOfVerts - 1); i++) {
+ for (int i = Start; i < LoopAmount; i++) {
real32 dlx0, dly0, dlx1, dly1, dmr2, cross, limit;
dlx0 = Point->dy;
@@ -223,7 +243,7 @@ NVG_ExpandStroke(void *Memory, block_bezier *Bezier, int NumberOfVerts, nvg_poin
// Check to see if the corner needs to be beveled.
if (NextPoint->Flags & NVG_PT_CORNER) {
// if ((dmr2 * MiterLimit*MiterLimit) < 1.0f) r // || lineJoin == NVG_BEVEL || lineJoin == NVG_ROUND) {
- NextPoint->Flags |= NVG_PT_BEVEL;
+ // NextPoint->Flags |= NVG_PT_BEVEL;
// }
}
@@ -239,9 +259,24 @@ NVG_ExpandStroke(void *Memory, block_bezier *Bezier, int NumberOfVerts, nvg_poin
Point = NextPoint++;
}
- StrokeData = NVG_RoundCap(NextPoint, StrokeData, Point->dx, Point->dy, Width, ncap, 0.5, 0.5, 1);
+ if (!IsClosed) {
+ StrokeData = NVG_RoundCap(NextPoint, StrokeData, Point->dx, Point->dy, Width, ncap, 0.5, 0.5, 1);
+ } else {
+ StrokeData = NVG_Point(StrokeData, StartingStrokeData[0], StartingStrokeData[1], 0, 0);
+ StrokeData = NVG_Point(StrokeData, StartingStrokeData[4], StartingStrokeData[5], 0, 0);
+ }
int GL_PointCount = (StrokeData - StartingStrokeData) / 4;
return GL_PointCount;
}
+
+static void
+NVG_ExpandFill(void *Memory, int NumberOfVerts, nvg_point *PointData, real32 *FillData)
+{
+ nvg_point *Point = PointData;
+ for (int i = 0; i < NumberOfVerts; i++) {
+ FillData = NVG_Point(FillData, Point->x, Point->y, 0, 0);
+ Point++;
+ }
+}