summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-11-29 21:04:09 -0500
committerFox Caminiti <fox@foxcam.net>2022-11-29 21:04:09 -0500
commitdc0d4a23fdbddef51d5e026f2eefef1731c4e338 (patch)
treed4a07d558f646186068633486a3628b8b141f4d5
parent7a5e57b5c806437b0fbd2ab0c08d616d5dec0090 (diff)
effects integration halfway
-rw-r--r--createcalls.cpp120
-rw-r--r--effects.cpp11
-rw-r--r--effects_constructors.cpp8
-rw-r--r--effects_gl.cpp74
-rw-r--r--gl_calls.cpp67
-rw-r--r--main.cpp37
-rw-r--r--main.h3
-rw-r--r--my_imgui_widgets.cpp350
8 files changed, 439 insertions, 231 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index a984454..145a58a 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -242,6 +242,15 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData, u
}
}
+static void
+Property_AddKeyframe(memory *Memory, property_channel *Property, int Frame, uint16 *ArrayLocation)
+{
+ 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, Property, Point, ArrayLocation);
+ History_Entry_End(Memory);
+}
+
// static void
// Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX, bool32 AlwaysInteger = 0) {
// {
@@ -440,14 +449,57 @@ void Source_DeselectAll(project_data *File, memory *Memory)
}
}
+// h: index of the total amount of properties and effects
+// c: index of the amount of properties in a given effect
+// p: prior property's keyframe count, so we can increment the sorted keyframe array properly
+static bool32
+Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_info **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer,
+ property_channel **Property, block_effect **EffectOut, int *h, int *c, int *p)
+{
+ uint32 Amount = AmountOf(Layer->Property) + Layer->Block_Effect_Count;
+ Assert(Layer->Block_Effect_Count < 2);
+ while (*h < Amount) {
+ if (*h < AmountOf(Layer->Property)) {
+ *Property = &Layer->Property[*h];
+ if (*h != 0) {
+ *SortedProperty += 1;
+ *SortedKeyframe += *p;
+ }
+ *h += 1;
+ *p = (**Property).Keyframe_Count;
+ return 1;
+ } else {
+ uint16 EffectIdx = Layer->Block_Effect_Index[*h - AmountOf(Layer->Property)];
+ block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, EffectIdx);
+ if (EffectOut)
+ *EffectOut = Effect;
+ header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID);
+ while (*c < EffectHeader->Property_Count) {
+ // header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + c];
+ *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[*c]);
+ *SortedKeyframe += *p;
+ *p = (**Property).Keyframe_Count;
+ *h += 1;
+ *c += 1;
+ return 1;
+ }
+ *c = 0;
+ }
+ }
+ Assert(*h != (Amount - 1));
+ return 0;
+}
+
inline sorted_property_info *
Property_GetSortedInfo(sorted_property_info *SortedPropertyInfo, int i, int h)
{
+ Assert(0);
return SortedPropertyInfo + (i * 8) + h;
}
inline uint16 *
Property_GetSortedArray(uint16 *SortedPropertyArray, int i, int h)
{
+ Assert(0);
return SortedPropertyArray + (i * 8 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
}
@@ -911,15 +963,6 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
Assert(Layer->Block_Composition_Index < CompCount);
CompStart[Layer->Block_Composition_Index].LayerCount++;
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
- if (Property->Block_Bezier_Count) {
- sorted_property_info *InfoLocation = Property_GetSortedInfo(SortedPropertyInfo, i, h);
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h);
- Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
- int x = 0;
- }
- }
}
h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
@@ -986,6 +1029,50 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
}
}
+void LayerProperty_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart,
+ sorted_comp_info *CompStart, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray,
+ uint32 LayerCount, uint32 CompCount)
+{
+ uint32 SortedPropertyPlayhead = 0;
+ uint32 SortedKeyframePlayhead = 0;
+ for (int c = 0; c < CompCount; c++) {
+ sorted_comp_info SortedCompInfo = CompStart[c];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, c);
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++) {
+ sorted_layer *SortedLayer = &SortedLayerInfo[i];
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index);
+ SortedLayer->SortedPropertyStart = SortedPropertyPlayhead;
+ SortedLayer->SortedKeyframeStart = SortedKeyframePlayhead;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Keyframe_Count) {
+ sorted_property_info *InfoLocation = SortedPropertyInfo + SortedPropertyPlayhead;
+ uint16 *ArrayLocation = SortedPropertyArray + SortedKeyframePlayhead;
+ Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
+ SortedKeyframePlayhead += Property->Keyframe_Count;
+ }
+ SortedPropertyPlayhead++;
+ }
+ for (int i = 0; i < Layer->Block_Effect_Count; i++) {
+ block_effect Effect = *(block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]);
+ header_effect *EffectHeader = Effect_EntryFromID(State, Effect.ID);
+ for (int h = 0; h < EffectHeader->Property_Count; h++) {
+ header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h];
+ property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[h]);
+ if (Property->Keyframe_Count) {
+ sorted_property_info *InfoLocation = SortedPropertyInfo + SortedPropertyPlayhead;
+ uint16 *ArrayLocation = SortedPropertyArray + SortedKeyframePlayhead;
+ Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
+ SortedKeyframePlayhead += Property->Keyframe_Count;
+ }
+ SortedPropertyPlayhead++;
+ }
+ }
+ }
+ }
+ int a = 0;
+}
+
sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Memory)
{
sorted_file Sorted = {0};
@@ -996,6 +1083,12 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem
Sorted.CompArray = (sorted_comp_info *)Layer_SortedArray;
Sorted.LayerArray = (sorted_layer *)((uint8 *)Layer_SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count));
+ uint64 SourceArraySize = sizeof(uint16) * File->Source_Count;
+ Sorted.Source_SortSize = SourceArraySize;
+ void *Source_SortedArray = Memory_PushScratch(Memory, Sorted.Source_SortSize);
+ Arbitrary_Zero((uint8 *)Source_SortedArray, Sorted.Source_SortSize);
+ Sorted.SourceArray = (uint16 *)Source_SortedArray;
+
uint64 PropertyArraySize = sizeof(uint16) * 8 * MAX_KEYFRAMES_PER_BLOCK * File->Layer_Count;
uint64 PropertyInfoSize = sizeof(sorted_property_info) * 8 * File->Layer_Count;
Sorted.Property_SortSize = PropertyArraySize + PropertyInfoSize;
@@ -1004,21 +1097,16 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem
Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray;
Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize);
- uint64 SourceArraySize = sizeof(uint16) * File->Source_Count;
- Sorted.Source_SortSize = SourceArraySize;
- void *Source_SortedArray = Memory_PushScratch(Memory, Sorted.Source_SortSize);
- Arbitrary_Zero((uint8 *)Source_SortedArray, Sorted.Source_SortSize);
- Sorted.SourceArray = (uint16 *)Source_SortedArray;
-
TempSource_SortAll(File, State, Memory, Sorted.SourceArray, &Sorted.TempSourceCount);
Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyInfo, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
+ LayerProperty_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyInfo, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
return Sorted;
}
void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize, uint64 Source_SortSize)
{
- Memory_PopScratch(Memory, Source_SortSize);
Memory_PopScratch(Memory, Property_SortSize);
+ Memory_PopScratch(Memory, Source_SortSize);
Memory_PopScratch(Memory, Layer_SortSize);
}
diff --git a/effects.cpp b/effects.cpp
index 98d6984..c5a07af 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -1,9 +1,18 @@
#include "effects_software.cpp"
+#include "effects_gl.cpp"
static void
Effect_DrawColor(real32 *Data, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, uint16 ShaderProgram)
{
v4 Color = { Data[0], Data[1], Data[2], Data[3] };
blend_mode BlendMode = (blend_mode)Data[4];
- Effect_Software_DrawColor(Width, Height, BytesPerPixel, EffectBitmapAddress, Color, BlendMode);
+ Effect_GL_DrawColor(Width, Height, BytesPerPixel, EffectBitmapAddress, ShaderProgram, Color, BlendMode);
+ // Effect_Software_DrawColor(Width, Height, BytesPerPixel, EffectBitmapAddress, Color, BlendMode);
+}
+
+static void
+Effect_GaussianBlur(real32 *Data, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, uint16 ShaderProgram)
+{
+ real32 Radius = Data[0];
+ Effect_GL_GaussianBlur(Width, Height, BytesPerPixel, EffectBitmapAddress, ShaderProgram, Radius);
}
diff --git a/effects_constructors.cpp b/effects_constructors.cpp
index 13fec9a..7eb2143 100644
--- a/effects_constructors.cpp
+++ b/effects_constructors.cpp
@@ -95,15 +95,15 @@ Effect_InitEntries(project_state *State)
Effect_AddProperty_Col(State, "Color", V4(0.3f, 0.2f, 0.6f, 1.0f));
Effect_AddProperty_Blendmode(State, "Blend mode", blend_softlight);
Effect_EndEntry(State);
+ // Gaussian blur
+ Effect_AddEntry(State, "Gaussian blur", "REALGBLR", &Effect_GaussianBlur, GLShader_GaussianBlur);
+ Effect_AddProperty_Real(State, "Radius", 1.0f, 0.0f, 200.0f);
+ Effect_EndEntry(State);
/*
Effect_AddEntry(State, "Curves", "REALCRVS", &Effect_Curves, NULL, effect_display_type_curves);
for (int i = 0; i < MAX_PROPERTIES_PER_EFFECT; i++) {
Effect_AddProperty_Real(State, "point", 0.0f);
}
- // Gaussian blur
- Effect_AddEntry(State, "Gaussian blur", "REALGBLR", &Effect_GaussianBlur, GLShader_GaussianBlur);
- Effect_AddProperty_Real(State, "Radius", 1.0f, 0.0f, 200.0f);
- Effect_EndEntry(State);
// Test gradient
Effect_AddEntry(State, "Test gradient", "REALTGRD", &Effect_TestGradient, NULL);
Effect_AddProperty_Col(State, "Color", V4(0.3f, 0.2f, 0.6f, 1.0f));
diff --git a/effects_gl.cpp b/effects_gl.cpp
new file mode 100644
index 0000000..2b8eac1
--- /dev/null
+++ b/effects_gl.cpp
@@ -0,0 +1,74 @@
+void GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 Multisample);
+static uint16 Effect_GL_InitShader(const char *Effect);
+static void GL_BindDefaultVertexArrays();
+
+void Effect_GL_Start(gl_effect_layer *Test, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, uint16 ShaderProgram)
+{
+ GL_UpdateTexture(Test, EffectBitmapAddress, Width, Height, BytesPerPixel, 0);
+
+ GL_BindDefaultVertexArrays();
+
+ glUseProgram(ShaderProgram);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, Test->FramebufferObject);
+ glBindRenderbuffer(GL_RENDERBUFFER, Test->Color_Renderbuffer);
+
+ glBindTexture(GL_TEXTURE_2D, Test->Texture);
+ int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16;
+ int ByteFlag2 = (BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ glTexImage2D(GL_TEXTURE_2D, 0, ByteFlag, Width, Height, 0, GL_RGBA,
+ ByteFlag2, EffectBitmapAddress);
+}
+
+void Effect_GL_DrawColor(int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress,
+ uint16 ShaderProgram, v4 Color, blend_mode BlendMode)
+{
+ gl_effect_layer Test = {};
+
+ int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16;
+ int ByteFlag2 = (BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ Effect_GL_Start(&Test, Width, Height, BytesPerPixel, EffectBitmapAddress, ShaderProgram);
+
+ int Uniform = glGetUniformLocation(ShaderProgram, "Color");
+ glUniform4f(Uniform, Color.r, Color.g, Color.b, Color.a);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, ByteFlag2, EffectBitmapAddress);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ GL_DeleteHWBuffer(&Test);
+}
+
+void Effect_GL_GaussianBlur(int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress,
+ uint16 ShaderProgram, real32 Radius)
+{
+ gl_effect_layer Test = {};
+
+ int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16;
+ int ByteFlag2 = (BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ Effect_GL_Start(&Test, Width, Height, BytesPerPixel, EffectBitmapAddress, ShaderProgram);
+
+ // horizontal pass
+ int Uniform = glGetUniformLocation(ShaderProgram, "Radius");
+ glUniform1f(Uniform, Radius + 1.60f);
+ Uniform = glGetUniformLocation(ShaderProgram, "Direction");
+ glUniform2f(Uniform, 1.0f, 0.0f);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, ByteFlag2, EffectBitmapAddress);
+ //
+
+ // vertical pass
+ glTexImage2D(GL_TEXTURE_2D, 0, ByteFlag, Width, Height, 0, GL_RGBA,
+ ByteFlag2, EffectBitmapAddress);
+
+ Radius = glGetUniformLocation(ShaderProgram, "Direction");
+ glUniform2f(Uniform, 0.0f, 1.0f);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, ByteFlag2, EffectBitmapAddress);
+ //
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ GL_DeleteHWBuffer(&Test);
+}
diff --git a/gl_calls.cpp b/gl_calls.cpp
index 277db2e..1cb408a 100644
--- a/gl_calls.cpp
+++ b/gl_calls.cpp
@@ -29,56 +29,6 @@ const char *DefaultFragmentShaderSource = "#version 330 core\n"
" FragColor = vec4(vec3(1.0f), Col.a);\n"
"}\n"
"}\0";
-const char *FragmentShaderEffectSource[] = {"",
-"#version 330 core\n"
-"out vec4 FragColor;\n"
-"in vec2 TexCoord;\n"
-"uniform float Start;\n"
-"uniform float Mid;\n"
-"uniform float End;\n"
-"uniform vec4 StartCol;\n"
-"uniform vec4 MidCol;\n"
-"uniform vec4 EndCol;\n"
-"uniform sampler2D ourTexture;\n"
-"void main()\n"
-"{\n"
-"vec4 OutCol = texture(ourTexture, TexCoord);\n"
-// individual channels
-"vec4 ColorI = pow(OutCol, MidCol);\n"
-"vec4 ValI = 1.0f / (EndCol - StartCol) * (ColorI - StartCol);\n"
-// global channel (doesn't affect alpha)
-"vec4 ColorG = pow(ValI, vec4(Mid));\n"
-"vec4 ValG = 1.0f / (End - Start) * (ColorG - Start);\n"
-"ValG = vec4(ValG.rgb, ValI.a);\n"
-"FragColor = clamp(ValG, 0.0f, 1.0f);\n"
-"}\0",
-"#version 330 core\n"
-"uniform float Radius;\n"
-"uniform vec2 Direction;\n"
-"uniform sampler2D ourTexture;\n"
-"out vec4 FragColor;\n"
-"in vec2 TexCoord;\n"
-"\n"
-"vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {\n"
-" vec4 color = vec4(0.0f);\n"
-" float Omega = Radius / 3;\n"
-" float Divisor = 2*Omega*Omega;\n"
-" float A2 = 1.0f / (Omega * sqrt(2*3.141592));\n"
-" for (float Span = -round(Radius); Span < round(Radius); Span++) {\n"
-" float Dividend = -Span * Span;\n"
-" float Multiplier = A2 * exp(Dividend/Divisor);\n"
-" vec2 Dir = Span*direction;\n"
-" color += texture2D(image, uv + (Dir / resolution)) * Multiplier;\n"
-" }\n"
-" return color;\n"
-"}\n"
-"void main(void) {\n"
-" gl_FragColor = blur(ourTexture, TexCoord, vec2(1280, 720), Direction);\n"
-"}\0"
-};
-
-
-// #include "effects_gl.cpp"
static void GL_InitDefaultShader() {
DefaultVertexShader = glCreateShader(GL_VERTEX_SHADER);
@@ -168,6 +118,23 @@ GL_GenAndBindTexture(GLuint *GLTexture, int Width, int Height, int BytesPerPixel
glTexImage2D(GL_TEXTURE_2D, 0, ByteFlag, Width, Height, 0, GL_RGBA, ByteFlag2, BufferAddress);
}
+static void
+GL_BindDefaultVertexArrays()
+{
+ glBindVertexArray(DefaultVerts.VertexArrayObject);
+ // Switch to main buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, DefaultVerts.ElementBufferObject);
+ glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ // texture coordinate (note the last parameter's offset)
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+}
+
void
GL_InitHWBuffer(gl_effect_layer *Test)
{
diff --git a/main.cpp b/main.cpp
index 76b085e..bb780c4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -187,7 +187,7 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI,
// }
ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyInfo, Sorted.PropertyArray);
ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray);
- ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.PropertyArray);
+ ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyInfo, Sorted.PropertyArray);
ImGui_ColorPanel(File, State, UI, Memory, io);
ImGui_EffectsPanel(File, State, Memory, UI, io);
#if STABLE
@@ -221,22 +221,24 @@ Render_Main(void *Data, void *OutputBuffer, render_type RenderType, rectangle Re
}
static void
-Layer_UpdateAllKeyframes(project_data *File, project_state *State, memory *Memory, block_layer *Layer, uint16 Index_Physical, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray, uint16 Frame_Current)
+Layer_UpdateAllKeyframes(project_data *File, project_state *State, memory *Memory, block_layer *Layer, uint16 Index_Physical,
+ sorted_property_info *SortedProperty, uint16 *SortedKeyframe, uint16 Frame_Current)
{
int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
- sorted_property_info *InfoLocation = Property_GetSortedInfo(SortedPropertyInfo, Index_Physical, h);
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, Index_Physical, h);
+ int h = 0, c = 0, p = 0;
+ property_channel *Property = NULL;
+ while (Layer_LoopChannels(State, Memory, &SortedProperty, &SortedKeyframe, Layer, &Property, NULL, &h, &c, &p))
+ {
+ Assert(Property);
if (Property->Block_Bezier_Count) {
real32 MinY, MaxY;
- Property_MinMax_Y(Memory, State, Property, InfoLocation, &MinY, &MaxY);
+ 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, ArrayLocation[0]);
+ bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[0]);
Bezier_EvaluateValue(State, FirstPointAddress, FirstPointPos);
v2 LastPointPos[3];
- bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[Property->Keyframe_Count - 1]);
+ bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[Property->Keyframe_Count - 1]);
Bezier_EvaluateValue(State, LastPointAddress, LastPointPos);
if (FirstPointPos[0].x >= Frame_Current) {
Property->CurrentValue = FirstPointPos[0].y;
@@ -246,17 +248,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, ArrayLocation[KeyframeIndex + 1]);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex + 1]);
Bezier_EvaluateValue(State, PointAddress, PointPos, 1, Y_Increment);
if (PointPos[0].x >= Frame_Current)
break;
KeyframeIndex++;
}
v2 PointPos[3];
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex]);
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex]);
Bezier_EvaluateValue(State, PointAddress, PointPos, 1, Y_Increment);
v2 NextPointPos[3];
- bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex + 1]);
+ bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property, SortedKeyframe[KeyframeIndex + 1]);
Bezier_EvaluateValue(State, NextPointAddress, NextPointPos, 1, Y_Increment);
if (PointAddress->Type == interpolation_type_hold) {
Property->CurrentValue = PointPos[0].y;
@@ -298,7 +300,9 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io
Layer->Frame_End > Frame_Current && Layer->IsVisible)
{
if (State->UpdateKeyframes) {
- Layer_UpdateAllKeyframes(File, State, Memory, Layer, Index_Physical, SortedPropertyInfo, SortedPropertyArray, Frame_Current);
+ sorted_property_info *SortedLayerProperties = SortedPropertyInfo + SortedLayerInfo->SortedPropertyStart;
+ uint16 *SortedLayerKeyframes = SortedPropertyArray + SortedLayerInfo->SortedKeyframeStart;
+ Layer_UpdateAllKeyframes(File, State, Memory, Layer, Index_Physical, SortedLayerProperties, SortedLayerKeyframes, Frame_Current);
}
layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical];
@@ -628,6 +632,13 @@ int main(int argc, char *argv[]) {
curl_state ProgHandle = {};
#endif
+#if DEBUG
+ sprintf(State->DummyName, "test2");
+ File_Open(File, State, &Memory, State->DummyName);
+ State->UpdateFrame = true;
+ State->MostRecentlySelectedLayer = 0;
+#endif
+
while (State->IsRunning)
{
// State->Interact_Active = interact_type_layer_move;
diff --git a/main.h b/main.h
index b322173..c1b37f3 100644
--- a/main.h
+++ b/main.h
@@ -152,6 +152,9 @@ struct sorted_layer
{
uint16 Block_Layer_Index;
real32 SortedOffset;
+ uint16 Sorted_Effect_Index[MAX_EFFECTS];
+ uint16 SortedPropertyStart;
+ uint16 SortedKeyframeStart;
};
struct sorted_file
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index 4bdedea..dbadd11 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -36,12 +36,18 @@ ImGui_PropertyInteract_Slider(project_state *State, memory *Memory, property_cha
}
static void
-ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, uint16 *SortedPropertyArray)
+ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray,
+ sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
{
bool32 Display = 1;
block_layer *Layer = NULL;
+ sorted_layer *SortedLayer = NULL;
if (State->MostRecentlySelectedLayer > -1) {
Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->MostRecentlySelectedLayer, 0);
+ sorted_comp_info SortedCompInfo = SortedCompArray[Layer->Block_Composition_Index];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, &SortedCompInfo, Layer->Block_Composition_Index);
+ SortedLayer = &SortedLayerInfo[State->MostRecentlySelectedLayer];
if (!Layer->Occupied)
Display = 0;
} else {
@@ -58,22 +64,49 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImVec2 WindowMinAbs = ImGui::GetWindowPos();
ImVec2 WindowMaxAbs = WindowMinAbs + WindowSize;
ImGui::Text("Transform");
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
+
+ sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayer->SortedPropertyStart;
+ uint16 *ArrayLocation = SortedPropertyArray + SortedLayer->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))
+ {
ImGui::PushID(Property);
- if (ImGui::Button("K")) {
- History_Entry_Commit(Memory, "Add keyframe");
- bezier_point Point = { 1, {(real32)State->Frame_Current, Property->CurrentValue, -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h);
- Bezier_Add(Memory, Property, Point, ArrayLocation);
- History_Entry_End(Memory);
+ if ((h - 1) < AmountOf(Layer->Property)) {
+ if (ImGui::Button("K")) {
+ uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h-1);
+ Property_AddKeyframe(Memory, Property, State->Frame_Current, ArrayLocation);
+ }
+ ImGui::SameLine();
+ char *Name = DefaultChannel[h-1];
+ ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
+ ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Layers);
+ } else {
+ Assert(Effect);
+ header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID);
+ header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + c - 1];
+ Assert(EffectHeader->DisplayType == effect_display_type_standard);
+ if ((c - 1) == 0) {
+ ImGui::PushID(Effect->Index);
+ ImGui::Text(EffectHeader->Name);
+ ImGui::PopID();
+ }
+ if (ChannelHeader.DisplayType == property_display_type_standard) {
+ if (ImGui::Button("K")) {
+ // uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h);
+ // Property_AddKeyframe(Memory, Property, State->Frame_Current, ArrayLocation);
+ }
+ ImGui::SameLine();
+ ImGui::DragScalar(ChannelHeader.Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
+ ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
+ } else {
+ Assert(0);
+ }
}
- ImGui::SameLine();
- char *Name = DefaultChannel[h];
- ImGui::DragScalar(Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
- ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Layers);
ImGui::PopID();
}
+#if 0
for (int i = 0; i < Layer->Block_Effect_Count; i++)
{
block_effect Effect = *(block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]);
@@ -81,12 +114,19 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui::PushID(Effect.Index);
ImGui::Text(EffectHeader->Name);
ImGui::PopID();
- if (EffectHeader->DisplayType == effect_display_type_standard) {
for (int c = 0; c < EffectHeader->Property_Count; c++) {
header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + c];
property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[c]);
ImGui::PushID(Property);
+ // NOTE(fox): We might have to make a system for processing create/delete
+ // calls after the UI if things like the Count get incremented and invalid
+ // data is read.
if (ChannelHeader.DisplayType == property_display_type_standard) {
+ if (ImGui::Button("K")) {
+ uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, State->MostRecentlySelectedLayer, h);
+ Property_AddKeyframe(Memory, Property, State->Frame_Current, ArrayLocation);
+ }
+ ImGui::SameLine();
ImGui::DragScalar(ChannelHeader.Name, ImGuiDataType_Float, &Property->CurrentValue, Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
ImGui_PropertyInteract_Slider(State, Memory, Property, io, WindowMinAbs, WindowMaxAbs, F_Properties);
} else if (ChannelHeader.DisplayType == property_display_type_color) {
@@ -155,6 +195,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
Assert(0);
}
}
+#endif
if (Layer->IsPrecomp) {
block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
ImGui::DragScalar("Width", ImGuiDataType_U16, &Comp->Width);
@@ -1503,165 +1544,178 @@ ImGui_Timeline_DrawKeySheet(project_data *File, project_state *State, memory *Me
static void
ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list,
ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize,
- ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
+ ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray,
+ sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
{
// I'm using the draw splitter here to be able to draw the dots on top of the graph lines.
State->Test.Split(draw_list, 2);
- 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)
- continue;
-
- int32 Frame_Start = Layer->Frame_Start;
+ for (int c = 0; c < File->Comp_Count; c++) {
+ sorted_comp_info SortedCompInfo = SortedCompArray[c];
+ sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, &SortedCompInfo, c);
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++) {
+ sorted_layer *SortedLayer = &SortedLayerInfo[i];
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayer->Block_Layer_Index);
+ if (!Layer->IsSelected)
+ continue;
- ImGui::PushID(i);
+ int32 Frame_Start = Layer->Frame_Start;
- if ((State->Interact_Active == interact_type_keyframe_move ||
- State->Interact_Active == interact_type_keyframe_rotate ||
- State->Interact_Active == interact_type_keyframe_scale))
- {
- ImGui_WarpMouse(State, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder);
- ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]);
- DragDelta = DragDelta + (ImVec2(State->Warp_X, State->Warp_Y) * TimelineSize);
- if (io.MouseDelta.x || io.MouseDelta.y) {
- State->UpdateFrame = true;
- }
- if (State->Interact_Active == interact_type_keyframe_move) {
- // The Y increment varies between graphs, so we have to do it in the Bezier_EvaluateValue call.
- State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x) / Increment.x;
- State->Interact_Offset[1] = DragDelta.y;
- } else if (State->Interact_Active == interact_type_keyframe_scale) {
- State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x;
- } else if (State->Interact_Active == interact_type_keyframe_rotate) {
- State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x);
- /*
- real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]);
- real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x);
- State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New));
- */
- }
- ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
- }
+ ImGui::PushID(i);
- for (int h = 0; h < AmountOf(Layer->Property); h++) {
- property_channel *Property = &Layer->Property[h];
- sorted_property_info *InfoLocation = Property_GetSortedInfo(SortedPropertyInfo, i, h);
- uint16 *ArrayLocation = Property_GetSortedArray(SortedPropertyArray, i, h);
- ImGui::PushID(Property);
- if (Property->Block_Bezier_Count) {
- real32 MinY, MaxY;
- Property_MinMax_Y(Memory, State, Property, InfoLocation, &MinY, &MaxY, 0);
- real32 Y_Increment = 1 / (MaxY - MinY);
-
- real32 GraphScale = 0;
- real32 GraphPos = 0;
- if ((1 / Y_Increment) < 5) {
- GraphScale = 0.2;
- GraphPos = 0.3;
- } else if ((1 / Y_Increment) > 700) {
- GraphScale = 0.6;
- GraphPos = 0.06;
- } else {
- GraphScale = 0.4;
- GraphPos = 0.2;
+ if ((State->Interact_Active == interact_type_keyframe_move ||
+ State->Interact_Active == interact_type_keyframe_rotate ||
+ State->Interact_Active == interact_type_keyframe_scale))
+ {
+ ImGui_WarpMouse(State, io.MousePos, TimelineAbsolutePos, TimelineAbsolutePos + TimelineSizeWithBorder);
+ ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]);
+ DragDelta = DragDelta + (ImVec2(State->Warp_X, State->Warp_Y) * TimelineSize);
+ if (io.MouseDelta.x || io.MouseDelta.y) {
+ State->UpdateFrame = true;
}
+ if (State->Interact_Active == interact_type_keyframe_move) {
+ // The Y increment varies between graphs, so we have to do it in the Bezier_EvaluateValue call.
+ State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x) / Increment.x;
+ State->Interact_Offset[1] = DragDelta.y;
+ } else if (State->Interact_Active == interact_type_keyframe_scale) {
+ State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x;
+ } else if (State->Interact_Active == interact_type_keyframe_rotate) {
+ State->Interact_Offset[0] = (DragDelta.x / TimelineZoomSize.x);
+ /*
+ real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]);
+ real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x);
+ State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New));
+ */
+ }
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
+ }
+ sorted_property_info *InfoLocation = SortedPropertyInfo + SortedLayer->SortedPropertyStart;
+ uint16 *ArrayLocation = SortedPropertyArray + SortedLayer->SortedKeyframeStart;
+ int h1 = 0, c1 = 0, p = 0;
+ property_channel *Property = NULL;
+ while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, NULL, &h1, &c1, &p))
+ {
+ ImGui::PushID(Property);
+ 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(MaxY >= MinY);
+ if (MaxY <= MinY)
+ int p = 0;
+ real32 Y_Increment = (MaxY - MinY) ? (1 / (MaxY - MinY)) : 0.5;
+
+ real32 GraphScale = 0;
+ real32 GraphPos = 0;
+ if ((1 / Y_Increment) < 5) {
+ GraphScale = 0.2;
+ GraphPos = 0.3;
+ } else if ((1 / Y_Increment) > 700) {
+ GraphScale = 0.6;
+ GraphPos = 0.06;
+ } else {
+ GraphScale = 0.4;
+ GraphPos = 0.2;
+ }
- real32 GraphMoveHeight = TimelineMoveSize.y + (TimelineZoomSize.y * GraphPos);
- real32 GraphZoomHeight = TimelineZoomSize.y * GraphScale;
-
- uint32 GraphCol = InfoLocation->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++) {
- int k = ArrayLocation[p];
- int Idx = (p % 2);
- int NewIdx = Idx * 3;
- int OldIdx = (NewIdx == 3) ? 0 : 3;
- PointAddress[Idx] = Bezier_LookupAddress(Memory, Property, k);
-
- v2 PointPos[3];
- Bezier_EvaluateValue(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment);
-
- ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[2]) };
- ImVec2 Keyframe_LocalPos_Ratio[3];
- for (int b = 0; b < 3; b++) {
- Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, MinY)) * ImVec2(Increment.x, Y_Increment);
- Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + ImVec2(TimelineMoveSize.x, GraphMoveHeight) + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * ImVec2(TimelineZoomSize.x, GraphZoomHeight));
- }
+ real32 GraphMoveHeight = TimelineMoveSize.y + (TimelineZoomSize.y * GraphPos);
+ real32 GraphZoomHeight = TimelineZoomSize.y * GraphScale;
- if (State->BoxSelect) {
- if (ImGui_TestBoxSelection_Point(Keyframe_ScreenPos[NewIdx], io, &PointAddress[Idx]->IsSelected))
- State->RecentSelectionType = selection_type_keyframe;
- }
+ uint32 GraphCol = InfoLocation->IsGraphSelected ? IM_COL32(255, 180, 150, 255) : IM_COL32(255, 255, 255, 70);
- State->Test.SetCurrentChannel(draw_list, 1);
-
- ImVec2 ButtonSize(16, 16);
-
- ImGui::PushID(k);
- int Max = PointAddress[Idx]->IsSelected ? 2 : 0;
- for (int b = Max; b >= 0; b--) {
- ImU32 PointCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f);
- ImU32 LineCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f);
- ImGui::PushID(b);
- ImGui::SetCursorScreenPos(Keyframe_ScreenPos[NewIdx + b] - (ButtonSize * 0.5));
- ImGui::InvisibleButton("##keyframemover", ButtonSize, ImGuiMouseButton_Left);
- bool32 IsHovered = ImGui::IsItemHovered();
- bool32 IsItemActive = ImGui::IsItemActive();
- bool32 IsItemActivated = ImGui::IsItemActivated();
- bool32 IsItemDeactivated = ImGui::IsItemDeactivated();
- bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left);
- bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right);
-
- if (IsHovered) {
- PointCol = ImColor(1.0f, 0.8f, 0.8f, 1.0f);
- ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+ bezier_point *PointAddress[2] = {};
+ ImVec2 Keyframe_ScreenPos[6] = {};
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ int k = ArrayLocation[p];
+ if (Property->Keyframe_Count == 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);
+
+ v2 PointPos[3];
+ Bezier_EvaluateValue(State, PointAddress[Idx], PointPos, GraphZoomHeight, Y_Increment);
+
+ ImVec2 Keyframe_LocalPos[3] = { V2(PointPos[0]), V2(PointPos[0] + PointPos[1]), V2(PointPos[0] + PointPos[2]) };
+
+ ImVec2 Keyframe_LocalPos_Ratio[3];
+ for (int b = 0; b < 3; b++) {
+ Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, MinY)) * ImVec2(Increment.x, Y_Increment);
+ Keyframe_ScreenPos[NewIdx + b] = TimelineAbsolutePos + ImVec2(TimelineMoveSize.x, GraphMoveHeight) + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 1)) * ImVec2(TimelineZoomSize.x, GraphZoomHeight));
}
- if (IsItemActivated) {
- PointAddress[Idx]->IsSelected = b+1;
+ if (State->BoxSelect) {
+ if (ImGui_TestBoxSelection_Point(Keyframe_ScreenPos[NewIdx], io, &PointAddress[Idx]->IsSelected))
+ State->RecentSelectionType = selection_type_keyframe;
}
- if (b != 0 && PointAddress[Idx]->IsSelected)
- draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx + b], LineCol, 2.0f);
+ State->Test.SetCurrentChannel(draw_list, 1);
+
+ ImVec2 ButtonSize(16, 16);
+
+ ImGui::PushID(k);
+ int Max = PointAddress[Idx]->IsSelected ? 2 : 0;
+ for (int b = Max; b >= 0; b--) {
+ ImU32 PointCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f);
+ ImU32 LineCol = ((PointAddress[Idx]->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f);
+ ImGui::PushID(b);
+ ImGui::SetCursorScreenPos(Keyframe_ScreenPos[NewIdx + b] - (ButtonSize * 0.5));
+ ImGui::InvisibleButton("##keyframemover", ButtonSize, ImGuiMouseButton_Left);
+ bool32 IsHovered = ImGui::IsItemHovered();
+ bool32 IsItemActive = ImGui::IsItemActive();
+ bool32 IsItemActivated = ImGui::IsItemActivated();
+ bool32 IsItemDeactivated = ImGui::IsItemDeactivated();
+ bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left);
+ bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right);
+
+ if (IsHovered) {
+ PointCol = ImColor(1.0f, 0.8f, 0.8f, 1.0f);
+ ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
+ }
- if (b == 0) {
- draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx + b], 4, PointCol);
- if (InfoLocation->IsGraphSelected) {
- char buf[8];
- sprintf(buf, "%.2f", Keyframe_LocalPos[0].y);
- draw_list->AddText(Keyframe_ScreenPos[NewIdx + b], 0xFFFFFFFF, buf);
+ if (IsItemActivated) {
+ PointAddress[Idx]->IsSelected = b+1;
+ }
+
+ if (b != 0 && PointAddress[Idx]->IsSelected)
+ draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx + b], LineCol, 2.0f);
+
+ if (b == 0) {
+ draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx + b], 4, PointCol);
+ if (InfoLocation->IsGraphSelected) {
+ char buf[8];
+ sprintf(buf, "%.2f", Keyframe_LocalPos[0].y);
+ draw_list->AddText(Keyframe_ScreenPos[NewIdx + b], 0xFFFFFFFF, buf);
+ }
+ } else {
+ draw_list->AddCircle(Keyframe_ScreenPos[NewIdx + b], 6, PointCol, 0, 2);
}
- } else {
- draw_list->AddCircle(Keyframe_ScreenPos[NewIdx + b], 6, PointCol, 0, 2);
- }
+ ImGui::PopID();
+ }
ImGui::PopID();
- }
- ImGui::PopID();
- State->Test.SetCurrentChannel(draw_list, 0);
+ State->Test.SetCurrentChannel(draw_list, 0);
- if (p != 0) {
- if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) {
- draw_list->AddBezierCubic(Keyframe_ScreenPos[OldIdx], Keyframe_ScreenPos[OldIdx + 2],
- Keyframe_ScreenPos[NewIdx + 1], Keyframe_ScreenPos[NewIdx], GraphCol, 1.0f, 0);
- } else {
- draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], GraphCol, 1.0f);
+ if (p != 0) {
+ if (PointAddress[0]->Type == interpolation_type_bezier && PointAddress[1]->Type == interpolation_type_bezier) {
+ draw_list->AddBezierCubic(Keyframe_ScreenPos[OldIdx], Keyframe_ScreenPos[OldIdx + 2],
+ Keyframe_ScreenPos[NewIdx + 1], Keyframe_ScreenPos[NewIdx], GraphCol, 1.0f, 0);
+ } else {
+ draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], GraphCol, 1.0f);
+ }
}
}
}
+ ImGui::PopID();
}
ImGui::PopID();
}
-
- ImGui::PopID();
}
State->Test.Merge(draw_list);
}
@@ -2025,8 +2079,8 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
State->FocusedWindow = focus_timeline;
}
- if (State->TimelineMode == timeline_mode_graph)
- ImGui_GraphInfo(File, State, Memory, UI, io, SortedPropertyInfo, SortedPropertyArray);
+ // if (State->TimelineMode == timeline_mode_graph)
+ // ImGui_GraphInfo(File, State, Memory, UI, io, SortedPropertyInfo, SortedPropertyArray);
real32 FontHeight = ImGui::GetFontSize();
@@ -2123,7 +2177,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
IM_COL32(50, 50, 50, 230));
ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list,
Increment, TimelineAbsolutePos, GraphMoveSize, GraphZoomSize,
- TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedPropertyInfo, SortedPropertyArray);
+ TimelineSize, TimelineSizeWithBorder, LayerIncrement,
+ SortedCompArray, SortedLayerArray,
+ SortedPropertyInfo, SortedPropertyArray);
}
ImGui_Timeline_HorizontalIncrementDraw(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize);