#include #include #if WINDOWS #include #else #include #include #endif #if ARM #include #include #else #include #endif #include "imgui/imgui.h" #include "imgui/backends/imgui_impl_sdl.h" #include "imgui/backends/imgui_impl_opengl3.h" #if WINDOWS #include #else #include #endif #if defined(IMGUI_IMPL_OPENGL_ES2) #include #else #include #endif #define STB_IMAGE_IMPLEMENTATION #define STBI_FAILURE_USERMSG #include "lib/stb_image.h" #include "defines.h" #include "my_math.h" #include "structs.h" #include "memory.h" #include "main.h" #include "debug.h" #include "functions.h" // #include "sharebuffer.h" SDL_Thread *Thread[8]; SDL_sem *Semaphore; SDL_atomic_t CurrentEntry; SDL_atomic_t QueuedEntries; SDL_atomic_t CompletedEntries; render_entry Entries[256]; static uint64 BitmapBlockSize; static instruction_mode InstructionMode = instruction_mode_scalar; static uint32 RandomGlobalIncrement = 0; // render_entry Entries[256]; #include "memory.cpp" #include "undo.cpp" #include "strings.cpp" #if THREADED #include "threading.cpp" #endif #include "createcalls.cpp" // #include "ffmpeg_backend.cpp" #include "my_imgui_widgets.cpp" #include "prenderer.cpp" #include "gl_calls.cpp" #include "bezier.cpp" #if 0 #include "effects.cpp" #include "keyframes.cpp" #include "layer.cpp" #include "bitmap_calls.cpp" #endif static void Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window) { ImGui::Render(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); SDL_GL_SwapWindow(window); } static void Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, SDL_Window *window, GLuint textureID) { ImGuiIO& io = ImGui::GetIO(); SDL_Event event = {}; while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); if (event.type == SDL_DROPFILE) { char *DropFile = event.drop.file; Source_Generate(File, State, Memory, DropFile); SDL_free(DropFile); } if (event.type == SDL_QUIT) State->IsRunning = false; if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) State->IsRunning = false; } if (UI->Warp_WantSetPos) { ImGui::GetIO().WantSetMousePos = true; io.MousePos = UI->Warp_PositionToSet; } ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL2_NewFrame(); ImGui::NewFrame(); if (UI->Warp_WantSetPos) { ImGui_WarpMouseFinish(UI, io.MousePos); io.MouseDelta = {}; UI->Warp_WantSetPos = false; } // NOTE(fox): The only requirement for something that needs to happen before the sort is anything that creates/deletes layers. // The requirement for something after the sort is things that depend on the sort. (obvious) if (!io.WantCaptureKeyboard) ImGui_ProcessInputs(File, State, UI, Memory, io); sorted_file Sorted = File_Sort_Push(File, State, Memory); if (ImGui::IsKeyPressed(ImGuiKey_T)) { Interact_Transform_Begin(File, Memory, State, io.MousePos, Sorted.CompArray, Sorted.LayerArray); } ImGui::DockSpaceOverViewport(); if (Debug.ToggleWindow) { ImGui::ShowDemoWindow(); ImGui_DebugMemoryViewer(Memory, State); ImGui_DebugUndoTree(Memory, State); } if (State->Initializing == 3) { Source_UICreateButton(File, State, Memory, Sorted.CompArray, Sorted.LayerArray); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); History_Entry_Commit(Memory, "Add keyframe"); property_channel *Property = &Layer->x; { bezier_point Point = { 1, {0, 800, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } { bezier_point Point = { 1, {20, 300, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } { bezier_point Point = { 1, {10, 200, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } { bezier_point Point = { 1, {15, 200, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } History_Entry_End(Memory); /* History_Entry_Commit(Memory, "Add keyframe"); Property = &Layer->y; { bezier_point Point = { 1, {0, 400, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } { bezier_point Point = { 1, {20, 400, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } Property = &Layer->opacity; { bezier_point Point = { 1, {0, 1, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } { bezier_point Point = { 1, {20, 0, -5, 0, 5, 0}, interpolation_type_bezier, 0, {0, 0, 0}, 0 }; Bezier_Add(Memory, Property, Point); } */ History_Entry_End(Memory); } ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray); ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray); ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_PropertiesPanel(File, State, UI, Memory, io); ImGui_ColorPanel(File, State, UI, Memory, io); ImGui_Menu(File, State, UI, Memory, io); File_Sort_Pop(Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize); #if DEBUG Debug.Temp = {}; #endif ImGui::EndFrame(); } static void * Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 *SortedPropertyArray, uint32 CompIndex) { 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, State->Frame_Current); void *CompBuffer = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry_Main->Block_StartIndex); uint64 Size = Comp->Width * Comp->Height * Comp->BytesPerPixel; Arbitrary_Zero((uint8 *)CompBuffer, Size); // if (Entry_Main->IsCached) // return CompBuffer; uint64 Comp_TimeStart = GetTime(); sorted_comp_info *SortedCompInfo = &SortedCompArray[CompIndex]; sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); for (int i = 0; i < SortedCompInfo->LayerCount; i++) { sorted_layer SortEntry = SortedLayerInfo[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); if (Layer->Frame_Start <= State->Frame_Current && Layer->Frame_End > State->Frame_Current && Layer->IsVisible) { layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical]; void *BitmapAddress = NULL; if (!Layer->IsPrecomp) { block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); if (Source->Type == source_type_principal) { BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index); } else { cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, 0); if (!Entry->IsCached) { uint64 Src_TimeStart = GetTime(); block_string *Name = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Source->Path_String_Index); int w = 0, h = 0; void *temp = stbi_load(Name->Char, &w, &h, NULL, 4); Source->Width = w; Source->Height = h; Source->BytesPerPixel = 4; uint64 Size = Source->Width * Source->Height * Source->BytesPerPixel; void *Source_Address = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex); Arbitrary_WriteInto((uint8 *)temp, (uint8 *)Source_Address, Size); stbi_image_free(temp); BitmapState->ToUpdate = false; BitmapState->CurrentFrame = 0; Entry->CycleTime = GetTime() - Src_TimeStart; Layer->x.CurrentValue = Comp->Width/2; Layer->y.CurrentValue = Comp->Height/2; Entry->IsCached = true; } BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex); } } else { block_composition *Precomp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index); cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_comp, Layer->Block_Source_Index, State->Frame_Current); // if (!Entry->IsCached) { uint64 Src_TimeStart = GetTime(); Render_Comp(File, State, Memory, io, SortedCompArray, SortedLayerArray, SortedPropertyArray, Layer->Block_Source_Index); Entry->CycleTime = GetTime() - Src_TimeStart; // } BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex); } Assert(BitmapAddress); // for (int a = 0; a < Layer->Block_Mask_Count; a++) { // } // for (int a = 0; a < Layer->Block_Effect_Count; a++) { // } 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]; uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); if (Property->Block_Bezier_Count) { v2 Min, Max; Property_MinMax(Memory, State, Property, ArrayLocation, &Min, &Max); if (Min.x >= State->Frame_Current) { Property->CurrentValue = Min.y; } else if (Max.x <= State->Frame_Current) { Property->CurrentValue = Max.y; } else { int KeyframeIndex = 0; for (;;) { v2 PointPos[3]; bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex + 1]); Bezier_EvaluateValue(State, PointAddress, PointPos); if (PointPos[0].x >= State->Frame_Current) break; KeyframeIndex++; } v2 PointPos[3]; bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex]); Bezier_EvaluateValue(State, PointAddress, PointPos); v2 NextPointPos[3]; bezier_point *NextPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[KeyframeIndex + 1]); Bezier_EvaluateValue(State, NextPointAddress, NextPointPos); Property->CurrentValue = Bezier_SolveYForX(PointPos[0], PointPos[0] + PointPos[2], NextPointPos[0] + NextPointPos[1], NextPointPos[0], State->Frame_Current); } } } /* for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; if (Property->Keyframe_Count) { Property->CurrentValue = State->Frame_Current * 2; } } */ transform_info T = Transform_Calculate(State, Memory, File, Layer, Comp); T.SourceBuffer = BitmapAddress; rectangle RenderRegion = {0, 0, Comp->Width, Comp->Height}; bool32 IsRendering = true; Renderer_Start((void *)&T, CompBuffer, RenderRegion); while (IsRendering) { SDL_Delay(1); Renderer_Check(&IsRendering); // TODO(fox): Make interruptable if the render time gets too long. } } } Entry_Main->CycleTime = GetTime() - Comp_TimeStart; Entry_Main->IsCached = true; return CompBuffer; } static void Main_Renderer(project_data *File, project_state *State, memory *Memory, SDL_Window *window, GLuint textureID, ImGuiIO io) { State->UpdateFrame = false; block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); sorted_file Sorted = File_Sort_Push(File, State, Memory); void *MainCompBuffer = Render_Comp(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray, File->PrincipalCompIndex); File_Sort_Pop(Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize); glBindTexture(GL_TEXTURE_2D, textureID); int ByteFlag2 = (MainComp->BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; if (State->FirstFrame) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MainComp->Width, MainComp->Height, 0, GL_RGBA, ByteFlag2, MainCompBuffer); State->FirstFrame = false; } glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, MainComp->Width, MainComp->Height, GL_RGBA, ByteFlag2, MainCompBuffer); // TODO(fox): garbage collect AV state! } int main(int argc, char *argv[]) { global_memory GlobalMemory = {}; GlobalMemory.Size = ((uint64)1 * 1024 * 1024 * 1024); GlobalMemory.CurrentPosition = 0; #if WINDOWS GlobalMemory.Address = VirtualAlloc(0, GlobalMemory.Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #else GlobalMemory.Address = mmap(0, GlobalMemory.Size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); #endif // 1 meg per block BitmapBlockSize = 1024 * 1024; memory Memory = {}; Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, P_AVInfo, "Image/video headers"); Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_UndoBuffer, "Undo buffer"); Memory_InitTable(&GlobalMemory, &Memory, 40 * 1024 * 1024, P_MiscCache, "Misc persistent"); Memory_InitTable(&GlobalMemory, &Memory, sizeof(project_data), F_File, "File", sizeof(project_data)); Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, F_Precomps, "Precomps", sizeof(block_composition)); Memory_InitTable(&GlobalMemory, &Memory, 2 * 1024 * 1024, F_Layers, "Layers", sizeof(block_layer)); Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, F_Sources, "Sources", sizeof(block_source)); Memory_InitTable(&GlobalMemory, &Memory, 2 * 1024 * 1024, F_Properties, "Properties", sizeof(property_channel)); Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier)); Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string)); Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, F_PrincipalBitmaps, "Principal bitmap data", BitmapBlockSize); Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch"); Memory_InitTable(&GlobalMemory, &Memory, (uint64)200 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer"); #if ARM InstructionMode = instruction_mode_neon; #else if (SDL_HasSSE2()) { InstructionMode = instruction_mode_sse; } if (SDL_HasAVX2()) { InstructionMode = instruction_mode_avx; } #endif project_state *State = (project_state *)Memory.Slot[P_MiscCache].Address; *State = {}; project_data *File = (project_data *)Memory_Block_AllocateAddress(&Memory, F_File); *File = {}; File->Occupied = 1; State->Brush.PaintBuffer = Memory.Slot[B_ScratchSpace].Address; uint64 ScratchPaintSize = 2048*2048*4; Memory.ScratchPos += ScratchPaintSize; ui UI = {}; UI.Test = ImDrawListSplitter(); // int ToolCount = (int)tool_count; // for (int i = 0; i < ToolCount; i++) { // glBindTexture(GL_TEXTURE_2D, textureID); // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MainComp->Width, MainComp->Height, 0, GL_RGBA, ByteFlag2, MainCompBuffer); // } block_composition *MainComp = (block_composition *)Memory_Block_AllocateAddress(&Memory, F_Precomps); MainComp->Width = 1024; MainComp->Height = 512; MainComp->FPS = 24; MainComp->BytesPerPixel = 4; MainComp->Frame_Count = 48; MainComp->Frame_End = 48; MainComp->Occupied = 1; MainComp->Name_String_Index = String_AddToFile(&Memory, "Main comp"); File->Comp_Count = 1; /* block_composition *Comp2 = (block_composition *)Memory_Block_AllocateAddress(&Memory, F_Precomps); Comp2->Width = 500; Comp2->Height = 500; Comp2->FPS = 24; Comp2->BytesPerPixel = 4; Comp2->Frame_Count = 48; Comp2->Frame_End = 48; Comp2->Occupied = 1; Comp2->Name_String_Index = String_AddToFile(&Memory, "Another comp"); */ { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 0); Source->IsSelected = true; /* { Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->Vertical_Offset = 6; Layer->Col[0] = 1; Layer->Col[1] = 0; Layer->Col[2] = 0; Layer->Block_Composition_Index = 0; Layer->IsSelected = true; property_channel *Property = &Layer->x; Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); Property->Block_Bezier_Count = 1; block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property->Block_Bezier_Index[0]); Bezier->Occupied = 1; Bezier->Point[0].Pos[0] = V2(0, 0); Bezier->Point[1].Pos[0] = V2(20, 50); Bezier->Point[2].Pos[0] = V2(40, -50); Bezier->Point[0].Pos[1] = V2(-4, 0); Bezier->Point[1].Pos[1] = V2(-4, 0); Bezier->Point[2].Pos[1] = V2(-4, 0); Bezier->Point[0].Pos[2] = V2(4, 0); Bezier->Point[1].Pos[2] = V2(4, 0); Bezier->Point[2].Pos[2] = V2(4, 0); Bezier->Point[0].Type = interpolation_type_bezier; Bezier->Point[1].Type = interpolation_type_bezier; Bezier->Point[2].Type = interpolation_type_bezier; Bezier->Point[1].IsSelected = false; Bezier->Point[0].Occupied = true; Bezier->Point[1].Occupied = true; Bezier->Point[2].Occupied = true; property_channel *Property2 = &Layer->opacity; Property2->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); Property2->Block_Bezier_Count = 1; block_bezier *Bezier2 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property2->Block_Bezier_Index[0]); Bezier2->Occupied = 1; Bezier2->Point[0].Pos[0] = V2(0, 0); Bezier2->Point[1].Pos[0] = V2(20, 1); Bezier2->Point[0].Occupied = true; Bezier2->Point[1].Occupied = true; property_channel *Property3 = &Layer->y; Property3->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); Property3->Block_Bezier_Count = 1; block_bezier *Bezier3 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property3->Block_Bezier_Index[0]); Bezier3->Occupied = 1; Bezier3->Point[0].Pos[0] = V2(0, -20); Bezier3->Point[1].Pos[0] = V2(20, 300); Bezier3->Point[2].Pos[0] = V2(40, 100); Bezier3->Point[0].Pos[1] = V2(-4, 0); Bezier3->Point[1].Pos[1] = V2(-4, 0); Bezier3->Point[2].Pos[1] = V2(-4, 0); Bezier3->Point[0].Pos[2] = V2(4, 0); Bezier3->Point[1].Pos[2] = V2(4, 0); Bezier3->Point[2].Pos[2] = V2(4, 0); Bezier3->Point[0].Type = interpolation_type_bezier; Bezier3->Point[1].Type = interpolation_type_bezier; Bezier3->Point[2].Type = interpolation_type_bezier; Bezier3->Point[0].Occupied = true; Bezier3->Point[1].Occupied = true; Bezier3->Point[2].Occupied = true; } */ /* { Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->Vertical_Offset = 2; Layer->IsSelected = true; Layer->ColIndex = 2; Layer->Block_Composition_Index = 0; } { Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->Vertical_Offset = 5; Layer->ColIndex = 0; Layer->Block_Composition_Index = 0; } */ } { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/b.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 1); // Source->IsSelected = true; /* { Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->IsSelected = true; Layer->Vertical_Offset = 3; Layer->ColIndex = 1; Layer->Block_Composition_Index = 0; // Layer->IsSelected = true; property_channel *Property = &Layer->x; Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); Property->Block_Bezier_Count = 1; block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property->Block_Bezier_Index[0]); Bezier->Occupied = 1; Bezier->Point[0].Pos[0] = V2(30, 0); Bezier->Point[1].Pos[0] = V2(33, 250); Bezier->Point[2].Pos[0] = V2(35, -50); Bezier->Point[3].Pos[0] = V2(55, 0); Bezier->Point[0].Pos[1] = V2(-1, 0); Bezier->Point[1].Pos[1] = V2(-1, 0); Bezier->Point[2].Pos[1] = V2(-1, 0); Bezier->Point[3].Pos[1] = V2(-1, 0); Bezier->Point[0].Pos[2] = V2(1, 0); Bezier->Point[1].Pos[2] = V2(1, 0); Bezier->Point[2].Pos[2] = V2(1, 0); Bezier->Point[3].Pos[2] = V2(1, 0); Bezier->Point[0].Type = interpolation_type_bezier; Bezier->Point[1].Type = interpolation_type_bezier; Bezier->Point[2].Type = interpolation_type_bezier; Bezier->Point[3].Type = interpolation_type_bezier; Bezier->Point[0].Occupied = true; Bezier->Point[1].Occupied = true; Bezier->Point[2].Occupied = true; Bezier->Point[3].Occupied = true; property_channel *Property2 = &Layer->opacity; Property2->Block_Bezier_Index[0] = Memory_Block_AllocateNew(&Memory, F_Bezier); Property2->Block_Bezier_Count = 1; block_bezier *Bezier2 = (block_bezier *)Memory_Block_AddressAtIndex(&Memory, F_Bezier, Property2->Block_Bezier_Index[0]); Bezier2->Occupied = 1; Bezier2->Point[0].Pos[0] = V2(25, 1); Bezier2->Point[1].Pos[0] = V2(40, 0); Bezier2->Point[0].Occupied = true; Bezier2->Point[1].Occupied = true; } */ } { uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/c.jpg"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2); // Source->IsSelected = true; /* { Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->Vertical_Offset = 1; Layer->ColIndex = 3; Layer->Block_Composition_Index = 0; } */ // { // Layer_CreateFromSource(File, State, &Memory, SourceIndex, MainComp->Frame_End); // block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); // Layer->Vertical_Offset = 4; // Layer->Col[0] = 0; // Layer->Col[1] = 1; // Layer->Col[2] = 1; // Layer->Block_Composition_Index = 1; // } } /* { Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->IsPrecomp = true; Layer->Vertical_Offset = 9; Layer->Col[0] = 1; Layer->Col[1] = 1; Layer->Col[2] = 1; Layer->Block_Composition_Index = 0; } { Layer_CreateFromSource(File, State, &Memory, 1, MainComp->Frame_End); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, File->Layer_Count - 1); Layer->IsPrecomp = true; Layer->Vertical_Offset = 10; Layer->Col[0] = 1; Layer->Col[1] = 1; Layer->Col[2] = 1; Layer->Block_Composition_Index = 0; } */ // History_Undo(&Memory); // History_Redo(&Memory); SDL_Init(SDL_INIT_VIDEO); Semaphore = SDL_CreateSemaphore(0); #if THREADED int Index[7]; for (int i = 0; i < 7; i++) { Index[i] = i; Thread[i] = SDL_CreateThread(TestThread, "thread", (void *)&Index[i]); } #endif // Decide GL+GLSL versions SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); #if defined(IMGUI_IMPL_OPENGL_ES2) // GL ES 2.0 + GLSL 100 const char* glsl_version = "#version 100"; SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #elif defined(__APPLE__) // GL 3.2 Core + GLSL 150 const char* glsl_version = "#version 150"; SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); #else // GL 3.0 + GLSL 130 const char* glsl_version = "#version 130"; SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); #if DEBUG #if ARM uint32 ScreenSize[2] = {(uint32)(2560/1.2), (uint32)(1600/1.2)}; #else real32 ScreenSize[2] = {3840/1.2, 2160/1.2}; #endif #else real32 ScreenSize[2]; SDL_DisplayMode current; int windowtest = SDL_GetCurrentDisplayMode(0, ¤t); if (windowtest == 0) { ScreenSize[0] = current.w; ScreenSize[1] = current.h; } else { ScreenSize[0] = 1920; ScreenSize[1] = 1080; } #endif SDL_Window* window = SDL_CreateWindow("Event Tester", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ScreenSize[0], ScreenSize[1], window_flags); SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GL_MakeCurrent(window, gl_context); SDL_GL_SetSwapInterval(1); // Enable vsync if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { printf("Failed to initialize GLAD"); return -1; } GL_InitDefaultShader(); GL_InitDefaultVerts(); SDL_GL_MakeCurrent(window, gl_context); SDL_Event Event; IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable | ImGuiConfigFlags_NavEnableSetMousePos; (void)io; // NOTE(fox): Instead of constructing the position of the windows on // startup with Docking API calls (which is experimental and incomplete) // I'm loading the window positions from this convenient tool. ImGui by // default saves window position to an external .ini file, which can be // loaded from disk or memory. // io.IniFilename = NULL; // ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); ImGui::StyleColorsDark(); ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL3_Init(glsl_version); GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); Brush_CalcBitmapAlphaFromSize(&Memory, &State->Brush, 4); State_BindBrushTexture(&Memory, &State->Brush, 4); while (State->IsRunning) { // State->Interact_Active = interact_type_layer_move; // State->Interact_Offset[1] = -3.0f; Main_InputTest(File, State, &Memory, &UI, window, textureID); if (State->IsPlaying) { block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(&Memory, F_Precomps, File->PrincipalCompIndex); State->Frame_Current = ((State->Frame_Current + 1) >= MainComp->Frame_Count) ? 0 : State->Frame_Current + 1; State->UpdateFrame = true; } if (State->UpdateFrame) { Main_Renderer(File, State, &Memory, window, textureID, io); } Assert(Debug.ScratchState == 0); Main_RenderUI(io, clear_color, window); // TODO(fox): Fix things that rely on this. if (State->Initializing) State->Initializing--; } for (int i = 0; i < 7; i++) { SDL_DetachThread(Thread[i]); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); SDL_Quit(); return 0; }