summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp596
1 files changed, 596 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..ff9dc22
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,596 @@
+#include <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#if WINDOWS
+#else
+#include <sys/mman.h>
+#endif
+
+#if ARM
+#include <arm_neon.h>
+#else
+#include <smmintrin.h>
+#endif
+
+#include "imgui/imgui.h"
+#include "imgui/backends/imgui_impl_sdl.h"
+#include "imgui/backends/imgui_impl_opengl3.h"
+#include <SDL2/SDL.h>
+#if defined(IMGUI_IMPL_OPENGL_ES2)
+#include <SDL_opengles2.h>
+#else
+#include <SDL_opengl.h>
+#endif
+
+#define STB_IMAGE_IMPLEMENTATION
+#define STBI_FAILURE_USERMSG
+#include "lib/stb_image.h"
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavformat/avio.h>
+#include <libavutil/avutil.h>
+#include <libswscale/swscale.h>
+}
+
+#if 0
+#include <iacaMarks.h>
+#else
+#define IACA_START
+#define IACA_END
+#endif
+
+#define internal static
+#define local_persist static
+#define global_variable static
+
+#define SwitchBool(Bool) if((Bool)) {(Bool) = 0;} else {(Bool) = 1;}
+#define AmountOf(Array) sizeof((Array)) / sizeof((Array)[1])
+
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+
+typedef int64_t int64;
+typedef int32 bool32;
+
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+
+typedef float real32;
+typedef double real64;
+
+#define NORMALIZED_COL_MIN { .col = V4(0.0f, 0.0f, 0.0f, 0.0f) }
+#define NORMALIZED_COL_MAX { .col = V4(1.0f, 1.0f, 1.0f, 1.0f) }
+#define NORMALIZED_REAL_MIN { 0.0f }
+#define NORMALIZED_REAL_MAX { 1.0f }
+
+
+// All of these MIN/MAX values are arbitrarily chosen; they can probably be
+// increased if the user requires it.
+
+#define PROPERTY_REAL_MAX 1000000
+#define PROPERTY_REAL_MIN -1000000
+
+#define MAX_LAYERS 2048
+#define MAX_EFFECTS 32
+#define MAX_SOURCES 1024
+#define MAX_PROPERTIES_PER_EFFECT 16
+#define MAX_KEYFRAME_BLOCKS 64
+#define MAX_KEYFRAMES_PER_BLOCK 32
+#define STRING_SIZE 256
+
+#define MAX_SELECTED_PROPERTIES 16
+
+#include "my_math.h"
+#include "main.h"
+#include "debug.h"
+
+global_variable uint32 volatile CompletedJobs;
+global_variable uint32 volatile NextEntryToDo;
+global_variable uint32 volatile EntryCount;
+global_variable bool32 IsRendering = false;
+global_variable bool32 AVXEnabled = true;
+
+render_entry Entries[256];
+
+SDL_Thread *thread[8];
+SDL_sem *Semaphore;
+
+#include "memory.cpp"
+#include "effects.cpp"
+#include "keyframes.cpp"
+#include "layer.cpp"
+#include "threading.cpp"
+#include "prenderer.cpp"
+#include "video.cpp"
+#include "createcalls.cpp"
+#include "my_imgui_widgets.cpp"
+
+// #include "sharebuffer.h"
+
+internal void
+MainFunction(main_sdl *Main, memory *Memory,
+ project_state *State, project_data *File,
+ cache_pool *Cache, pixel_buffer *CompBuffer)
+{
+ SSE_ClearBuffer(CompBuffer);
+ for (int i = 0; i < File->NumberOfLayers; i++) {
+ project_layer *Layer = File->Layer[i];
+ if (Layer->RenderInfo) {
+ // Keyframe updating
+ if (State->UpdateKeyframes) {
+ for (int p = 0; p < Layer->NumberOfEffects; p++) {
+ for (int o = 0; o < Layer->Effect[p]->NumberOfProperties; o++) {
+ CalculateKeyframesLinearly(File->CurrentFrame, &Layer->Effect[p]->Property[o]);
+ }
+ }
+ for (int r = 0; r < AmountOf(Layer->Property); r++) {
+ CalculateKeyframesLinearly(File->CurrentFrame, &Layer->Property[r]);
+ }
+ State->UpdateKeyframes = false;
+ }
+
+ // Video updating
+ if (Layer->SourceType == source_video) { // && Layer->VideoCurrentFrame != File->CurrentFrame - Layer->VideoFrameOffset) {
+ video_source *Source = (video_source *)Layer->RenderInfo;
+ LoadVideoFrame(Source, Memory, File->CurrentFrame); // TODO(fox): Make above check work!
+ UpdateEffects(Layer, Memory);
+ Source->Raster.ToUpdate = true;
+ }
+
+ // Effect updating
+ if (Layer->SourceType == source_image) {
+ image_source *Source = (image_source *)Layer->RenderInfo;
+ if (Source->Raster.ToUpdate) {
+ UpdateEffects(Layer, Memory);
+ Source->Raster.ToUpdate = false;
+ }
+ }
+ }
+ }
+ QueueCurrentFrame(File, CompBuffer, State);
+}
+
+#if 0
+internal void
+MainFunction(main_sdl *Main, project_debug *D, memory *Memory, sdl_input *Input, sdl_input *OldInput,
+ project_state *State, brush_tool *Brush, project_data *File,
+ cache_pool *Cache, pixel_buffer *CompBuffer)
+{
+ ClearBuffer(CompBuffer);
+
+ if (Cache->Frame[File->CurrentFrame].Cached) {
+ FetchCache(&Cache->Frame[File->CurrentFrame], CompBuffer);
+ } else {
+ for (int i = 0; i < File->NumberOfLayers; i++) {
+ if (File->Layer[i]->Raster.OriginalBuffer) {
+ for (int p = 0; p < File->Layer[i]->NumberOfEffects; p++) {
+ for (int o = 0; o < File->Layer[i]->Effect[p].NumberOfProperties; o++) {
+ CalculateKeyframesLinearly(File->CurrentFrame, &File->Layer[i]->Effect[p].Property[o]);
+ }
+ }
+ for (int r = 0; r < AmountOf(File->Layer[i]->Property); r++) {
+ CalculateKeyframesLinearly(File->CurrentFrame, &File->Layer[i]->Property[r]);
+ }
+ if (File->Layer[i]->Raster.ToUpdate) {
+ UpdateEffects(File->Layer[i], Memory);
+ File->Layer[i]->Raster.ToUpdate = true;
+ }
+ }
+ }
+
+ if (State->DebugDisableCache) {
+ RenderCurrentFrame(File, CompBuffer, State);
+ } else {
+ if (Cache->Interact == Clear) {
+ Cache->Intermediate[0].Cached = 0;
+ Cache->Intermediate[1].Cached = 0;
+ Cache->Intermediate[2].Cached = 0;
+ Cache->Interact = Inactive;
+ }
+ if (Cache->Interact == Active) {
+ if (!Cache->Intermediate[0].Address) {
+ Cache->Intermediate[0].Address = (uint64 *)Memory->Address + Memory->CurrentPosition;
+ Memory->CurrentPosition += File->Width * File->Height * 4;
+ Cache->Intermediate[1].Address = (uint64 *)Memory->Address + Memory->CurrentPosition;
+ Memory->CurrentPosition += File->Width * File->Height * 4;
+ Cache->Intermediate[2].Address = (uint64 *)Memory->Address + Memory->CurrentPosition;
+ Memory->CurrentPosition += File->Width * File->Height * 4;
+ }
+ pixel_buffer TempBuffer = *CompBuffer;
+ if (!Cache->Intermediate[0].Cached) {
+ TempBuffer.OriginalBuffer = Cache->Intermediate[0].Address;
+ ClearBuffer(&TempBuffer);
+ for (int i = 0; i < Cache->InteractIndex; i++) {
+ // RenderLayer(File->LayerPTR[i], &TempBuffer, State);
+ // RenderCurrentFrame(File->LayerPTR[Cache->InteractIndex], &TempBuffer, State);
+ }
+ Cache->Intermediate[0].Cached = 1;
+ }
+ TempBuffer.OriginalBuffer = Cache->Intermediate[1].Address;
+ ClearBuffer(&TempBuffer);
+ // RenderLayer(File->LayerPTR[Cache->InteractIndex], &TempBuffer, State);
+ // RenderCurrentFrame(File->LayerPTR[Cache->InteractIndex], &TempBuffer, State);
+ if (!Cache->Intermediate[2].Cached) {
+ TempBuffer.OriginalBuffer = Cache->Intermediate[2].Address;
+ ClearBuffer(&TempBuffer);
+ for (int i = Cache->InteractIndex + 1; i < File->NumberOfLayers; i++) {
+ // RenderLayer(File->LayerPTR[i], &TempBuffer, State);
+ // RenderCurrentFrame(File->LayerPTR[Cache->InteractIndex], &TempBuffer, State);
+ }
+ Cache->Intermediate[2].Cached = 1;
+ }
+ InteractToComp(CompBuffer, Cache);
+ } else {
+ for (int i = 0; i < File->NumberOfLayers; i++) {
+ }
+ }
+ if (!Cache->Interact) {
+ if (!Cache->Frame[File->CurrentFrame].Address) {
+ Cache->Frame[File->CurrentFrame].Address = (uint64 *)Memory->Address + Memory->CurrentPosition;
+ Memory->CurrentPosition += File->Width * File->Height * 4;
+ }
+ CacheFrame(&Cache->Frame[File->CurrentFrame], CompBuffer);
+ Cache->Frame[File->CurrentFrame].Cached = true;
+ } else {
+ Cache->Frame[File->CurrentFrame].Cached = false;
+ }
+ }
+ }
+}
+#endif
+
+
+internal void
+DebugPrintMemoryUsage(memory Memory)
+{
+ for (int i = 0; i < 8; i++) {
+ memory_table Table = Memory.Slot[i];
+ printf("%s: %li bytes, %li kb\n", Table.Name, Table.CurrentPosition, Table.CurrentPosition / 1024);
+ }
+}
+
+
+int main(int argc, char *argv[]) {
+
+ global_memory GlobalMemory = {};
+
+ GlobalMemory.Size = ((uint64)2 * 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
+
+ memory Memory = {};
+
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_UIState, "UI state");
+ // TODO(fox): Make clean-up functions when these get deleted!
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_SourceData, "Image/video headers");
+
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_ProjectSettings, "Project settings");
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers");
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Effects, "Effects");
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Keyframes, "Keyframe blocks");
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Strings, "Strings");
+ InitMemoryTable(&GlobalMemory, &Memory, 1024 * 1024 * 1024, B_Scratch, "Scratch buffer");
+
+ if (!SDL_HasAVX2()) {
+ AVXEnabled = false;
+ printf("CPU does not have AVX2!");
+ return -1;
+ }
+
+
+ project_state State = {};
+
+ project_data File = {};
+ File.Width = 1280;
+ File.Height = 720;
+ File.NumberOfFrames = 65;
+ File.FPS = 30;
+ File.CurrentFrame = 1;
+ File.StartFrame = 0;
+ File.EndFrame = 65;
+
+ // char String[1024];
+ // uint16 Size = 1024;
+ // getcwd(String, Size);
+ // printf("dir: %s", String);
+
+ pixel_buffer CompBuffer = CreateBuffer(File.Width, File.Height, &Memory);
+
+ cache_pool Cache = {};
+ Cache.Interact = Inactive;
+
+ ui UI = {};
+
+ File.NumberOfSources = 2;
+ File.Source[0] = (char *)AllocateMemory(&Memory, STRING_SIZE, F_Strings);
+ File.Source[1] = (char *)AllocateMemory(&Memory, STRING_SIZE, F_Strings);
+ sprintf(File.Source[0], "../asset/b.jpg");
+ sprintf(File.Source[1], "../asset/24.mp4");
+ CreateLayerFromSource(&File, &State, &Memory, File.Source[0]);
+ CreateLayerFromSource(&File, &State, &Memory, File.Source[1]);
+
+#if 1
+ // shm_unlink("/testl");
+ // int fd = shm_open("/testl", O_CREAT | O_EXCL | O_RDWR,
+ // S_IRUSR | S_IWUSR);
+ // if (fd == -1)
+ // errExit("shm_open");
+
+ // if (ftruncate(fd, SHAREDMEMORY_SIZE) == -1)
+ // Assert(0);
+
+ // void *asda = mmap(NULL, SHAREDMEMORY_SIZE,
+ // PROT_READ | PROT_WRITE,
+ // MAP_SHARED, fd, 0);
+ // SharedMemoryInfo *shmp = (SharedMemoryInfo *)asda;
+
+ // if (shmp == MAP_FAILED)
+ // Assert(0);
+
+ // if (sem_init(&shmp->sem1, 1, 0) == -1)
+ // Assert(0);
+ // if (sem_init(&shmp->sem2, 1, 0) == -1)
+ // Assert(0);
+
+ // CreateLayer(&File, &Memory);
+ // CreateRenderInfo(File.Layer[1], &Memory, File, video, "./asset/24.mp4");
+ // File.Layer[1]->Name = "yuyu";
+ // File.Layer[1]->StartFrame = 0;
+ // File.Layer[1]->EndFrame = 65;
+#else
+ CreateDebugLayer(&File, &Memory, 12, 8);
+ File.Layer[0]->Name = "debug";
+ File.Layer[0]->StartFrame = 0;
+ File.Layer[0]->EndFrame = 65;
+#endif
+
+ // CreateLayer(&File, &Memory);
+
+ // CreateRenderInfo(File.Layer[0], &Memory, File, image, "./asset/r.jpg");
+
+ // File.Layer[0]->Name = "Robot";
+ // File.Layer[0]->x.CurrentValue.f = 200;
+ // File.Layer[0]->y.CurrentValue.f = 250;
+ // File.Layer[0]->scale.CurrentValue.f = 1.1;
+ // File.Layer[0]->opacity.CurrentValue.f = 1.0;
+ // File.Layer[0]->StartFrame = 0;
+ // File.Layer[0]->EndFrame = 65;
+
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 2, 100);
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 60, 500);
+
+
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 3, 300);
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 8, 800);
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 5, 500);
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 6, 600);
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 7, 700);
+
+ // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[2].IsSelected = true;
+ // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[3].IsSelected = true;
+ // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[4].IsSelected = true;
+ // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[6].IsSelected = true;
+
+ // DeleteSelectedKeyframes(&File, &Memory);
+
+ // for (int16 i = 0; i < 10; i++) {
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, i*6 + 3, i*100);
+ // }
+
+ // int16 kef = 2;
+ // for (int16 i = 0; i < kef; i++) {
+ // int16 p = kef - i;
+ // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, p*4, p*100);
+ // }
+ // &File.Layer[1]->x.KeyframeBlock[0]->Keyframe[2];
+ // KeyframeDelete(&File.Layer[1]->x, &Memory, 2);
+
+ // AddEffect(File.Layer[0], &Memory, 0);
+ // AddEffect(File.Layer[0], &Memory, 0);
+
+ for (int i = 0; i < 3; i++)
+ // CreateLayer(&File, &Memory);
+
+ // DebugPrintMemoryUsage(Memory);
+
+ SDL_Init(SDL_INIT_VIDEO);
+
+ Semaphore = SDL_CreateSemaphore(0);
+
+ render_queue RenderInfo = {};
+ RenderInfo.File = &File;
+ RenderInfo.State = &State;
+ RenderInfo.CompBuffer = &CompBuffer;
+
+ thread_info ThreadInfo[7];
+
+ for (int i = 0; i < 7; i++) {
+ char str[256];
+ ThreadInfo[i].Index = i;
+ ThreadInfo[i].RenderInfo = &RenderInfo;
+ thread[i] = SDL_CreateThread(TestThread, str, &ThreadInfo[i]);
+ }
+
+ sdl_input Input;
+ sdl_input OldInput;
+
+ // Decide GL+GLSL versions
+#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);
+ // uint32 ScreenSize[2] = {2560/1.2, 1600/1.2};
+ real32 ScreenSize[2] = {3840/1.2, 2160/1.2};
+ SDL_Window* window = SDL_CreateWindow("Event Tester", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 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
+
+ SDL_Event Event;
+
+ IMGUI_CHECKVERSION();
+ ImGui::CreateContext();
+ ImGuiIO& io = ImGui::GetIO();
+ ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
+ (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, 1146);
+
+ 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_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
+#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+#endif
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, CompBuffer.Width, CompBuffer.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, CompBuffer.OriginalBuffer);
+
+ ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
+
+ while (State.IsRunning)
+ {
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ ImGui_ImplSDL2_ProcessEvent(&event);
+ if (event.type == SDL_DROPFILE) {
+ printf("%s", event.drop.file);
+ // AddSource(File, Memory, event.drop.file);
+ }
+ 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;
+ }
+
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplSDL2_NewFrame();
+
+ ImGui::NewFrame();
+
+ if (!io.WantCaptureKeyboard)
+ ImGui_ProcessInputs(&File, &State, &CompBuffer, &Memory, &UI, io);
+
+ ImGui::DockSpaceOverViewport();
+
+ ImGui_Viewport(File, &State, &UI, CompBuffer, io, textureID);
+
+ ImGui_File(&File, &State, &Memory, &UI, io);
+
+ ImGui_PropertiesPanel(&File, &State, &UI, &Memory);
+
+ ImGui_Timeline(&File, &State, &Memory, &UI, io);
+#if DEBUG
+ if (Debug.ToggleWindow)
+ ImGui::ShowDemoWindow();
+#endif
+
+ if (UI.TemporaryUpdateOverride) {
+ UI.TemporaryUpdateOverride = 0;
+ State.UpdateFrame = 1;
+ }
+
+ if (UI.Initializing)
+ UI.Initializing--;
+
+ // if (File.CurrentFrame != shmp->shared_framenumber) {
+ // File.CurrentFrame = shmp->shared_framenumber;
+ // }
+
+ if (State.UpdateFrame && !IsRendering) {
+ MainFunction(0, &Memory, &State, &File, &Cache, &CompBuffer);
+ State.UpdateFrame = 0;
+ }
+
+ if (IsRendering) {
+ while (CompletedJobs != 16) {
+ CheckQueue(RenderInfo, 8);
+ }
+ if (CompletedJobs == 16) {
+#if PACKEDRGB
+ Unpack4x4Chunk(&CompBuffer);
+ // SSE_CopyToBuffer(CompBuffer);
+#else
+ PackBitmapRGB(&CompBuffer);
+#endif
+ EndRenderState(&State);
+ glBindTexture(GL_TEXTURE_2D, textureID);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CompBuffer.Width, CompBuffer.Height, GL_RGBA, GL_UNSIGNED_BYTE,
+ CompBuffer.EffectBuffer);
+
+ // shmp->shared_framenumber = File.CurrentFrame;
+ // if (sem_post(&shmp->sem2) == -1)
+ // Assert(0);
+
+ }
+ }
+
+ 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);
+ }
+ for (int i = 0; i < 7; i++) {
+ SDL_DetachThread(thread[i]);
+ }
+ // shm_unlink("/testl");
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui_ImplSDL2_Shutdown();
+ ImGui::DestroyContext();
+ SDL_Quit();
+ return 0;
+}