From 02870398a99fab6351182fba407d7d733affa5a1 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Fri, 17 Feb 2023 17:20:18 -0500 Subject: blend mode rendering halfway implemented --- src/bezier.cpp | 58 +++------ src/createcalls.cpp | 148 +++++++++++++++++++---- src/ffmpeg_backend.cpp | 10 ++ src/gl_calls.cpp | 287 ++++++++++++++++++++++++++++++++++++++------ src/imgui_ui.cpp | 26 +++- src/imgui_ui_properties.cpp | 6 +- src/imgui_ui_timeline.cpp | 52 +++++--- src/imgui_ui_viewport.cpp | 47 +++++++- src/include/all.h | 29 +++-- src/include/gl_calls.h | 5 +- src/include/main.h | 15 ++- src/layer.cpp | 2 +- src/main.cpp | 193 ++++++++++++++++++++++++----- src/memory.cpp | 11 +- src/prenderer.cpp | 1 - src/sorted.cpp | 6 +- 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 +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); @@ -385,6 +547,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) { @@ -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++; } -- cgit v1.2.3