summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-02-17 17:20:18 -0500
committerFox Caminiti <fox@foxcam.net>2023-02-17 17:20:18 -0500
commit02870398a99fab6351182fba407d7d733affa5a1 (patch)
treefb5f4744f46e9d7816072e4d01547034bca04bb2
parentfffb3474ee0321d73a47db01dbc4b6b19670ddc5 (diff)
blend mode rendering halfway implemented
-rw-r--r--src/bezier.cpp58
-rw-r--r--src/createcalls.cpp148
-rw-r--r--src/ffmpeg_backend.cpp10
-rw-r--r--src/gl_calls.cpp287
-rw-r--r--src/imgui_ui.cpp26
-rw-r--r--src/imgui_ui_properties.cpp6
-rw-r--r--src/imgui_ui_timeline.cpp52
-rw-r--r--src/imgui_ui_viewport.cpp47
-rw-r--r--src/include/all.h29
-rw-r--r--src/include/gl_calls.h5
-rw-r--r--src/include/main.h15
-rw-r--r--src/layer.cpp2
-rw-r--r--src/main.cpp193
-rw-r--r--src/memory.cpp11
-rw-r--r--src/prenderer.cpp1
-rw-r--r--src/sorted.cpp6
16 files changed, 734 insertions, 162 deletions
diff --git a/src/bezier.cpp b/src/bezier.cpp
index dd3974d..8bfcf2b 100644
--- a/src/bezier.cpp
+++ b/src/bezier.cpp
@@ -134,14 +134,6 @@ Bezier_LookupAddress(memory *Memory, uint16 *Block_Bezier_Index, uint16 Index, b
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!
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], AssertExists);
- return &Bezier->Point[Index];
-}
-
static void
Bezier_Interact_Evaluate(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight, real32 Y_Increment)
{
@@ -191,41 +183,31 @@ Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Ind
}
static void
-Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation)
+Bezier_Delete(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *PointCount, uint16 *ArrayLocation)
{
- if (!Property->Block_Bezier_Count) {
- // TODO(fox): Test multiple keyframe blocks!
- Assert(Property->Keyframe_Count < MAX_KEYFRAMES_PER_BLOCK);
- Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier);
- block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], 0);
- Bezier->Occupied = true;
- History_Action_Swap(Memory, TableName, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count);
- Property->Block_Bezier_Count++;
- }
- // First check to see if the point to add overlaps an existing keyframe:
- if (ArrayLocation) {
- for (int p = 0; p < Property->Keyframe_Count; p++) {
- int k = ArrayLocation[p];
- bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
- if (Point->Pos[0].x == PointData.Pos[0].x) {
- History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
- *Point = PointData;
- return;
- }
+ for (int p = 0; p < *PointCount; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *Point = Bezier_LookupAddress(Memory, Block_Bezier_Index, k);
+ if (Point->IsSelected) {
+ History_Action_Swap(Memory, F_Bezier, sizeof(Point->Occupied), &Point->Occupied);
+ Point->Occupied = 0;
+ History_Action_Swap(Memory, TableName, sizeof(*PointCount), PointCount);
+ *PointCount -= 1;
}
}
- int k = 0;
- for (;;) {
- bezier_point *Point = Bezier_LookupAddress(Memory, Property, k, 0);
- if (!Point->Occupied) {
- History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
- *Point = PointData;
- History_Action_Swap(Memory, TableName, sizeof(Property->Keyframe_Count), &Property->Keyframe_Count);
- Property->Keyframe_Count++;
- return;
+}
+
+static int32
+Bezier_CheckSameX(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 KeyframeCount, uint16 *ArrayLocation, real32 ValX)
+{
+ for (int p = 0; p < KeyframeCount; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *Point = Bezier_LookupAddress(Memory, Block_Bezier_Index, k);
+ if (Point->Pos[0].x == ValX) {
+ return k;
}
- k++;
}
+ return -1;
}
// return all points
diff --git a/src/createcalls.cpp b/src/createcalls.cpp
index 56cf4d8..d7fb4b7 100644
--- a/src/createcalls.cpp
+++ b/src/createcalls.cpp
@@ -187,17 +187,116 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
return -1;
}
-
+#if WINDOWS
+#else
+#include <dirent.h>
+static void
+File_LoadDirectory(project_data *File, project_state *State, memory *Memory, char *DirString)
+{
+ DIR *Directory = opendir(DirString);
+ if (!Directory) {
+ PostMsg(State, "Directory couldn't be read.");
+ return;
+ }
+ for (;;) {
+ dirent *DirEnt = readdir(Directory);
+ if (DirEnt != NULL) {
+ if (DirEnt->d_name[0] != '.') {
+ char buf[1024];
+ sprintf(buf, "%s/%s", DirString, DirEnt->d_name);
+ Source_Generate(File, State, Memory, buf);
+ }
+ } else {
+ closedir(Directory);
+ return;
+ }
+ }
+}
+#endif
static void
-Property_AddKeyframe(memory *Memory, memory_table_list TableName, property_channel *Property, int Frame, uint16 *ArrayLocation)
+Property_AddKeyframe(memory *Memory, memory_table_list TableName, uint16 *ArrayLocation, property_channel *Property, int Frame)
{
History_Entry_Commit(Memory, "Add keyframe");
bezier_point Point = { 1, {(real32)Frame, Property->CurrentValue, -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
- Bezier_Add(Memory, TableName, Property, Point, ArrayLocation);
+ int Idx = Bezier_CheckSameX(Memory, TableName, Property->Block_Bezier_Index, Property->Keyframe_Count, ArrayLocation, Point.Pos[0].x);
+ if (Idx == -1) {
+ Bezier_Add(Memory, TableName, Property->Block_Bezier_Index, &Property->Block_Bezier_Count, &Property->Keyframe_Count, Point);
+ } else {
+ Assert(0);
+ }
+ History_Entry_End(Memory);
+}
+
+// TODO(fox): Only works with transform keyframes for now!
+static void
+Property_AddKeyframe_AllSelected(project_data *File, project_state *State, memory *Memory,
+ memory_table_list TableName, sorted_layer_array *SortedLayerArray, sorted_comp_array *SortedCompArray, uint16 *SortedKeyframeArray,
+ uint16 Idx, int Frame)
+{
+ History_Entry_Commit(Memory, "Add keyframe");
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
+ {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected & 0x01) {
+ sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Composition_Index);
+ uint16 *ArrayLocation = SortedKeyframeArray + SortedLayerStart->SortedKeyframeStart;
+ property_channel *Property = &Layer->Property[Idx];
+ bezier_point NewPoint = { 1, {(real32)Frame, Property->CurrentValue, -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
+ int Idx = Bezier_CheckSameX(Memory, TableName, Property->Block_Bezier_Index, Property->Keyframe_Count, ArrayLocation, NewPoint.Pos[0].x);
+ if (Idx == -1) {
+ Bezier_Add(Memory, TableName, Property->Block_Bezier_Index, &Property->Block_Bezier_Count, &Property->Keyframe_Count, NewPoint);
+ } else {
+ bezier_point *Point = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, Idx);
+ History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point);
+ *Point = NewPoint;
+ }
+ }
+ }
History_Entry_End(Memory);
}
+static void
+Bezier_Delete_Selected(project_data *File, project_state *State, memory *Memory,
+ sorted_layer_array *SortedLayerArray, sorted_comp_array *SortedCompArray,
+ sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray)
+{
+ History_Entry_Commit(Memory, "Delete keyframes");
+#if 0
+ for (int c = 0; c < File->Comp_Count; c++) {
+ sorted_comp_array SortedCompStart = SortedCompArray[c];
+ sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, c);
+ for (int i = 0; i < SortedCompStart.LayerCount; i++) {
+ sorted_layer_array *SortedLayer = &SortedLayerStart[i];
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index);
+ sorted_property_array *InfoLocation = SortedPropertyStart + SortedLayerStart->SortedPropertyStart;
+ uint16 *ArrayLocation = SortedKeyframeArray + SortedLayerStart->SortedKeyframeStart;
+ int h = 0, c = 0, p = 0;
+ property_channel *Property = NULL;
+ block_effect *Effect = NULL;
+ while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p))
+ {
+ if ((State->TimelineMode != timeline_mode_graph) && !Property->IsToggled)
+ continue;
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
+ if (PointAddress->IsSelected) {
+ History_Action_Swap(Memory, F_Bezier, sizeof(PointAddress->Occupied), &PointAddress->Occupied);
+ PointAddress->Occupied = 0;
+ History_Action_Swap(Memory, F_Layers, sizeof(*PointCount), PointCount);
+ *PointCount -= 1;
+ }
+ }
+ }
+ }
+ }
+#endif
+ History_Entry_End(Memory);
+}
+
+
static property_channel
Property_InitFloat(real32 Val, real32 ScrubVal, real32 MinVal, real32 MaxVal, bool32 AlwaysInteger) {
property_channel Property = {};
@@ -311,9 +410,9 @@ Keyframe_Commit(project_data *File, project_state *State, memory *Memory,
{
if ((State->TimelineMode != timeline_mode_graph) && !Property->IsToggled)
continue;
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
int k = ArrayLocation[p];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
if (PointAddress->IsSelected) {
v2 NewPos[3];
Bezier_Interact_Evaluate(State, PointAddress, NewPos);
@@ -427,8 +526,8 @@ void Clipboard_Store(project_data *File, project_state *State, memory *Memory, s
clipboard_channel *Channel = &Contents->Channel[Contents->ChannelCount];
bezier_point *FirstPoint = NULL;
int TimeOffset = 0;
- for (int p = 0; p < Property->Keyframe_Count; p++) {
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]);
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, ArrayLocation[p]);
if (PointAddress->IsSelected) {
if (!FirstPoint) {
FirstPoint = PointAddress;
@@ -488,27 +587,25 @@ void Slide_Test(project_data *File, project_state *State, memory *Memory, sorted
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Interact_Layer->Index);
v2 CompUV = V2(State->Interact_Offset[0], State->Interact_Offset[1]);
v2 CompPos = CompUV * CompDimensions;
- // v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, CompUV, SortedCompArray, SortedLayerArray, Interact_Layer->Index);
v2 LayerPos = V2(Layer->x.CurrentValue, Layer->y.CurrentValue);
int Width, Height;
Layer_GetDimensions(Memory, Layer, &Width, &Height);
v2 Difference = V2(fabs(CompPos.x - LayerPos.x), fabs(CompPos.y - LayerPos.y));
printf("Diff: %.1f, %.1f\n", Difference.x, Difference.y);
- if (Difference.x < Threshold &&
- Difference.y < Threshold)
- Assert(0);
+ // if (Difference.x < Threshold &&
+ // Difference.y < Threshold)
}
}
-void Property_MinMax_X(memory *Memory, project_state *State, property_channel *Property,
+void Property_MinMax_X(memory *Memory, project_state *State, uint16 *Block_Bezier_Index, uint16 LastIndex,
uint16 *ArrayLocation, real32 *Min, real32 *Max)
{
v2 FirstPointPos[3];
- bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[0]);
+ bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Block_Bezier_Index, ArrayLocation[0]);
Bezier_Interact_Evaluate(State, FirstPointAddress, FirstPointPos);
*Min = FirstPointPos[0].x;
v2 LastPointPos[3];
- bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[Property->Keyframe_Count - 1]);
+ bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Block_Bezier_Index, ArrayLocation[LastIndex]);
Bezier_Interact_Evaluate(State, LastPointAddress, LastPointPos);
*Max = LastPointPos[0].x;
}
@@ -517,17 +614,17 @@ void Property_MinMax_Y(memory *Memory, project_state *State, property_channel *P
{
if (Evaluate) {
v2 MinYPointPos[3];
- bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyStart->MinYIndex);
+ bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, PropertyStart->MinYIndex);
Bezier_Interact_Evaluate(State, MinYPointAddress, MinYPointPos);
*Min = MinYPointPos[0].y;
v2 MaxYPointPos[3];
- bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyStart->MaxYIndex);
+ bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, PropertyStart->MaxYIndex);
Bezier_Interact_Evaluate(State, MaxYPointAddress, MaxYPointPos);
*Max = MaxYPointPos[0].y;
} else {
- bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyStart->MinYIndex);
+ bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, PropertyStart->MinYIndex);
*Min = MinYPointAddress->Pos[0].y;
- bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyStart->MaxYIndex);
+ bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, PropertyStart->MaxYIndex);
*Max = MaxYPointAddress->Pos[0].y;
}
}
@@ -645,9 +742,9 @@ void File_DeselectAllKeyframes(project_data *File, project_state *State, memory
block_effect *Effect = NULL;
while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p))
{
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
int k = ArrayLocation[p];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
PointAddress->IsSelected = 0;
}
}
@@ -678,12 +775,13 @@ Project_Layer_Delete(project_data *File, project_state *State, memory *Memory)
}
}
+// TODO(fox): make property-agnostic
static bool32
-Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *ArrayLocation)
+Property_IsGraphSelected(memory *Memory, uint16 *Block_Bezier_Index, uint16 *ArrayLocation, uint16 KeyframeCount)
{
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < KeyframeCount; p++) {
int k = ArrayLocation[p];
- bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *Point = Bezier_LookupAddress(Memory, Block_Bezier_Index, k);
if (Point->IsSelected)
return 1;
}
@@ -1054,8 +1152,8 @@ void Precomp_UICreateButton(project_data *File, project_state *State, memory *Me
block_layer *PrecompLayer = Layer_Init(File, Memory);
bezier_point Point0 = { 1, {0, 0, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
bezier_point Point1 = { 1, {(real32)NewComp->Frame_End, (real32)NewComp->Frame_End, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
- Bezier_Add(Memory, F_Layers, &PrecompLayer->time, Point0, NULL);
- Bezier_Add(Memory, F_Layers, &PrecompLayer->time, Point1, NULL);
+ Bezier_Add(Memory, F_Layers, PrecompLayer->time.Block_Bezier_Index, &PrecompLayer->time.Block_Bezier_Count, &PrecompLayer->time.Keyframe_Count, Point0);
+ Bezier_Add(Memory, F_Layers, PrecompLayer->time.Block_Bezier_Index, &PrecompLayer->time.Block_Bezier_Count, &PrecompLayer->time.Keyframe_Count, Point1);
PrecompLayer->IsPrecomp = true;
Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, PrecompLayer));
PrecompLayer->Block_Source_Index = File->Comp_Count - 1;
diff --git a/src/ffmpeg_backend.cpp b/src/ffmpeg_backend.cpp
index 510188b..b688725 100644
--- a/src/ffmpeg_backend.cpp
+++ b/src/ffmpeg_backend.cpp
@@ -159,10 +159,12 @@ void AV_GetDuration(av_info *AV, av_stream_info *Stream, uint64 *Duration, real3
int32 err = 0;
bool32 EndOfFile = 0;
uint64 TestDuration = 0;
+ uint64 BestTimestamp = 0;
while (err >= 0) {
if (AV_TryFrame(AV, Stream->CodecContext, &err, &EndOfFile, Stream->Index))
{
TestDuration = AV->Frame->pts;
+ BestTimestamp = AV->Frame->best_effort_timestamp;
}
av_frame_unref(AV->Frame);
if (EndOfFile)
@@ -174,8 +176,15 @@ void AV_GetDuration(av_info *AV, av_stream_info *Stream, uint64 *Duration, real3
if (Stream->Stream->nb_frames > 0) {
*SecondCount = Stream->Stream->nb_frames / FPS;
} else if (AV->Video.CodecContext) {
+#if 1
+ // NOTE(fox): I'm going to believe this is accurate. The
+ // AVFormatContext->duration estimate doesn't work when the video
+ // stream's frame count differs greatly from the file's.
+ *SecondCount = (real32)*Duration / (real32)Stream->Stream->time_base.den;
+#else
Assert(AV->FileFormatContext->duration > 0);
*SecondCount = (real32)AV->FileFormatContext->duration / 1000000LL;
+#endif
}
}
@@ -344,6 +353,7 @@ void AV_LoadVideoFrame(memory *Memory, block_source *Source, av_info *AV, int32
real32 TotalFrames = AV->SecondCount * Source->FPS;
int64 SeekPTS = (int64)(((real64)FrameToSeek / TotalFrames) * AV->PTSDuration);
+ SeekPTS += AV->Video.Stream->start_time;
int64 AveragePTS = AV->PTSDuration / TotalFrames;
bool32 EndOfFile = 0;
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
index 5d65100..39dba50 100644
--- a/src/gl_calls.cpp
+++ b/src/gl_calls.cpp
@@ -40,6 +40,7 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"in vec2 TexCoord;\n"
"uniform sampler2D Texture;\n"
+"uniform sampler2D Texture1;\n"
"uniform int FragmentMode;\n"
"uniform vec3 InputCol;\n"
"void main()\n"
@@ -47,55 +48,137 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n"
"vec4 Col = texture(Texture, TexCoord);\n"
" if (FragmentMode == 0) {\n"
" FragColor = Col;\n"
-"} else {\n"
+"} else if (FragmentMode == 1) {\n"
" FragColor = vec4(InputCol, Col.a);\n"
+"} else if (FragmentMode == 2) {\n"
+" FragColor = Col;\n"
+"} else {\n"
+" vec4 Dest = texture(Texture1, TexCoord);\n"
+" FragColor = Dest + Col;\n"
+" FragColor = ((1.0f - Dest * 2) * Col * Col) + (Dest * 2 * Col);\n"
+" FragColor.a = Col.a;\n"
"}\n"
"}\0";
-static void GL_InitDefaultShader() {
- DefaultVertexShader = glCreateShader(GL_VERTEX_SHADER);
+#if 1
+const char *BlendVertexShaderSource = "#version 330 core\n"
+"layout (location = 0) in vec2 Point;\n"
+"layout (location = 1) in vec2 aTexCoord;\n"
+"layout (location = 2) in vec2 aTexCoordBlend;\n"
+"out vec2 TexCoord;\n"
+"out vec2 TexCoordBlend;\n"
+"uniform vec2 CompDimensions;\n"
+"uniform vec2 ScreenDimensions;\n"
+"uniform vec2 UIOffset;\n"
+"uniform vec2 UIZoom;\n"
+"void main()\n"
+"{\n"
+" vec2 GL_Space = Point * 2 - vec2(1.0f, 1.0f);\n"
+" gl_Position = vec4(vec2(GL_Space.x, -GL_Space.y), 0.0f, 1.0);\n"
+" TexCoord = aTexCoord;\n"
+" TexCoordBlend = aTexCoordBlend;\n"
+"}\0";
+#else
+const char *BlendVertexShaderSource = "#version 330 core\n"
+"layout (location = 0) in vec2 Point;\n"
+"layout (location = 1) in vec2 aTexCoord;\n"
+"layout (location = 2) in vec2 aTexCoordBlend;\n"
+"out vec2 TexCoord;\n"
+"out vec2 TexCoordBlend;\n"
+"uniform vec2 CompDimensions;\n"
+"uniform vec2 LayerDimensions;\n"
+"uniform vec2 ScreenDimensions;\n"
+"uniform vec2 Pos;\n"
+"uniform vec2 UIOffset;\n"
+"uniform vec2 UIZoom;\n"
+"uniform vec2 Anchor;\n"
+"uniform float Rad;\n"
+"uniform float Scale;\n"
+"void main()\n"
+"{\n"
+" vec2 XRotation = vec2(cos(Rad), sin(Rad));\n"
+" vec2 YRotation = vec2(sin(Rad), -cos(Rad));\n"
+" vec2 XAxis = (Point.x - (Anchor.x * LayerDimensions.x)) * Scale * XRotation;\n"
+" vec2 YAxis = (Point.y - (Anchor.y * LayerDimensions.y)) * -Scale * YRotation;\n"
+" vec2 CompPoint = Pos + vec2(XAxis + YAxis);\n"
+" vec2 CompUV = CompPoint / CompDimensions;\n"
+" vec2 ScreenPoint = UIOffset + (CompUV * UIZoom);\n"
+" vec2 ScreenUV = ScreenPoint / ScreenDimensions;\n"
+" vec2 GL_Space = ScreenUV * 2 - vec2(1.0f, 1.0f);\n"
+" gl_Position = vec4(vec2(GL_Space.x, -GL_Space.y), 0.0f, 1.0);\n"
+" TexCoord = aTexCoord;\n"
+" TexCoordBlend = aTexCoordBlend;\n"
+"}\0";
+#endif
- glShaderSource(DefaultVertexShader, 1, &DefaultVertexShaderSource, NULL);
- glCompileShader(DefaultVertexShader);
+const char *BlendFragmentShaderSource = "#version 330 core\n"
+"out vec4 FragColor;\n"
+"in vec2 TexCoord;\n"
+"in vec2 TexCoordBlend;\n"
+"uniform sampler2D Texture;\n"
+"uniform sampler2D Texture1;\n"
+"uniform vec3 InputCol;\n"
+"uniform float Rad;\n"
+"void main()\n"
+"{\n"
+" float Rada = Rad;\n"
+" vec2 XRotation = vec2(cos(Rada), sin(Rada));\n"
+" vec2 YRotation = vec2(sin(Rada), -cos(Rada));\n"
+" vec2 XAxis = (TexCoord.x - 0.5) * XRotation;\n"
+" vec2 YAxis = (TexCoord.y - 0.5) * YRotation;\n"
+" vec2 NewCoord = vec2(0.5, 0.5) + vec2(XAxis + YAxis);\n"
+" vec4 Col = texture(Texture, TexCoord);\n"
+" vec4 Dest = texture(Texture1, NewCoord);\n"
+" FragColor = Dest + Col;\n"
+" FragColor = ((1.0f - Dest * 2) * Col * Col) + (Dest * 2 * Col);\n"
+" FragColor.a = Col.a;\n"
+" FragColor = Col + Dest;\n"
+"}\0";
+
+static void GL_InitDefaultShader(uint32 *VertexShader, const char *VertexShaderSource,
+ uint32 *FragmentShader, const char *FragmentShaderSource,
+ uint32 *ShaderProgram)
+{
+ *VertexShader = glCreateShader(GL_VERTEX_SHADER);
+
+ glShaderSource(*VertexShader, 1, &VertexShaderSource, NULL);
+ glCompileShader(*VertexShader);
int success;
char infoLog[512];
- glGetShaderiv(DefaultVertexShader, GL_COMPILE_STATUS, &success);
+ glGetShaderiv(*VertexShader, GL_COMPILE_STATUS, &success);
if(!success)
{
- glGetShaderInfoLog(DefaultVertexShader, 512, NULL, infoLog);
+ glGetShaderInfoLog(*VertexShader, 512, NULL, infoLog);
printf("Vertex shader fail:\n %s", infoLog);
}
- uint32 DefaultFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ *FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(DefaultFragmentShader, 1, &DefaultFragmentShaderSource, NULL);
- glCompileShader(DefaultFragmentShader);
+ glShaderSource(*FragmentShader, 1, &FragmentShaderSource, NULL);
+ glCompileShader(*FragmentShader);
- glGetShaderiv(DefaultFragmentShader, GL_COMPILE_STATUS, &success);
+ glGetShaderiv(*FragmentShader, GL_COMPILE_STATUS, &success);
if(!success)
{
- glGetShaderInfoLog(DefaultFragmentShader, 512, NULL, infoLog);
+ glGetShaderInfoLog(*FragmentShader, 512, NULL, infoLog);
printf("Fragment shader fail:\n %s", infoLog);
}
// Shader programs link both types of shaders together.
- DefaultShaderProgram = glCreateProgram();
+ *ShaderProgram = glCreateProgram();
- glAttachShader(DefaultShaderProgram, DefaultVertexShader);
- glAttachShader(DefaultShaderProgram, DefaultFragmentShader);
- glLinkProgram(DefaultShaderProgram);
+ glAttachShader(*ShaderProgram, *VertexShader);
+ glAttachShader(*ShaderProgram, *FragmentShader);
+ glLinkProgram(*ShaderProgram);
- glGetProgramiv(DefaultShaderProgram, GL_LINK_STATUS, &success);
+ glGetProgramiv(*ShaderProgram, GL_LINK_STATUS, &success);
if(!success) {
- glGetProgramInfoLog(DefaultShaderProgram, 512, NULL, infoLog);
+ glGetProgramInfoLog(*ShaderProgram, 512, NULL, infoLog);
printf("Shader linkage fail:\n %s", infoLog);
}
-
- // Default vertex shader is still needed to link to other effects.
- glDeleteShader(DefaultFragmentShader);
}
static void GL_InitDefaultVerts() {
@@ -225,31 +308,36 @@ GL_BlitStencil(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32
}
static void
-GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount,
- layer_transforms T, int Width, int Height, int BytesPerPixel,
+GL_RasterizeShape2(gl_effect_layer *TestM, gl_effect_layer *TestM2, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount,
+ layer_transforms T, int Width, int Height, int BytesPerPixel, void *Bitmap,
int L_Width, int L_Height,v4 StrokeCol, v4 FillCol, int RenderMode, int Vector,
- ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom, int StencilLayer)
+ ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom, v2 BlendMin, v2 BlendMax, int StencilLayer)
{
int Uniform = 0;
- Uniform = glGetUniformLocation(DefaultShaderProgram, "CompDimensions");
+ uint32 ShaderProgram = DefaultShaderProgram;
+ if (RenderMode & gl_renderflag_blend) {
+ ShaderProgram = BlendShaderProgram;
+ glUseProgram(BlendShaderProgram);
+ }
+ Uniform = glGetUniformLocation(ShaderProgram, "CompDimensions");
glUniform2f(Uniform, Width, Height);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "LayerDimensions");
- glUniform2f(Uniform, L_Width, L_Height);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "ScreenDimensions");
+ Uniform = glGetUniformLocation(ShaderProgram, "ScreenDimensions");
glUniform2f(Uniform, ViewportSize.x, ViewportSize.y);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "UIOffset");
+ Uniform = glGetUniformLocation(ShaderProgram, "UIOffset");
glUniform2f(Uniform, UIPos.x, UIPos.y);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "UIZoom");
+ Uniform = glGetUniformLocation(ShaderProgram, "UIZoom");
glUniform2f(Uniform, UIZoom.x, UIZoom.y);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "Pos");
+ Uniform = glGetUniformLocation(ShaderProgram, "LayerDimensions");
+ glUniform2f(Uniform, L_Width, L_Height);
+ Uniform = glGetUniformLocation(ShaderProgram, "Pos");
glUniform2f(Uniform, T.x, T.y);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "Anchor");
+ Uniform = glGetUniformLocation(ShaderProgram, "Anchor");
glUniform2f(Uniform, T.ax, T.ay);
real32 Rad = (T.rotation * (PI / 180));
- Uniform = glGetUniformLocation(DefaultShaderProgram, "Rad");
+ Uniform = glGetUniformLocation(ShaderProgram, "Rad");
glUniform1f(Uniform, Rad);
- Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale");
+ Uniform = glGetUniformLocation(ShaderProgram, "Scale");
glUniform1f(Uniform, T.scale);
// Concave shapes are fairly more costly than convex: we have to write to
@@ -334,6 +422,80 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
+ else if (RenderMode & gl_renderflag_texture)
+ {
+ GLuint Texture;
+ int InitialTex1 = 0;
+ if (RenderMode & gl_renderflag_blend) {
+
+ glGenTextures(1, &Texture);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, Texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, Bitmap);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TestM2->FramebufferObject);
+ glBlitFramebuffer(0, 0, 2000, 2000,
+ 0, 0, 2000, 2000,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ glBindFramebuffer(GL_FRAMEBUFFER, TestM->FramebufferObject);
+
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &InitialTex1);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, TestM2->Texture);
+ glUniform1i(glGetUniformLocation(BlendShaderProgram, "Texture"), 0);
+ glUniform1i(glGetUniformLocation(BlendShaderProgram, "Texture1"), 1);
+ } else {
+ glGenTextures(1, &Texture);
+ glBindTexture(GL_TEXTURE_2D, Texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, Bitmap);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glBindVertexArray(ShapeVerts.VertexArrayObject);
+ glStencilFunc(GL_EQUAL, StencilLayer, 0xFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ int VertRowSize = 4;
+ if (!(RenderMode & gl_renderflag_blend)) {
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 2);
+ } else {
+ VertRowSize = 6;
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * VertRowSize * FillCount, FillData, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)(2 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+ if (RenderMode & gl_renderflag_blend) {
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, VertRowSize * sizeof(float), (void*)(4 * sizeof(float)));
+ glEnableVertexAttribArray(2);
+ }
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
+
+ if (RenderMode & gl_renderflag_blend) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, InitialTex1);
+ glUseProgram(DefaultShaderProgram);
+ }
+ glActiveTexture(GL_TEXTURE0);
+ glDeleteTextures(1, &Texture);
+ }
else if (RenderMode & gl_renderflag_fill)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -386,6 +548,57 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
}
void
+GL_UpdateTexture2(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample)
+{
+ glViewport(0, 0, Width, Height);
+
+ // int err;
+ // err = glGetError(); Assert(err == 0);
+
+ if (!Test->Initialized) {
+ GL_InitHWBuffer(Test);
+ }
+
+ GLenum Target = GL_TEXTURE_2D;
+ if (Multisample)
+ Target = GL_TEXTURE_2D_MULTISAMPLE;
+
+
+ int Depth = 0, StencilDepth = 0;
+ if (BytesPerPixel == 4) {
+ Depth = GL_RGBA8;
+ StencilDepth = GL_STENCIL_INDEX8;
+ } else if (BytesPerPixel == 8) {
+ Depth = GL_RGBA16;
+ StencilDepth = GL_STENCIL_INDEX16;
+ }
+
+ glBindTexture(Target, Test->Texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data);
+ glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)Test->Stencil_Renderbuffer );
+ glRenderbufferStorage(GL_RENDERBUFFER, StencilDepth, Width, Height);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Test->Texture, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, Test->Stencil_Renderbuffer);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("incomplete framebuffer");
+ Assert(0);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void
GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample)
{
glViewport(0, 0, Width, Height);
@@ -438,9 +651,15 @@ GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height,
glRenderbufferStorage(GL_RENDERBUFFER, StencilDepth, Width, Height );
}
+ // glBindTexture(GL_TEXTURE_2D, Test->Texture);
+ // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA,
+ // GL_UNSIGNED_BYTE, Data);
+ // glBindTexture(GL_TEXTURE_2D, 0);
+
glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Test->Color_Renderbuffer);
+ // glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RGBA, Test->Texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, Test->Stencil_Renderbuffer);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 817fc1d..57d3f79 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -381,6 +381,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
State->Frame_Current = ((State->Frame_Current - 1) < 0) ? 0 : State->Frame_Current - 1;
State->UpdateFrame = true;
State->UpdateKeyframes = true;
+ State->Interact_Transform = {};
if (State->UncommitedKeyframe) {
Memory->PurgeCache = true;
State->UncommitedKeyframe = false;
@@ -392,6 +393,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
State->Frame_Current = ((State->Frame_Current + 1) >= MainComp->Frame_Count) ? 0 : State->Frame_Current + 1;
State->UpdateFrame = true;
State->UpdateKeyframes = true;
+ State->Interact_Transform = {};
if (State->UncommitedKeyframe) {
Memory->PurgeCache = true;
State->UncommitedKeyframe = false;
@@ -586,7 +588,7 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
int h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
- if ((Layer->IsSelected & 0x01) && Layer->IsPrecomp) {
+ if (((Layer->IsSelected & 0x01) || (Layer->IsSelected & 0x02)) && Layer->IsPrecomp) {
Layer->Precomp_Toggled ^= 1;
}
}
@@ -594,7 +596,15 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
if (ImGui::IsKeyPressed(ImGuiKey_Delete))
{
- State->HotkeyInput = hotkey_deletelayer;
+ Bezier_Delete_Selected(File, State, Memory,
+ Sorted.LayerArray, Sorted.CompArray,
+ Sorted.PropertyStart, Sorted.PropertyArray);
+#if 0
+ if (State->FocusedWindow == focus_timeline) {
+ } else {
+ State->HotkeyInput = hotkey_deletelayer;
+ }
+#endif
}
if (io.KeyShift && ImGui::IsKeyPressed(ImGuiKey_Slash))
@@ -704,6 +714,18 @@ ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImG
}
if (ImGui::BeginMenu("Layer"))
{
+#if WINDOWS
+#else
+ if (ImGui::BeginMenu("Import sources from directory"))
+ {
+ ImGui::InputText("Path to directory", State->DummyName2, 512);
+ if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
+ File_LoadDirectory(File, State, Memory, State->DummyName2);
+ State->UpdateFrame = true;
+ }
+ ImGui::EndMenu();
+ }
+#endif
if (ImGui::BeginMenu("Import source from file"))
{
ImGui::InputText("Path to image", State->DummyName2, 512);
diff --git a/src/imgui_ui_properties.cpp b/src/imgui_ui_properties.cpp
index 345f612..e24ebf2 100644
--- a/src/imgui_ui_properties.cpp
+++ b/src/imgui_ui_properties.cpp
@@ -311,7 +311,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui::PushID(Property);
if ((h - 1) < MainProperties && c == 0) {
if (ImGui::Button("K")) {
- Property_AddKeyframe(Memory, F_Layers, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation);
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, h - 1, State->Frame_Current);
}
ImGui::SameLine();
#if DEBUG
@@ -368,14 +368,14 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
if (EffectHeader->DisplayType == effect_display_type_standard) {
if (ChannelHeader.DisplayType == property_display_type_standard) {
if (ImGui::Button("K")) {
- Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation);
+ Property_AddKeyframe(Memory, F_Properties, ArrayLocation, Property, State->Frame_Current - Layer->Frame_Offset);
}
ImGui::SameLine();
ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
ImGui_Properties_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
} else if (ChannelHeader.DisplayType == property_display_type_color) {
if (ImGui::Button("K")) {
- Property_AddKeyframe(Memory, F_Properties, Property, State->Frame_Current - Layer->Frame_Offset, ArrayLocation);
+ Property_AddKeyframe(Memory, F_Properties, ArrayLocation, Property, State->Frame_Current - Layer->Frame_Offset);
}
ImGui::SameLine();
ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp
index 40bc889..8b8ca36 100644
--- a/src/imgui_ui_timeline.cpp
+++ b/src/imgui_ui_timeline.cpp
@@ -12,6 +12,7 @@ ImGui_Timeline_BGElements(project_data *File, project_state *State, memory *Memo
ImVec2 Region_Min = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize.x + ((real32)MainComp.Frame_Start / MainComp.Frame_Count)*TimelineZoomSize.x, TimelineAbsolutePos.y);
ImVec2 Region_Max = ImVec2(Region_Min.x + ((real32)(MainComp.Frame_End - MainComp.Frame_Start) / MainComp.Frame_Count)*TimelineZoomSize.x, Region_Min.y + TimelineSizeWithBorder.y);
draw_list->AddRectFilled(Region_Min, Region_Max, PreviewAreaColor);
+#if 0
// cache bar
cache_entry *EntryArray = State->Render.Entry;
int c = 0;
@@ -29,6 +30,7 @@ ImGui_Timeline_BGElements(project_data *File, project_state *State, memory *Memo
}
c++;
}
+#endif
}
static void
@@ -127,11 +129,11 @@ ImGui_Timeline_GraphInfo(project_data *File, project_state *State, memory *Memor
sorted_property_array *InfoLocation = Property_GetSortedInfo(SortedPropertyStart, i, h);
uint16 *ArrayLocation = Property_GetSortedArray(SortedKeyframeArray, i, h);
ImGui::PushID(Property);
- if (ImGui::Selectable(DefaultChannel[h], Property_IsGraphSelected(Memory, Property, ArrayLocation))) {
+ if (ImGui::Selectable(DefaultChannel[h], Property_IsGraphSelected(Memory, Property->Block_Bezier_Index, ArrayLocation, InfoLocation->KeyframeCount))) {
File_DeselectAllKeyframes(File, State, Memory, SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray);
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
int k = ArrayLocation[p];
- bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *Point = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
Point->IsSelected = true;
}
State->RecentSelectionType = selection_type_keyframe;
@@ -147,16 +149,16 @@ ImGui_Timeline_GraphInfo(project_data *File, project_state *State, memory *Memor
}
static void
-ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, property_channel *Property, uint16 *ArrayLocation,
+ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, property_channel *Property, sorted_property_array *InfoLocation, uint16 *ArrayLocation,
ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 GraphPos, int Frame_Offset, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement,
sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray)
{
ImGui::PushID(Property);
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
int k = ArrayLocation[p];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
v2 PointPos[3];
Bezier_Interact_Evaluate(State, PointAddress, PointPos);
@@ -287,8 +289,8 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
if (Property->Block_Bezier_Count) {
real32 MinY, MaxY;
Property_MinMax_Y(Memory, State, Property, InfoLocation, &MinY, &MaxY, 0);
- Assert(InfoLocation->MinYIndex < Property->Keyframe_Count);
- Assert(InfoLocation->MaxYIndex < Property->Keyframe_Count);
+ Assert(InfoLocation->MinYIndex < InfoLocation->KeyframeCount);
+ Assert(InfoLocation->MaxYIndex < InfoLocation->KeyframeCount);
Assert(MaxY >= MinY);
real32 Y_Increment = (MaxY - MinY) ? (1 / (MaxY - MinY)) : 0.5;
@@ -309,19 +311,19 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
real32 GraphMoveHeight = TimelineMoveSize.y + (TimelineZoomSize.y * GraphPos);
real32 GraphZoomHeight = TimelineZoomSize.y * GraphScale;
- bool32 IsGraphSelected = Property_IsGraphSelected(Memory, Property, ArrayLocation);
+ bool32 IsGraphSelected = Property_IsGraphSelected(Memory, Property->Block_Bezier_Index, ArrayLocation, InfoLocation->KeyframeCount);
uint32 GraphCol = IsGraphSelected ? IM_COL32(255, 180, 150, 255) : IM_COL32(255, 255, 255, 70);
bezier_point *PointAddress[2] = {};
ImVec2 Keyframe_ScreenPos[6] = {};
- for (int p = 0; p < Property->Keyframe_Count; p++) {
+ for (int p = 0; p < InfoLocation->KeyframeCount; p++) {
int k = ArrayLocation[p];
- if (Property->Keyframe_Count == 1)
+ if (InfoLocation->KeyframeCount == 1)
int b = 0;
int Idx = (p % 2);
int NewIdx = Idx * 3;
int OldIdx = (NewIdx == 3) ? 0 : 3;
- PointAddress[Idx] = Bezier_LookupAddress(Memory, Property, k);
+ PointAddress[Idx] = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, k);
v2 PointPos[3];
Bezier_Interact_Evaluate(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment);
@@ -639,6 +641,13 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
if (ImGui::MenuItem("Duplicate layer")) {
State->HotkeyInput = hotkey_duplicatelayer;
}
+ ImGui::Button("Layer Offset");
+ if (ImGui::IsItemActive()) {
+ Layer->Frame_Offset -= 120;
+ Layer->Frame_Start += 120;
+ Layer->Frame_End += 120;
+ State->UpdateFrame = true;
+ }
if (ImGui::MenuItem("Delete layer")) {
State->HotkeyInput = hotkey_deletelayer;
State->UpdateKeyframes = true;
@@ -683,7 +692,22 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
{
const bool is_selected = (*item_current_idx == n);
if (ImGui::Selectable(BlendmodeNames[n], is_selected)) {
- *item_current_idx = n;
+ int h = 0, z = 0, i = 0;
+ bool32 Commit = false;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected & 0x01) {
+ if (!Commit) {
+ History_Entry_Commit(Memory, "Change layer blend mode");
+ Commit = true;
+ }
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->BlendMode), &Layer->BlendMode);
+ Layer->BlendMode = (blend_mode)n;
+ }
+ }
+ if (Commit) {
+ History_Entry_End(Memory);
+ }
State->UpdateFrame = true;
}
@@ -764,7 +788,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
ImVec2 GraphMaxBounds = GraphMinBounds + ImVec2(TimelineSizeWithBorder.x, Layer_ScreenSize.y);
uint32 col = (Channel % 2) ? IM_COL32(50, 50, 50, 255) : IM_COL32(70, 70, 70, 255);
draw_list->AddRectFilled(GraphMinBounds, GraphMaxBounds, col);
- ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, ArrayLocation,
+ ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, InfoLocation, ArrayLocation,
Increment, TimelineAbsolutePos, GraphPos, Frame_Offset, TimelineMoveSize, TimelineZoomSize,
TimelineSize, TimelineSizeWithBorder, LayerIncrement,
SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray);
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index 4b6f6ce..b2830de 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -744,6 +744,20 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
Height = Source->Height;
}
+ if (State->Interact_Active == interact_type_viewport_slide) {
+ real32 Threshold = 10;
+ v2 CompUV = V2(State->Interact_Offset[0], State->Interact_Offset[1]);
+ v2 CompPos = CompUV * V2(Comp->Width, Comp->Height);
+ v2 LayerPos = V2(Layer->x.CurrentValue, Layer->y.CurrentValue);
+ v2 Difference = V2(fabs(CompPos.x - LayerPos.x), fabs(CompPos.y - LayerPos.y));
+ printf("Diff: %.1f, %.1f\n", Difference.x, Difference.y);
+ if (Difference.x < Threshold &&
+ Difference.y < Threshold)
+ {
+ Assert(0);
+ }
+ }
+
layer_transforms T = Layer_GetTransforms(Layer);
if ((State->Interact_Active == interact_type_viewport_transform ||
State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected & 0x01) {
@@ -892,6 +906,8 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
Render_UI(File, State, Memory, UI, draw_list, Data, RenderData,
SortedCompArray, SortedLayerArray, ExtraT,
SortedPropertyStart, SortedKeyframeArray, File->PrincipalCompIndex, State->Frame_Current);
+ State->UpdateFrame = false;
+ State->UpdateKeyframes = false;
draw_list->AddCallback(GL_Test, (void *)StartAddress);
draw_list->AddCallback(ImDrawCallback_ResetRenderState, NULL);
draw_list->AddRect(CompPosMin, CompPosMax, OUTLINE);
@@ -1107,6 +1123,36 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
if (IsActive)
int a = 0;
+ if (State->Tool == tool_default && State->Interact_Active == interact_type_none && !io.MouseDelta.x && !io.MouseDelta.y) {
+ ImGui::OpenPopupOnItemClick("defaultcontext", ImGuiPopupFlags_MouseButtonRight);
+ if (ImGui::BeginPopup("defaultcontext")) {
+ ImGui::Text("Insert keyframe...");
+ if (ImGui::Button("X/Y")) {
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 0, State->Frame_Current);
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 1, State->Frame_Current);
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Rotation")) {
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 4, State->Frame_Current);
+ ImGui::CloseCurrentPopup();
+ }
+ if (ImGui::Button("Scale")) {
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 5, State->Frame_Current);
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("X/Y+R+S")) {
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 0, State->Frame_Current);
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 1, State->Frame_Current);
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 4, State->Frame_Current);
+ Property_AddKeyframe_AllSelected(File, State, Memory, F_Layers, SortedLayerArray, SortedCompArray, SortedKeyframeArray, 5, State->Frame_Current);
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::EndPopup();
+ }
+ }
+
if (State->Tool == tool_pen && State->Interact_Active == interact_type_none && State->MostRecentlySelectedLayer == -1) {
v2 CompUV = State->LastClickedPoint;
ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
@@ -1160,7 +1206,6 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
State->Interact_Offset[1] = MouseCompPos.y;
State->Interact_Offset[3] = PrevMouseCompPos.x;
State->Interact_Offset[4] = PrevMouseCompPos.y;
- Slide_Test(File, State, Memory, SortedCompArray, SortedLayerArray);
}
}
diff --git a/src/include/all.h b/src/include/all.h
index 8117437..603ba1d 100644
--- a/src/include/all.h
+++ b/src/include/all.h
@@ -10,21 +10,29 @@ Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData,
project_state *State, layer_transforms T, int Width, int Height,
int CompWidth, int CompHeight, real32 Radius, bool32 Interact);
-static bezier_point *
-Bezier_LookupAddress(memory *Memory, uint16 *Block_Bezier_Index, uint16 Index, bool32 AssertExists = 1);
+static void
+Property_AddKeyframe_AllSelected(project_data *File, project_state *State, memory *Memory,
+ memory_table_list TableName, sorted_layer_array *SortedLayerArray, sorted_comp_array *SortedCompArray, uint16 *SortedKeyframeArray,
+ uint16 Idx, int Frame);
+
+static int32
+Bezier_CheckSameX(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 KeyframeCount, uint16 *ArrayLocation, real32 ValX);
+
+static void
+Property_AddKeyframe(memory *Memory, memory_table_list TableName, uint16 *ArrayLocation, property_channel *Property, int Frame);
static bezier_point *
-Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists = 1);
+Bezier_LookupAddress(memory *Memory, uint16 *Block_Bezier_Index, uint16 Index, bool32 AssertExists = 1);
static void
Bezier_Interact_Evaluate(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight = 1, real32 Y_Increment = 1);
static void
-Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *Block_Bezier_Count,
- uint16 *PointCount, bezier_point PointData);
+Bezier_Delete(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *PointCount, uint16 *ArrayLocation);
static void
-Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation);
+Bezier_Add(memory *Memory, memory_table_list TableName, uint16 *Block_Bezier_Index, uint16 *Block_Bezier_Count,
+ uint16 *PointCount, bezier_point PointData);
// return all points
static void Bezier_CubicCalcPointsCasteljauStep(void *Data, uint32 Size, uint32 *Increment, real32 x1, real32 y1, real32 x2, real32 y2, real32 x3, real32 y3, real32 x4, real32 y4, real32 tess_tol, int level);
@@ -51,6 +59,9 @@ static void Bezier_CubicMinMaxCasteljauStep(v2 *p_min, v2 *p_max, real32 x1, rea
real32 Bezier_CubicRatioOfPoint(v2 p1, v2 p2, v2 p3, v2 p4, v2 p);
+static void
+File_LoadDirectory(project_data *File, project_state *State, memory *Memory, char *DirString);
+
static bool32
File_Open(project_data *File, project_state *State, memory *Memory, char *Filename);
@@ -74,7 +85,9 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
static void
-Property_AddKeyframe(memory *Memory, memory_table_list TableName, property_channel *Property, int Frame, uint16 *ArrayLocation);
+Property_AddKeyframe_AllSelected(project_data *File, project_state *State, memory *Memory,
+ memory_table_list TableName, sorted_layer_array *SortedLayerArray, sorted_comp_array *SortedCompArray, uint16 *SortedKeyframeArray,
+ uint16 Idx, int Frame);
static block_composition *
Precomp_Init(project_data *File, memory *Memory, block_composition *DupeComp = NULL);
@@ -119,7 +132,7 @@ static void
Project_Layer_Delete(project_data *File, project_state *State, memory *Memory);
static bool32
-Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *ArrayLocation);
+Property_IsGraphSelected(memory *Memory, uint16 *Block_Bezier_Index, uint16 *ArrayLocation, uint16 KeyframeCount);
static void
Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory,
diff --git a/src/include/gl_calls.h b/src/include/gl_calls.h
index 3c2bef0..3bc85fb 100644
--- a/src/include/gl_calls.h
+++ b/src/include/gl_calls.h
@@ -13,8 +13,11 @@ static default_gl_vertex_object DefaultVerts;
static default_gl_vertex_object ShapeVerts;
static gl_vertex_shader GL_DefaultVertexObjects;
static uint32 DefaultVertexShader;
+static uint32 DefaultFragmentShader; // unused
static uint32 DefaultShaderProgram;
-static uint32 MaskShaderProgram;
+static uint32 BlendVertexShader;
+static uint32 BlendFragmentShader;
+static uint32 BlendShaderProgram;
float GL_DefaultVertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
diff --git a/src/include/main.h b/src/include/main.h
index ac1118d..46aed98 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -218,6 +218,7 @@ enum focused_window
struct sorted_property_array
{
+ uint32 KeyframeCount;
uint32 MinYIndex;
uint32 MaxYIndex;
};
@@ -239,6 +240,7 @@ struct sorted_layer_array
uint16 Sorted_Effect_Index[MAX_EFFECTS];
uint16 SortedPropertyStart;
uint16 SortedKeyframeStart;
+ real32 Interact_Offset[4];
};
struct sorted_file
@@ -402,7 +404,9 @@ enum gl_shape_renderflags
{
gl_renderflag_fill = 1 << 0,
gl_renderflag_stroke = 1 << 1,
- gl_renderflag_convex = 1 << 2
+ gl_renderflag_convex = 1 << 2,
+ gl_renderflag_texture = 1 << 3,
+ gl_renderflag_blend = 1 << 4
};
struct gl_data
@@ -417,7 +421,11 @@ struct gl_data
layer_transforms T;
real32 Width;
real32 Height;
+ void *BitmapData;
int RenderMode;
+
+ v2 BlendMin;
+ v2 BlendMax;
};
struct gl_viewport_data
@@ -478,8 +486,8 @@ struct project_state
bool32 UpdateScreen = 1; // refreshes entire UI; influenced by raw key/mouse input
bool32 DebugDisableCache = 1;
+ // TODO(fox): Group inconsequential state UI into one thing?
bool32 ShapeMode = 0;
-
bool32 ViewportEnabled = 0;
bool32 SelectionMode = 1;
@@ -710,7 +718,8 @@ struct property_channel {
uint8 Occupied;
uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS];
uint16 Block_Bezier_Count;
- uint16 Keyframe_Count;
+ // NOTE(fox): Don't use this in sorted circumstances; use the one in sorted_property_array instead!
+ uint16 Keyframe_Count;
int32 Identifier;
diff --git a/src/layer.cpp b/src/layer.cpp
index 570c7fc..9cb1e8b 100644
--- a/src/layer.cpp
+++ b/src/layer.cpp
@@ -339,7 +339,7 @@ Layer_ToggleAllChannels(project_state *State, memory *Memory, block_layer *Layer
block_effect *Effect = NULL;
while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p))
{
- if (Property->Keyframe_Count) {
+ if (InfoLocation->KeyframeCount) {
Property->IsToggled = ToggleMode;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 3152156..b144942 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -120,7 +120,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_
if (State->FirstFrame) {
ImGui::MyWindowSetup(&State->RightDock, DockID);
}
- ImGui::MyDockWindow("Timeline", State->RightDock);
+ // ImGui::MyDockWindow("Timeline", State->RightDock);
if (State->Warp_WantSetPos) {
ImGui_WarpMouseFinish(State, io.MousePos);
@@ -155,7 +155,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_
} else {
}
ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray);
- // ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray);
+ ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray);
ImGui_ColorPanel(File, State, UI, Memory, io);
#if STABLE
@@ -218,10 +218,10 @@ Layer_UpdateAllKeyframes(project_data *File, project_state *State, memory *Memor
Property_MinMax_Y(Memory, State, Property, SortedProperty, &MinY, &MaxY);
real32 Y_Increment = 1 / (MaxY - MinY);
v2 FirstPointPos[3];
- bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[0]);
+ bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, SortedKeyframe[0]);
Bezier_Interact_Evaluate(State, FirstPointAddress, FirstPointPos);
v2 LastPointPos[3];
- bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[Property->Keyframe_Count - 1]);
+ bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, SortedKeyframe[Property->Keyframe_Count - 1]);
Bezier_Interact_Evaluate(State, LastPointAddress, LastPointPos);
if (FirstPointPos[0].x >= Frame_Current) {
Property->CurrentValue = FirstPointPos[0].y;
@@ -231,17 +231,17 @@ Layer_UpdateAllKeyframes(project_data *File, project_state *State, memory *Memor
int KeyframeIndex = 0;
for (;;) {
v2 PointPos[3];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex + 1]);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, SortedKeyframe[KeyframeIndex + 1]);
Bezier_Interact_Evaluate(State, PointAddress, PointPos, 1, Y_Increment);
if (PointPos[0].x >= Frame_Current)
break;
KeyframeIndex++;
}
v2 PointPos[3];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex]);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, SortedKeyframe[KeyframeIndex]);
Bezier_Interact_Evaluate(State, PointAddress, PointPos, 1, Y_Increment);
v2 NextPointPos[3];
- bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex + 1]);
+ bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, SortedKeyframe[KeyframeIndex + 1]);
Bezier_Interact_Evaluate(State, NextPointAddress, NextPointPos, 1, Y_Increment);
if (PointAddress->Type == interpolation_type_hold) {
Property->CurrentValue = PointPos[0].y;
@@ -291,10 +291,19 @@ Render_SortKeyframes(project_data *File, project_state *State, memory *Memory,
int32 Frame_End_Abs = Frame_End + Frame_Offset;
int FrameToSeek = State->Frame_Current - Frame_Start_Abs;
+ if (Layer->x.Keyframe_Count == 2)
+ int b = 0;
+ if (State->UpdateKeyframes) {
+ if (Layer->x.Keyframe_Count == 2)
+ int b = 0;
+ }
+
if (Frame_Start_Abs <= Frame_Current &&
Frame_End_Abs > Frame_Current && Layer->IsVisible)
{
if (State->UpdateKeyframes) {
+ if (Layer->x.Keyframe_Count == 2)
+ int b = 0;
sorted_property_array *SortedLayerProperties = SortedPropertyStart + SortEntry.SortedPropertyStart;
uint16 *SortedLayerKeyframes = SortedKeyframeArray + SortEntry.SortedKeyframeStart;
Layer_UpdateAllKeyframes(File, State, Memory, Layer, Index_Physical, SortedLayerProperties, SortedLayerKeyframes, Frame_Current);
@@ -309,6 +318,7 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
uint64 PerfStart = SDL_GetPerformanceCounter();
gl_viewport_data *RenderData = (gl_viewport_data *)cmd->UserCallbackData;
gl_effect_layer MSBuffer = {};
+ gl_effect_layer MSBuffer2 = {};
int err = 0;
@@ -316,6 +326,7 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
glGetIntegerv(GL_VIEWPORT, A);
GL_UpdateTexture(&MSBuffer, NULL, A[2], A[3], RenderData->BytesPerPixel, 1);
+ GL_UpdateTexture2(&MSBuffer2, NULL, A[2], A[3], RenderData->BytesPerPixel, 0);
glBindFramebuffer(GL_FRAMEBUFFER, MSBuffer.FramebufferObject);
glBindTexture(GL_TEXTURE_2D, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -340,10 +351,10 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
if (Data->Type == 0) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- GL_RasterizeShape2(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount,
- Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel,
+ GL_RasterizeShape2(&MSBuffer, &MSBuffer2, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount,
+ Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel, Data->BitmapData,
Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0,
- RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom, StencilLayer);
+ RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom, Data->BlendMin, Data->BlendMax, StencilLayer);
} else if (Data->Type == 1) {
GL_BlitStencil(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount,
Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel,
@@ -352,7 +363,7 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
StencilLayer++;
} else if (Data->Type == 2) {
GL_BlitStencil(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount,
- Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel,
+ Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel,
Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0,
RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom, StencilLayer, GL_DECR);
StencilLayer--;
@@ -377,13 +388,15 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
MinPos.x, MinPos.y, MaxPos.x, MaxPos.y,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
} else {
- // TODO(fox): fix this?
- glBlitFramebuffer(RenderData->ViewportMin.x, RenderData->ViewportMin.y - 50, RenderData->ViewportMax.x, RenderData->ViewportMax.y,
- RenderData->ViewportMin.x, RenderData->ViewportMin.y - 50, RenderData->ViewportMax.x, RenderData->ViewportMax.y,
+ real32 FlipY = A[3] - RenderData->ViewportMax.y;
+ real32 FlipY2 = A[3] - RenderData->ViewportMin.y;
+ glBlitFramebuffer(RenderData->ViewportMin.x, FlipY, RenderData->ViewportMax.x, FlipY2,
+ RenderData->ViewportMin.x, FlipY, RenderData->ViewportMax.x, FlipY2,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
GL_DeleteHWBuffer(&MSBuffer);
+ GL_DeleteHWBuffer(&MSBuffer2);
uint64 PerfEnd = SDL_GetPerformanceCounter() - PerfStart;
// printf("OPENGL: %.2lu\n", PerfEnd);
}
@@ -601,7 +614,6 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current)
{
block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex);
- cache_entry *Entry_Main = Memory_Cache_Search(State, Memory, cache_entry_type_comp, CompIndex, Frame_Current);
uint64 Size = Comp->Width * Comp->Height * Comp->BytesPerPixel;
sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex];
@@ -622,7 +634,7 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset);
int32 Frame_Start_Abs = Frame_Start + Frame_Offset;
int32 Frame_End_Abs = Frame_End + Frame_Offset;
- int FrameToSeek = State->Frame_Current - Frame_Start_Abs;
+ int FrameToSeek = State->Frame_Current - Frame_Offset;
if (Frame_Start_Abs <= Frame_Current &&
Frame_End_Abs > Frame_Current && Layer->IsVisible)
@@ -697,7 +709,7 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
*GL_Data = { 0, Data_Stroke, StrokeCount, ShapeOpt.StrokeCol,
Data_Fill, NumberOfVerts, ShapeOpt.FillCol,
- T, Shape->Width, Shape->Height, RenderFlags };
+ T, Shape->Width, Shape->Height, NULL, RenderFlags };
} else if (Layer->IsPrecomp) {
layer_transforms NewExtraT = Layer_GetTransforms(Layer);
@@ -715,10 +727,10 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
GL_Data->Width = Width;
GL_Data->Height = Height;
GL_Data->FillData = PointBuffer;
- real32 CompVerts[16] = { 0.f, 0.f, 0.f, 0.f,
- 0.f, (real32)Height, 0.f, 0.f,
- (real32)Width, (real32)Height, 0.f, 0.f,
- (real32)Width, 0.f, 0.f, 0.f };
+ real32 CompVerts[16] = { 0.f, 0.f, 0.0f, 0.0f,
+ 0.f, (real32)Height, 0.0f, 1.0f,
+ (real32)Width, (real32)Height, 1.0f, 1.0f,
+ (real32)Width, 0.f, 1.0f, 0.0f };
for (int a = 0; a < 16; a++) {
*(real32 *)PointBuffer = CompVerts[a];
PointBuffer += sizeof(real32);
@@ -743,15 +755,133 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
}
GL_Data->FillCount = 4;
} else {
- Assert(0);
+
+ // gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)PointBuffer;
+ // GL_Data->Type = 3;
+ // RenderData->LayerCount++;
+
gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)PointBuffer;
RenderData->LayerCount++;
PointBuffer += sizeof(gl_data);
+ void *BitmapAddress;
- GL_Data->Type = 1;
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ av_info *AV = NULL;
+ if (Source->Type == source_type_file) {
+ AV = AV_Retrieve(State, Memory, Layer->Block_Source_Index);
+ if (!AV) {
+ AV = (av_info *)Memory_Block_AllocateAddress(Memory, P_AVInfo);
+ AV->Occupied = 1;
+ AV->Block_Source_Index = Layer->Block_Source_Index;
+ AV_Init(Source, AV, Memory);
+ State->AVCount++;
+ }
+ }
+
+ if (Source->Type == source_type_principal || Source->Type == source_type_principal_temp) {
+ BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0);
+ } else {
+ cache_entry *CacheEntry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, FrameToSeek);
+ BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, CacheEntry->Block_StartIndex);
+ if (!CacheEntry->IsCached) {
+ AV_LoadVideoFrame(Memory, Source, AV, FrameToSeek, BitmapAddress);
+ CacheEntry->IsCached = true;
+ }
+ }
+
+ Assert(BitmapAddress);
+
+ GL_Data->FillData = PointBuffer;
+ GL_Data->FillCount = 4;
+ int Blend = (Layer->BlendMode != blend_normal) ? gl_renderflag_blend : 0;
+ v2 Min = V2(10000, 10000), Max = V2(-10000, -10000);
+ if (Blend) {
+ real32 CompVerts[24] = { 0.f, 0.f, 0.0f, 0.0f, -0.5f, 0.5f,
+ 0.f, (real32)Height, 0.0f, 1.0f, -0.5f, 0.5f,
+ (real32)Width, (real32)Height, 1.0f, 1.0f, -0.5f, 0.5f,
+ (real32)Width, 0.f, 1.0f, 0.0f, -0.5f, 0.5f };
+#if 1
+ real32 Rad = (T.rotation * (PI / 180));
+ v2 UIOffset = V2(RenderData->UIPos);
+ v2 UIZoom = V2(RenderData->UIZoom);
+ v2 ScreenDimensions = V2(RenderData->ViewportSize);
+ v2 LayerDimensions = V2(Width, Height);
+ v2 CompDimensions = V2(Comp->Width, Comp->Height);
+ v2 Anchor = V2(T.ax, T.ay);
+ v2 Pos = V2(T.x, T.y);
+ real32 Scale = T.scale;
+
+ for (int a = 0; a < 4; a++) {
+
+ real32 *PointX = &CompVerts[(a*6)];
+ real32 *PointY = &CompVerts[(a*6)+1];
+ v2 Point = V2(*PointX, *PointY);
+
+ v2 XRotation = V2(cos(Rad), sin(Rad));
+ v2 YRotation = V2(sin(Rad), -cos(Rad));
+ v2 XAxis = (Point.x - (Anchor.x * LayerDimensions.x)) * Scale * XRotation;
+ v2 YAxis = (Point.y - (Anchor.y * LayerDimensions.y)) * -Scale * YRotation;
+ v2 CompPoint = Pos + v2(XAxis + YAxis);
+ v2 CompUV = CompPoint / CompDimensions;
+ v2 ScreenPoint = UIOffset + (CompUV * UIZoom);
+ v2 ScreenUV = ScreenPoint / ScreenDimensions;
+
+ *PointX = ScreenUV.x;
+ *PointY = ScreenUV.y;
+ // if (ScreenPoint.x > Max.x)
+ // Max.x = ScreenPoint.x;
+ // if (ScreenPoint.x < Min.x)
+ // Min.x = ScreenPoint.x;
+ // if (ScreenPoint.y > Max.y)
+ // Max.y = ScreenPoint.y;
+ // if (ScreenPoint.y < Min.y)
+ // Min.y = ScreenPoint.y;
+ }
+
+#if 0
+ Rad = -Rad;
+ for (int a = 0; a < 4; a++) {
+
+ real32 *PointX = &CompVerts[(a*6)+2];
+ real32 *PointY = &CompVerts[(a*6)+3];
+ v2 Point = V2(*PointX, *PointY);
+
+ v2 XRotation = V2(cos(Rad), sin(Rad));
+ v2 YRotation = V2(sin(Rad), -cos(Rad));
+ v2 XAxis = (Point.x - 0.5) * XRotation;
+ v2 YAxis = (Point.y - 0.5) * YRotation;
+ v2 CompPoint = V2(0.5, 0.5) + v2(XAxis + YAxis);
+
+ *PointX = CompPoint.x;
+ *PointY = CompPoint.y;
+ }
+#endif
+#endif
+ for (int a = 0; a < 24; a++) {
+ *(real32 *)PointBuffer = CompVerts[a];
+ PointBuffer += sizeof(real32);
+ }
+ } else {
+ real32 CompVerts[16] = { 0.f, 0.f, 0.0f, 0.0f,
+ 0.f, (real32)Height, 0.0f, 1.0f,
+ (real32)Width, (real32)Height, 1.0f, 1.0f,
+ (real32)Width, 0.f, 1.0f, 0.0f };
+ for (int a = 0; a < 16; a++) {
+ *(real32 *)PointBuffer = CompVerts[a];
+ PointBuffer += sizeof(real32);
+ }
+ }
+
+ GL_Data->Type = 0;
GL_Data->Width = Width;
GL_Data->Height = Height;
+ if (Blend) {
+ GL_Data->BlendMin = Min;
+ GL_Data->BlendMax = Max;
+ }
+ GL_Data->BitmapData = BitmapAddress;
GL_Data->T = T;
+ GL_Data->RenderMode = gl_renderflag_convex | gl_renderflag_fill | gl_renderflag_texture | Blend;
}
}
}
@@ -800,7 +930,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil
Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset);
int32 Frame_Start_Abs = Frame_Start + Frame_Offset;
int32 Frame_End_Abs = Frame_End + Frame_Offset;
- int FrameToSeek = State->Frame_Current - Frame_Start_Abs;
+ int FrameToSeek = State->Frame_Current - Frame_Offset;
if (Frame_Start_Abs <= Frame_Current &&
Frame_End_Abs > Frame_Current && Layer->IsVisible)
@@ -1002,7 +1132,7 @@ int main(int argc, char *argv[]) {
global_memory GlobalMemory = {};
- GlobalMemory.Size = ((uint64)1 * 1024 * 1024 * 1024);
+ GlobalMemory.Size = ((uint64)8 * 1024 * 1024 * 1024);
GlobalMemory.CurrentPosition = 0;
#if WINDOWS
@@ -1037,7 +1167,7 @@ int main(int argc, char *argv[]) {
Memory_InitTable(&GlobalMemory, &Memory, (uint64)5 * 1024 * 1024, B_Thumbnails, "Thumbnails");
Memory_InitTable(&GlobalMemory, &Memory, (uint64)5 * 1024 * 1024, B_PointData, "Point data");
Memory_InitTable(&GlobalMemory, &Memory, (uint64)128 * 1024 * 1024, B_ScratchSpace, "Scratch");
- Memory_InitTable(&GlobalMemory, &Memory, (uint64)700 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer");
+ Memory_InitTable(&GlobalMemory, &Memory, (uint64)5400 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer");
uint8 *Test = (uint8 *)Memory.Slot[B_ScratchSpace].Address + Memory.Slot[B_ScratchSpace].Size + 2;
*Test = 30;
@@ -1088,7 +1218,7 @@ int main(int argc, char *argv[]) {
block_composition *MainComp = (block_composition *)Memory_Block_AllocateAddress(&Memory, F_Precomps);
MainComp->Width = 1280;
- MainComp->Height = 1280;
+ MainComp->Height = 720;
MainComp->FPS = 60;
MainComp->BytesPerPixel = 4;
MainComp->Frame_Count = 80;
@@ -1182,7 +1312,12 @@ int main(int argc, char *argv[]) {
}
gladInstallGLDebug();
- GL_InitDefaultShader();
+ GL_InitDefaultShader(&DefaultVertexShader, DefaultVertexShaderSource,
+ &DefaultFragmentShader, DefaultFragmentShaderSource,
+ &DefaultShaderProgram);
+ GL_InitDefaultShader(&BlendVertexShader, BlendVertexShaderSource,
+ &BlendFragmentShader, BlendFragmentShaderSource,
+ &BlendShaderProgram);
GL_InitDefaultVerts();
Effect_InitEntries(State);
@@ -1402,7 +1537,9 @@ int main(int argc, char *argv[]) {
block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(&Memory, F_Precomps, File->PrincipalCompIndex);
Playhead_Increment(&State->Frame_Current, MainComp->Frame_Start, MainComp->Frame_End, 1);
State->UpdateFrame = true;
+ State->Interact_Transform = {};
State->UpdateKeyframes = true;
+ State->UpdateScreen += 1;
}
bool32 FullyCached = (State->CachedFrameCount == (MainComp->Frame_End - MainComp->Frame_Start + 1));
diff --git a/src/memory.cpp b/src/memory.cpp
index 7454a2a..fc82a13 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -95,7 +95,7 @@ Block_Loop(memory *Memory, property_channel *Property, uint32 TotalCount, int *H
*HasIncremented = 0;
(*Index)++;
}
- uint8 *Occupied = (uint8 *)Bezier_LookupAddress(Memory, Property, *Index, 0);
+ uint8 *Occupied = (uint8 *)Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, *Index, 0);
if (*Occupied) {
*HasIncremented = 1;
(*CurrentCount)++;
@@ -291,7 +291,16 @@ void Memory_Fill(uint8 *Address_Write, uint8 *Address_Read, uint64 WriteSize, ui
void Arbitrary_Zero(uint8 *Address_Write, uint64 Size)
{
+ __m256i Zero256 = _mm256_setzero_si256();
uint64 i = 0;
+ if (Size > 64 && InstructionMode == instruction_mode_avx) {
+ uint64 Size_Lane = Size - (Size % 64);
+ while (i < Size_Lane) {
+ _mm256_storeu_si256((__m256i *)(Address_Write + i), Zero256);
+ _mm256_storeu_si256((__m256i *)(Address_Write + i + 32), Zero256);
+ i += 64;
+ }
+ }
while (i < Size) {
*(Address_Write + i) = 0;
i++;
diff --git a/src/prenderer.cpp b/src/prenderer.cpp
index 7cac63e..600efd7 100644
--- a/src/prenderer.cpp
+++ b/src/prenderer.cpp
@@ -225,7 +225,6 @@ Transform_TestInteracts(project_state *State, block_layer *Layer, sorted_layer_a
Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale);
}
if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected & 0x01) {
- Assert(0);
// Transform_ApplySlide((v2 *)&State->Interact_Offset[0], &T);
}
if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) {
diff --git a/src/sorted.cpp b/src/sorted.cpp
index 948c6f6..3ecd69e 100644
--- a/src/sorted.cpp
+++ b/src/sorted.cpp
@@ -42,7 +42,7 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr
int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
while (Block_Loop(Memory, Property, Property->Keyframe_Count, &h, &c, &i)) {
v2 PointPos[3];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, i);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, i);
Bezier_Interact_Evaluate(State, PointAddress, PointPos);
@@ -59,7 +59,7 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr
while (SortedIndex_Playhead < CurrentSortIndex) {
uint16 TestPointEntry = PropertyArrayStart[SortedIndex_Playhead];
v2 TestPointPos[3];
- bezier_point *TestPointAddress = Bezier_LookupAddress(Memory, Property, TestPointEntry);
+ bezier_point *TestPointAddress = Bezier_LookupAddress(Memory, Property->Block_Bezier_Index, TestPointEntry);
Bezier_Interact_Evaluate(State, TestPointAddress, TestPointPos);
if (PointPos[0].x < TestPointPos[0].x ) {
break;
@@ -395,6 +395,7 @@ void LayerProperty_SortAll(project_data *File, project_state *State, memory *Mem
uint16 *ArrayLocation = SortedKeyframeArray + SortedKeyframePlayhead;
Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
SortedKeyframePlayhead += Property->Keyframe_Count;
+ InfoLocation->KeyframeCount = Property->Keyframe_Count;
}
SortedPropertyPlayhead++;
}
@@ -409,6 +410,7 @@ void LayerProperty_SortAll(project_data *File, project_state *State, memory *Mem
uint16 *ArrayLocation = SortedKeyframeArray + SortedKeyframePlayhead;
Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
SortedKeyframePlayhead += Property->Keyframe_Count;
+ InfoLocation->KeyframeCount = Property->Keyframe_Count;
}
SortedPropertyPlayhead++;
}