summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bezier.cpp47
-rw-r--r--bitmap_calls.cpp45
-rwxr-xr-xbuild.sh20
-rw-r--r--createcalls.cpp211
-rw-r--r--debug.h32
-rw-r--r--effects.cpp231
-rw-r--r--effects.h76
-rw-r--r--effects_software.cpp174
-rw-r--r--ffmpeg_backend.cpp55
-rw-r--r--functions.h20
-rw-r--r--gl_calls.cpp111
-rw-r--r--gl_calls.h24
-rw-r--r--main.cpp116
-rw-r--r--main.h91
-rw-r--r--my_imgui_widgets.cpp9
-rw-r--r--prenderer.cpp1
-rw-r--r--structs.h5
17 files changed, 647 insertions, 621 deletions
diff --git a/bezier.cpp b/bezier.cpp
index 63cc328..f41bd06 100644
--- a/bezier.cpp
+++ b/bezier.cpp
@@ -209,3 +209,50 @@ Mask_AddPointToCurve(mask *Mask, uint16 Index, real32 ratio)
PointToAdd->TangentRight = -(NewPos - NewHandleRight);
Mask->NumberOfPoints++;
}
+
+static void
+Mask_RasterizePoints(mask *Mask)
+{
+ Mask->NumberOfVerts = 0;
+ for (int i = 0; i < Mask->NumberOfPoints; i++) {
+ mask_point Point0 = Mask->Point[i];
+ mask_point Point1 = Mask->Point[i+1];
+ if (i+1 == Mask->NumberOfPoints)
+ Point1 = Mask->Point[0];
+
+ if (Point0.HandleBezier && Point1.HandleBezier) {
+ Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos + Point0.TangentRight, Point1.Pos + Point1.TangentLeft, Point1.Pos,
+ Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
+ } else if (Point0.HandleBezier) {
+ Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos + Point0.TangentRight, Point1.Pos, Point1.Pos,
+ Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
+ } else if (Point1.HandleBezier) {
+ Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos, Point1.Pos + Point1.TangentLeft, Point1.Pos,
+ Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
+ } else {
+ real32 *Data = (real32 *)Mask->TriangulatedPointCache + Mask->NumberOfVerts*3;
+ *(Data++) = Point0.Pos.x;
+ *(Data++) = Point0.Pos.y;
+ *(Data++) = 0;
+ // NOTE(fox): CubicCalcPoints sometimes misses generating the start
+ // point of the next path in the above two cases, so I'm making
+ // straight lines always add both points as a hotfix. This leads
+ // to cases of duplicate verts, but it doesn't seem like it harms
+ // the rendering in any way.
+ *(Data++) = Point1.Pos.x;
+ *(Data++) = Point1.Pos.y;
+ *(Data++) = 0;
+ Mask->NumberOfVerts += 2;
+ }
+ }
+}
+
+void Mask_TriangulateAndRasterize(memory *Memory, project_layer *Layer, mask *Mask)
+{
+ if (!Mask->TriangulatedPointCache) {
+ Mask->TriangulatedPointCache = AllocateMemory(Memory, 50*1024, P_VectorPoints);
+ }
+ Mask_RasterizePoints(Mask);
+
+ GL_RasterizeShape(Layer, Mask);
+}
diff --git a/bitmap_calls.cpp b/bitmap_calls.cpp
index a67cd0b..f37f493 100644
--- a/bitmap_calls.cpp
+++ b/bitmap_calls.cpp
@@ -238,6 +238,51 @@ Bitmap_CopyToPointer(void *Input, void *Output, uint16 BytesPerPixel, uint64 Tot
}
}
+static void
+Bitmap_StencilAlpha(void *Input, void *Output, uint16 BytesPerPixel, uint64 TotalBytes)
+{
+ uint8 *Row = (uint8 *)Input;
+ uint8 *Row2 = (uint8 *)Output;
+
+ uint64 bytes = 0;
+ uint16 ByteOffset = Bitmap_CalcByteOffset(BytesPerPixel);
+ uint64 RemainderBytes = TotalBytes % ByteOffset;
+
+ __m256i AlphaBytes = _mm256_set1_epi32(0x00FFFFFF);
+ __m256 Zeroi = _mm256_set1_epi32(0);
+
+ while (bytes <= TotalBytes - RemainderBytes) {
+ uint8 *Pixel = (uint8 *)Row + bytes;
+ uint8 *Pixel2 = (uint8 *)Row2 + bytes;
+#if ARM
+ if (InstructionMode == instruction_mode_neon) {
+ uint32x2x4_t OutputPixel = vld4_u32((uint32 *)Pixel);
+ vst4_u32((uint32 *)Pixel2, OutputPixel);
+#else
+ if (InstructionMode == instruction_mode_avx) {
+ __m256i InputPixel = _mm256_loadu_si256((__m256i *)Pixel);
+ __m256i OutputPixel = _mm256_loadu_si256((__m256i *)Pixel2);
+ if (_mm256_movemask_epi8(OutputPixel)) {
+ OutputPixel = _mm256_blendv_epi8(OutputPixel, InputPixel, AlphaBytes);
+ _mm256_storeu_si256((__m256i *)Pixel2, OutputPixel);
+ }
+ } else if (InstructionMode == instruction_mode_sse) {
+ __m128i OutputPixel = _mm_loadu_si128((__m128i *)Pixel);
+ _mm_storeu_si128((__m128i *)Pixel2, OutputPixel);
+#endif
+ } else {
+ *(uint32 *)Pixel2 = *(uint32 *)Pixel;
+ }
+ bytes += ByteOffset;
+ }
+ while (bytes <= TotalBytes) {
+ uint8 *Pixel = (uint8 *)Row + bytes;
+ uint8 *Pixel2 = (uint8 *)Row2 + bytes;
+ *(uint32 *)Pixel2 = *(uint32 *)Pixel;
+ bytes += BytesPerPixel;
+ }
+}
+
// This would be an easy SIMD if only AVX had a scatter call...
// NOTE(fox): Only works with unpacked bitmaps for now.
static void
diff --git a/build.sh b/build.sh
index 74f1435..a41428b 100755
--- a/build.sh
+++ b/build.sh
@@ -1,11 +1,12 @@
#!/bin/bash
-DEBUG=1 # Compile with debug symbols.
-IMGUI=0 # Compile ImGui libs. Our custom ImGui functions still compile on zero.
+OPTIMIZATION="-O2" # Enable optimization.
+DEBUG=1 # Compile with debug UI.
+IMGUI=1 # Compile ImGui libs. Our custom ImGui functions still compile on zero.
THREADED=1 # Compile with threading. Useful to disable when stepping through the renderer.
WINDOWS=0 # Compile for Windows with Mingw.
ARM=0 # Compile on ARM machines.
-PACKEDRGB=0 # Use 4x4 chunks for the software rasterizer.
+PACKEDRGB=0 # Use 4x4 chunks for the software rasterizer. Isn't actually faster at the moment.
PERF=0 # Print cycle stats.
FFMPEG_LIBS="
@@ -42,9 +43,6 @@ WARNING_FLAGS="
if [[ "$DEBUG" == 1 ]]; then
WARNING_FLAGS="$WARNING_FLAGS -DDEBUG=1"
-DEBUG="-g"
-else
-DEBUG="-O2"
fi
if [[ "$THREADED" == 1 ]]; then
WARNING_FLAGS="$WARNING_FLAGS -DTHREADED=1"
@@ -71,11 +69,11 @@ fi
if [[ "$OSTYPE" =~ ^darwin ]]; then
IMGUI_FLAGS="
- -std=c++11 -Iimgui -Iimgui/backends $DEBUG -Wall -Wformat `sdl2-config --cflags` -I/usr/local/include -I/opt/local/include -c
+ -std=c++11 -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -I/usr/local/include -I/opt/local/include -c
"
else
IMGUI_FLAGS="
- -Iimgui -Iimgui/backends $DEBUG -Wall -Wformat `sdl2-config --cflags` -c
+ -Iimgui -Iimgui/backends $OPTIMIZATION -Wall -Wformat `sdl2-config --cflags` -c
"
fi
@@ -104,15 +102,15 @@ if [[ "$IMGUI" == 1 ]]; then
fi
if [[ "$WINDOWS" == 1 ]]; then
-clang++ $DEBUG $WARNING_FLAGS -target x86_64-pc-windows-gnu -march=x86-64-v3 -I .. -Iimgui -Iimgui/backends \
+clang++ $OPTIMIZATION $WARNING_FLAGS -target x86_64-pc-windows-gnu -march=x86-64-v3 -I .. -Iimgui -Iimgui/backends \
main.cpp imgui/imgui*.cpp imgui/backends/imgui_impl_sdl.cpp imgui/backends/imgui_impl_opengl3.cpp \
-I/usr/x86_64-w64-mingw32/include/SDL2 -I/usr/x86_64-w64-mingw32/include/GL \
-lmingw32 -lopengl32 -lSDL2main -lSDL2 -llibavcodec -llibswscale -llibavformat -llibavutil \
-o bin/real2d
else
clang lib/glad.c $GLAD_FLAGS -I/usr/local/include -I/opt/local/include -c \
- $WARNING_FLAGS $DEBUG $ADDITIONAL_FLAGS -o bin/glad.o
-clang main.cpp $WARNING_FLAGS $DEBUG $ADDITIONAL_FLAGS -o bin/real2d bin/*.o \
+ $WARNING_FLAGS $OPTIMIZATION $ADDITIONAL_FLAGS -o bin/glad.o
+clang main.cpp $WARNING_FLAGS $OPTIMIZATION $ADDITIONAL_FLAGS -o bin/real2d bin/*.o \
$GLAD_FLAGS \
-std=c++11 -lstdc++ -Iimgui -Iimgui/backends \
$SDL_ARGS \
diff --git a/createcalls.cpp b/createcalls.cpp
index 1d4e2e5..f8c166e 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -83,6 +83,8 @@ project_layer * Layer_Init(project_data *File, memory *Memory)
File->Layer[Index] = (project_layer *)AllocateMemory(Memory, sizeof(project_layer), F_Layers);
project_layer *Layer = File->Layer[Index];
+ *Layer = {};
+ Layer->BitmapInfo.CurrentFrame = -1;
History_Entry_SetPointer(Memory, &Layer->BitmapInfo.AVInfo);
@@ -110,10 +112,13 @@ Cache_CheckBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory,
return 0;
memory_table *Table = &Memory->Slot[B_LoadedBitmaps];
int32 FrameToSeek = TimelineFrame - BitmapInfo->FrameOffset;
- // Stills have a frame index of zero.
- if (FrameToSeek < 0 || Source->SourceType == source_type_image) {
+ if (FrameToSeek < 0) {
FrameToSeek = 0;
- };
+ }
+ // Stills have a frame index of one.
+ if (Source->SourceType == source_type_image) {
+ FrameToSeek = 0;
+ }
for (int i = 0; i < Table->NumberOfPointers; i++) {
cached_bitmap *Bitmap = &Memory->Bitmap[i];
if (Bitmap->Frame == FrameToSeek && Bitmap->SourceOwner == Source) {
@@ -138,145 +143,6 @@ STB_LoadStill(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory)
}
static void
-Mask_RasterizePoints(mask *Mask)
-{
- Mask->NumberOfVerts = 0;
- for (int i = 0; i < Mask->NumberOfPoints; i++) {
- mask_point Point0 = Mask->Point[i];
- mask_point Point1 = Mask->Point[i+1];
- if (i+1 == Mask->NumberOfPoints)
- Point1 = Mask->Point[0];
-
- if (Point0.HandleBezier && Point1.HandleBezier) {
- Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos + Point0.TangentRight, Point1.Pos + Point1.TangentLeft, Point1.Pos,
- Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
- } else if (Point0.HandleBezier) {
- Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos + Point0.TangentRight, Point1.Pos, Point1.Pos,
- Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
- } else if (Point1.HandleBezier) {
- Bezier_CubicCalcPoints(Point0.Pos, Point0.Pos, Point1.Pos + Point1.TangentLeft, Point1.Pos,
- Mask->TriangulatedPointCache, &Mask->NumberOfVerts);
- } else {
- real32 *Data = (real32 *)Mask->TriangulatedPointCache + Mask->NumberOfVerts*3;
- *(Data++) = Point0.Pos.x;
- *(Data++) = Point0.Pos.y;
- *(Data++) = 0;
- // NOTE(fox): CubicCalcPoints sometimes misses generating the start
- // point of the next path in the above two cases, so I'm making
- // straight lines always add both points as a hotfix. This leads
- // to cases of duplicate verts, but it doesn't seem like it harms
- // the rendering in any way.
- *(Data++) = Point1.Pos.x;
- *(Data++) = Point1.Pos.y;
- *(Data++) = 0;
- Mask->NumberOfVerts += 2;
- }
- }
-}
-
-static void
-Mask_TriangulateAndRasterize(memory *Memory, project_layer *Layer, mask *Mask)
-{
- if (!Mask->TriangulatedPointCache) {
- Mask->TriangulatedPointCache = AllocateMemory(Memory, 50*1024, P_VectorPoints);
- }
- Mask_RasterizePoints(Mask);
-
- gl_vertex_shader VertData;
- gl_effect_layer Test = Layer->BitmapInfo.TestM;
- gl_effect_layer Test2 = Layer->BitmapInfo.Test;
-
- uint32 Width = Layer->Source->Info.Width;
- uint32 Height = Layer->Source->Info.Height;
-
- uint8 *Data = (uint8 *)Layer->BitmapInfo.BitmapBuffer;
-
- glBindFramebuffer(GL_FRAMEBUFFER, Test.FramebufferObject);
-
- glEnable(GL_STENCIL_TEST);
- // glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
- glStencilFunc(GL_ALWAYS, 0, 0xFF); // always write
- glStencilMask(0xff); // allow writing; ANDs any writes to the stencil buffer with this
-
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- glUseProgram(DefaultShaderProgram);
-
- int VertexMode = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
- int FragmentMode = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
- glUniform1i(VertexMode, 1);
- glUniform1i(FragmentMode, 0);
-
- // secondary VBO
- glGenVertexArrays(1, &VertData.VertexArrayObject);
- glBindVertexArray(VertData.VertexArrayObject);
- glBindBuffer(GL_ARRAY_BUFFER, VertData.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, Mask->NumberOfVerts*3*sizeof(real32), Mask->TriangulatedPointCache, GL_STREAM_DRAW);
-
- // position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
-
- int Scale = glGetUniformLocation(DefaultShaderProgram, "CompDimensions");
- glUniform3f(Scale, Width, Height, 0);
-
-
- glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
- glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
-
- glDisable(GL_CULL_FACE);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, Mask->NumberOfVerts);
-
- // glEnable(GL_CULL_FACE);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
- glBindVertexArray(0);
-
- // glBindRenderbuffer(GL_RENDERBUFFER, Test.Color_Renderbuffer);
-
- VertexMode = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
- FragmentMode = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
- glUniform1i(VertexMode, 0);
- glUniform1i(FragmentMode, 1);
-
-
- // // Switch to main buffer
- glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(DefaultVertices), DefaultVertices, GL_STATIC_DRAW);
- // position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- // texture coordinate (note the last parameter's offset)
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
-
- glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
- glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
- glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
-
- glDisable(GL_STENCIL_TEST);
- glStencilMask(0xFF);
- glStencilFunc(GL_ALWAYS, 0, 0xFF);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, Test.FramebufferObject);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Test2.FramebufferObject);
- glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER, Test2.FramebufferObject);
-
- glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
-}
-
-static void
Layer_InitSource(project_layer *Layer, source *Source, memory *Memory)
{
uint16 Width = Source->Info.Width;
@@ -320,7 +186,7 @@ Layer_UpdateBitmap(project_data *File, project_layer *Layer, memory *Memory, int
cached_bitmap *Bitmap = Cache_CheckBitmap(Source, BitmapInfo, Memory, CurrentFrame);
if (!Bitmap) {
if (Source->SourceType == source_type_image) {
- Bitmap = AV_LoadVideoFrame(Source, BitmapInfo, Memory, 1);
+ Bitmap = STB_LoadStill(Source, BitmapInfo, Memory);
} else {
Bitmap = AV_LoadVideoFrame(Source, BitmapInfo, Memory, CurrentFrame);
}
@@ -338,8 +204,8 @@ Layer_UpdateBitmap(project_data *File, project_layer *Layer, memory *Memory, int
Bitmap_CopyToPointer(Memory->Scratch, DestBuffer, BytesPerPixel, PackedSize);
} else {
Bitmap_CopyToPointer(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize);
- TestGL_InitTexture(&BitmapInfo->Test, DestBuffer, Width, Height);
- TestGL_MaskTexture(&BitmapInfo->TestM, DestBuffer, Width, Height);
+ // GL_InitTexture(&BitmapInfo->Test, DestBuffer, Width, Height);
+ // GL_MaskTexture(&BitmapInfo->TestM, DestBuffer, Width, Height);
if (Layer->NumberOfMasks) {
for (int i = 0; i < Layer->NumberOfMasks; i++) {
@@ -359,8 +225,8 @@ Layer_UpdateBitmap(project_data *File, project_layer *Layer, memory *Memory, int
}
#else
Bitmap_CopyToPointer(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize);
- TestGL_UpdateTexture(&BitmapInfo->Test, DestBuffer, Width, Height, 0);
- TestGL_UpdateTexture(&BitmapInfo->TestM, DestBuffer, Width, Height, 1);
+ GL_UpdateTexture(&BitmapInfo->Test, DestBuffer, Width, Height, 0);
+ GL_UpdateTexture(&BitmapInfo->TestM, DestBuffer, Width, Height, 1);
if (Layer->NumberOfMasks) {
for (int i = 0; i < Layer->NumberOfMasks; i++) {
@@ -368,6 +234,13 @@ Layer_UpdateBitmap(project_data *File, project_layer *Layer, memory *Memory, int
if (Mask->IsClosed)
Mask_TriangulateAndRasterize(Memory, Layer, Mask);
}
+ Bitmap_StencilAlpha(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize);
+ }
+
+ for (int i = 0; i < Layer->NumberOfEffects; i++)
+ {
+ if (Layer->Effect[i]->IsActive)
+ Layer->Effect[i]->func(Source, BitmapInfo, Memory, Layer->Effect[i]->Property);
}
#endif
}
@@ -406,11 +279,18 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory)
{
void *SourceString = String_GenerateFromChar(Memory, "../asset/24.mp4");
Source_Generate(File, Memory, SourceString);
+ SourceString = String_GenerateFromChar(Memory, "../asset/a.jpg");
+ Source_Generate(File, Memory, SourceString);
+ SourceString = String_GenerateFromChar(Memory, "../asset/b.jpg");
+ Source_Generate(File, Memory, SourceString);
+ SourceString = String_GenerateFromChar(Memory, "../asset/c.jpg");
+ Source_Generate(File, Memory, SourceString);
+ SourceString = String_GenerateFromChar(Memory, "../asset/p.mp4");
+ Source_Generate(File, Memory, SourceString);
- source *Source = &File->Source[0];
- Layer_CreateFromSource(File, State, Memory, Source);
- SelectLayer(File->Layer[0], State, 0);
- property_channel *Property = &File->Layer[0]->x;
+ // Layer_CreateFromSource(File, State, Memory, &File->Source[0]);
+ // SelectLayer(File->Layer[0], State, 0);
+ // property_channel *Property = &File->Layer[0]->x;
// for (int i = 0; i < 16; i++)
// Keyframe_Insert(Property, Memory, i*2, i*2*100);
// Keyframe_Insert(Property, Memory, 1, 100);
@@ -420,10 +300,11 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory)
// History_Undo(Memory);
// History_Redo(Memory);
- Property->IsToggled = true;
+ // Property->IsToggled = true;
// AddEffect(File->Layer[0], Memory, 3);
+ /*
mask *Mask = &File->Layer[0]->Mask[0];
File->Layer[0]->NumberOfMasks = 1;
Mask->Point[0].Pos = V2(200, 200);
@@ -452,6 +333,7 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory)
Mask->NumberOfPoints = 5;
Mask->IsClosed = true;
+ */
// if (!Source_Generate(File, Memory, "../asset/test.png"))
// PostMsg(State, "File open fail...");
@@ -498,26 +380,28 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory)
}
static void
-CreateDemoScene(project_data *File, memory *Memory)
+CreateDemoScene(project_data *File, project_state *State, memory *Memory)
{
-#if 0
- project_layer *Layer1 = CreateSolidLayer(File, Memory, 720, 1280, V4(0.0, 0.0, 0.0, 1.0));
- Layer1->x.CurrentValue.f = 1280/2;
- Layer1->y.CurrentValue.f = 720/2;
+ Layer_CreateFromSource(File, State, Memory, &File->Source[1]);
+ project_layer *Layer1 = File->Layer[0];
+ Layer1->x.CurrentValue.f = 1920/2;
+ Layer1->y.CurrentValue.f = 1080/2;
Layer1->StartFrame = 0;
Layer1->EndFrame = File->EndFrame;
- project_layer *Layer2 = CreateSolidLayer(File, Memory, 499, 503, V4(0.0, 1.0, 0.4, 1.0));
- Layer2->x.CurrentValue.f = 1280/2;
- Layer2->y.CurrentValue.f = 720/2;
+ Layer_CreateFromSource(File, State, Memory, &File->Source[2]);
+ project_layer *Layer2 = File->Layer[1];
+ Layer2->x.CurrentValue.f = 1920/2;
+ Layer2->y.CurrentValue.f = 1080/2;
Layer2->StartFrame = 0;
Layer2->EndFrame = File->EndFrame;
Keyframe_Insert(&Layer2->rotation, Memory, 2, 0);
Keyframe_Insert(&Layer2->rotation, Memory, 50, 360);
Layer2->rotation.IsToggled = true;
Layer2->scale.IsToggled = true;
- project_layer *Layer3 = CreateSolidLayer(File, Memory, 157, 163, V4(1.0, 0.3, 0.2, 1.0));
- Layer3->x.CurrentValue.f = 1280/4;
- Layer3->y.CurrentValue.f = 720/4;
+ Layer_CreateFromSource(File, State, Memory, &File->Source[3]);
+ project_layer *Layer3 = File->Layer[2];
+ Layer3->x.CurrentValue.f = 1920/4;
+ Layer3->y.CurrentValue.f = 1080/4;
Layer3->opacity.CurrentValue.f = 0.5f;
Layer3->StartFrame = 0;
Layer3->EndFrame = File->EndFrame;
@@ -526,7 +410,6 @@ CreateDemoScene(project_data *File, memory *Memory)
Keyframe_Insert(&Layer3->x, Memory, 60, Layer3->x.CurrentValue.f+(1280/3));
Layer3->x.IsToggled = true;
Layer3->y.IsToggled = true;
-#endif
}
#if 0
diff --git a/debug.h b/debug.h
index 5863298..0e6c9b6 100644
--- a/debug.h
+++ b/debug.h
@@ -15,10 +15,6 @@ union debugval {
int32 i;
};
-enum PerfID {
- perf_renderframe
-};
-
// things that get cleared every frame with the UI
struct debug_temp
{
@@ -41,15 +37,6 @@ struct project_debug
static project_debug Debug;
-
-#if DEBUG
-#define Debug_CycleCountStart(ID) Debug.CycleCount[ID] = __rdtsc();
-#define Debug_CycleCountEnd(ID) Debug.EndCycleCount[ID] += __rdtsc() - Debug.CycleCount[ID]; Debug.ExecutionAmount[ID]++;
-#else
-#define Debug_CycleCountStart(ID)
-#define Debug_CycleCountEnd(ID)
-#endif
-
static void
DebugWatchVar(char *Name, void *Address, valtype Type) {
uint32 i = Debug.Temp.WatchedProperties;
@@ -64,6 +51,17 @@ DebugWatchVar(char *Name, void *Address, valtype Type) {
Debug.Temp.WatchedProperties++;
}
+static 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);
+ }
+}
+
+
+
#else
#define Assert(Expression)
@@ -82,12 +80,13 @@ struct project_debug
{
};
-#define DEBUG_CycleCountStart(ID)
-#define DEBUG_CycleCountEnd(ID)
-
static void
DebugWatchVar(char *Name, void *Address, valtype Type) {
}
+
+static void
+DebugPrintMemoryUsage(memory Memory) {
+}
#endif
#ifdef PERF
@@ -99,7 +98,6 @@ struct perf_stats
uint64 PixelCountChecked;
};
-static perf_stats Perf;
static uint64 Test;
#endif
diff --git a/effects.cpp b/effects.cpp
index 61b7729..9de8008 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -1,190 +1,16 @@
-static void
-DrawColor(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
-{
-#if 0
- v4 FloatColor = Property[0].CurrentValue.col;
- blend_mode BlendMode = Property[1].CurrentValue.blendmode;
-
- __m256 ZeroReal = _mm256_set1_ps(0);
- __m256 ZeroPointFive = _mm256_set1_ps(0.5);
- __m256 One = _mm256_set1_ps(1);
- __m256 Two = _mm256_set1_ps(2);
-
- __m256 Fraction255 = _mm256_set1_ps(1/255.0f);
- __m256 Real255 = _mm256_set1_ps(255);
-
- __m256i FF = _mm256_set1_epi32(0xFF);
-
- __m256 Alpha = _mm256_set1_ps(FloatColor.a);
- __m256 AlphaInv = _mm256_set1_ps(1.0f - FloatColor.a);
-
- __m256 R_Col = _mm256_set1_ps(FloatColor.E[0]);
- __m256 R_Colx2 = _mm256_mul_ps(R_Col, Two);
- __m256 R_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[0]);
-
- __m256 G_Col = _mm256_set1_ps(FloatColor.E[1]);
- __m256 G_Colx2 = _mm256_mul_ps(G_Col, Two);
- __m256 G_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[1]);
-
- __m256 B_Col = _mm256_set1_ps(FloatColor.E[2]);
- __m256 B_Colx2 = _mm256_mul_ps(B_Col, Two);
- __m256 B_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[2]);
-
- for (int16 Y = 0; Y < Source->Info.Height; Y += 2)
- {
- for (int16 X = 0; X < Source->Info.Width; X += 4)
- {
- uint32 XLookup = (X >> 2)*16 + (X % 4);
- uint32 YLookup = (Y >> 2)*(Source->Info.Width*4) + (Y % 4)*4;
- uint32 PixelToSeek = XLookup + YLookup;
- uint8 *Pixel = (uint8 *)BitmapInfo->BitmapBuffer + PixelToSeek*Source->Info.BytesPerPixel;
- __m256i DestPixel = _mm256_loadu_si256((const __m256i *)Pixel);
-
- // normalized values
- __m256 R_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256( DestPixel, FF)), Fraction255);
- __m256 G_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(DestPixel, 8), FF)), Fraction255);
- __m256 B_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(DestPixel, 16), FF)), Fraction255);
- __m256i A_Out = _mm256_and_si256(_mm256_srli_epi32(DestPixel, 24), FF);
-
- __m256 R_Blend = _mm256_setzero_ps();
- __m256 G_Blend = _mm256_setzero_ps();
- __m256 B_Blend = _mm256_setzero_ps();
- switch (BlendMode)
- {
- case blend_normal:
- {
- } break;
- case blend_multiply:
- {
- R_Blend = _mm256_mul_ps(R_Dest, R_Col);
- G_Blend = _mm256_mul_ps(G_Dest, G_Col);
- B_Blend = _mm256_mul_ps(B_Dest, B_Col);
- } break;
- case blend_colorburn:
- {
- R_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, R_Dest), R_Col));
- G_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, G_Dest), G_Col));
- B_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, B_Dest), B_Col));
- } break;
- case blend_linearburn:
- {
- R_Blend = _mm256_sub_ps(_mm256_add_ps(R_Dest, R_Col), One);
- G_Blend = _mm256_sub_ps(_mm256_add_ps(G_Dest, G_Col), One);
- B_Blend = _mm256_sub_ps(_mm256_add_ps(B_Dest, B_Col), One);
- } break;
- case blend_add:
- {
- R_Blend = _mm256_add_ps(R_Dest, R_Col);
- G_Blend = _mm256_add_ps(G_Dest, G_Col);
- B_Blend = _mm256_add_ps(B_Dest, B_Col);
- } break;
- case blend_screen:
- {
- R_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv));
- G_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv));
- B_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv));
- } break;
- case blend_overlay:
- {
- __m256 R_Mask = _mm256_cmp_ps(R_Dest, ZeroPointFive, 1);
- __m256 G_Mask = _mm256_cmp_ps(G_Dest, ZeroPointFive, 1);
- __m256 B_Mask = _mm256_cmp_ps(B_Dest, ZeroPointFive, 1);
- __m256 R_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(R_Dest, R_Col));
- __m256 G_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(G_Dest, G_Col));
- __m256 B_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(B_Dest, B_Col));
- __m256 R_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv)));
- __m256 G_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv)));
- __m256 B_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv)));
- R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
- G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
- B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
- } break;
- case blend_softlight:
- {
- // using Pegtop's equation
- R_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, R_Colx2), _mm256_mul_ps(R_Dest, R_Dest)), _mm256_mul_ps(R_Colx2, R_Dest));
- G_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, G_Colx2), _mm256_mul_ps(G_Dest, G_Dest)), _mm256_mul_ps(G_Colx2, G_Dest));
- B_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, B_Colx2), _mm256_mul_ps(B_Dest, B_Dest)), _mm256_mul_ps(B_Colx2, B_Dest));
- } break;
- case blend_hardlight:
- {
- __m256 R_Mask = _mm256_cmp_ps(R_Dest, ZeroPointFive, 13);
- __m256 G_Mask = _mm256_cmp_ps(G_Dest, ZeroPointFive, 13);
- __m256 B_Mask = _mm256_cmp_ps(B_Dest, ZeroPointFive, 13);
- __m256 R_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(R_Dest, R_Col));
- __m256 G_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(G_Dest, G_Col));
- __m256 B_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(B_Dest, B_Col));
- __m256 R_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv)));
- __m256 G_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv)));
- __m256 B_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv)));
- R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
- G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
- B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
- } break;
- case blend_subtract:
- {
- R_Blend = _mm256_sub_ps(R_Dest, R_Col);
- G_Blend = _mm256_sub_ps(G_Dest, G_Col);
- B_Blend = _mm256_sub_ps(B_Dest, B_Col);
- } break;
- case blend_divide:
- {
- R_Blend = _mm256_div_ps(R_Dest, R_Col);
- G_Blend = _mm256_div_ps(G_Dest, G_Col);
- B_Blend = _mm256_div_ps(B_Dest, B_Col);
- } break;
- case blend_difference:
- {
- __m256 R_Lower = _mm256_sub_ps(R_Col, R_Dest);
- __m256 G_Lower = _mm256_sub_ps(G_Col, G_Dest);
- __m256 B_Lower = _mm256_sub_ps(B_Col, B_Dest);
- __m256 R_Upper = _mm256_sub_ps(R_Dest, R_Col);
- __m256 G_Upper = _mm256_sub_ps(G_Dest, G_Col);
- __m256 B_Upper = _mm256_sub_ps(B_Dest, B_Col);
- __m256 R_Mask = _mm256_cmp_ps(R_Lower, ZeroReal, 14);
- __m256 G_Mask = _mm256_cmp_ps(G_Lower, ZeroReal, 14);
- __m256 B_Mask = _mm256_cmp_ps(B_Lower, ZeroReal, 14);
- R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
- G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
- B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
- } break;
- }
-
- R_Blend = _mm256_add_ps(_mm256_mul_ps(R_Dest, AlphaInv),
- _mm256_mul_ps(R_Blend, Alpha));
- G_Blend = _mm256_add_ps(_mm256_mul_ps(G_Dest, AlphaInv),
- _mm256_mul_ps(G_Blend, Alpha));
- B_Blend = _mm256_add_ps(_mm256_mul_ps(B_Dest, AlphaInv),
- _mm256_mul_ps(B_Blend, Alpha));
-
- R_Blend = _mm256_max_ps(_mm256_min_ps(One, R_Blend), ZeroReal);
- G_Blend = _mm256_max_ps(_mm256_min_ps(One, G_Blend), ZeroReal);
- B_Blend = _mm256_max_ps(_mm256_min_ps(One, B_Blend), ZeroReal);
-
- __m256i R_Out = _mm256_cvttps_epi32(_mm256_mul_ps(R_Blend, Real255));
- __m256i G_Out = _mm256_cvttps_epi32(_mm256_mul_ps(G_Blend, Real255));
- __m256i B_Out = _mm256_cvttps_epi32(_mm256_mul_ps(B_Blend, Real255));
-
- __m256i OutputPixel = _mm256_or_si256(
- _mm256_or_si256(R_Out, _mm256_slli_epi32(G_Out, 8)),
- _mm256_or_si256(_mm256_slli_epi32(B_Out, 16), _mm256_slli_epi32(A_Out, 24)));
-
- _mm256_storeu_si256((__m256i *)Pixel, OutputPixel);
- }
- }
-#endif
-}
+#include "effects.h"
+#include "effects_software.cpp"
static void
-DrawGradient(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
+Effect_DrawColor(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
- v4 StartColor = Property[0].CurrentValue.col;
- v4 EndColor = Property[1].CurrentValue.col;
+ Effect_DrawColor_Software(Source, BitmapInfo, Memory, Property);
}
static void
-Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
+Effect_Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
+#if 0
real32 All_Start = Property[0].CurrentValue.f;
real32 All_Mid = Property[1].CurrentValue.f;
real32 All_End = Property[2].CurrentValue.f;
@@ -225,11 +51,13 @@ Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_c
uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer;
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#endif
}
static void
-GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
+Effect_GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
+#if 0
real32 Radius = Property[0].CurrentValue.f;
gl_effect_layer *Test = &BitmapInfo->Test;
@@ -251,7 +79,7 @@ GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, prop
uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer;
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
- TestGL_UpdateTexture(&BitmapInfo->Test, Data, Width, Height, 0);
+ GL_UpdateTexture(&BitmapInfo->Test, Data, Width, Height, 0);
// glBindRenderbuffer(GL_RENDERBUFFER, Test->RBO);
/*
glUseProgram(TGL.ShaderProgram);
@@ -263,46 +91,9 @@ GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, prop
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#endif
}
-#if WINDOWS
-static effect_header EffectList[3];
-#else
-static effect_header EffectList[] {
- {
- "Solid Color",
- &DrawColor, 2, standard, {
- {"Color", {.col = V4(0.0f, 0.0f, 0.0f, 0.0f)}, type_color, NORMALIZED_COL_MIN, NORMALIZED_COL_MAX},
- {"Blend mode", {.blendmode = blend_normal}, type_blendmode},
- }
- },
- {
- "Linear Gradient",
- &DrawGradient, 3, standard, {
- {"Start Color", {.col = V4(0.0f, 1.0f, 0.0f, 0.0f)}, type_color, NORMALIZED_COL_MIN, NORMALIZED_COL_MAX},
- {"End Color", {.col = V4(1.0f, 0.0f, 0.0f, 1.0f)}, type_color, NORMALIZED_COL_MIN, NORMALIZED_COL_MAX},
- {"Opacity", {1.0f}, type_real, NORMALIZED_REAL_MIN, NORMALIZED_REAL_MAX}
- }
- },
- {
- "Levels",
- &Levels, 6, levels, {
- {"Start point", {0.0f}, type_real},
- {"Mid point", {1.0f}, type_real},
- {"End point", {1.0f}, type_real},
- {"Start Col", {.col = V4(0.0f)}, type_color},
- {"Mid Col", {.col = V4(1.0f)}, type_color},
- {"End Col", {.col = V4(1.0f)}, type_color},
- }
- },
- {
- "Gaussian Blur",
- &GaussianBlur, 1, standard, {
- {"Radius", {0.0f}, type_real, 0.0f, 500.0f},
- }
- }
-};
-#endif
#if 0
{
"Solid Color",
diff --git a/effects.h b/effects.h
new file mode 100644
index 0000000..58787c2
--- /dev/null
+++ b/effects.h
@@ -0,0 +1,76 @@
+enum effect_display_type
+{
+ standard,
+ levels
+};
+
+struct effect_supported_renderers
+{
+ bool32 renderer_effect_gpu;
+#if ARM
+ bool32 renderer_effect_neon;
+#else
+ bool32 renderer_effect_avx;
+ bool32 renderer_effect_sse;
+#endif
+ bool32 renderer_effect_scalar;
+};
+
+struct effect_header
+{
+ char *Name;
+ void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
+ uint16 NumberOfProperties;
+ effect_display_type DisplayType;
+ // effect_supported_renderers SupportedRenderers;
+ property_header PropertyHeader[MAX_PROPERTIES_PER_EFFECT];
+};
+
+struct effect {
+ char *Name;
+ void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
+ uint16 NumberOfProperties;
+ effect_display_type DisplayType;
+
+ struct gl_effect {
+ uint32 ShaderProgram;
+ };
+
+ gl_effect GL_Effect;
+ property_channel Property[MAX_PROPERTIES_PER_EFFECT];
+ bool32 UIIsCollapsed = 0;
+ bool32 IsActive = 1;
+};
+
+
+#if WINDOWS
+static effect_header EffectList[3];
+#else
+static effect_header EffectList[] {
+ {
+ "Solid Color",
+ &Effect_DrawColor, 2, standard, {
+ {"Color", {.col = V4(0.0f, 0.0f, 0.0f, 1.0f)}, type_color, NORMALIZED_COL_MIN, NORMALIZED_COL_MAX},
+ {"Blend mode", {.blendmode = blend_normal}, type_blendmode},
+ }
+ },
+ {
+ "Levels",
+ &Effect_Levels, 6, levels, {
+ {"Start point", {0.0f}, type_real},
+ {"Mid point", {1.0f}, type_real},
+ {"End point", {1.0f}, type_real},
+ {"Start Col", {.col = V4(0.0f)}, type_color},
+ {"Mid Col", {.col = V4(1.0f)}, type_color},
+ {"End Col", {.col = V4(1.0f)}, type_color},
+ }
+ },
+ {
+ "Gaussian Blur",
+ &Effect_GaussianBlur, 1, standard, {
+ {"Radius", {0.0f}, type_real, 0.0f, 500.0f},
+ }
+ }
+};
+#endif
+
diff --git a/effects_software.cpp b/effects_software.cpp
new file mode 100644
index 0000000..5b9e4d9
--- /dev/null
+++ b/effects_software.cpp
@@ -0,0 +1,174 @@
+static void
+Effect_DrawColor_Software(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
+{
+ v4 FloatColor = Property[0].CurrentValue.col;
+ blend_mode BlendMode = Property[1].CurrentValue.blendmode;
+
+ __m256 ZeroReal = _mm256_set1_ps(0);
+ __m256 ZeroPointFive = _mm256_set1_ps(0.5);
+ __m256 One = _mm256_set1_ps(1);
+ __m256 Two = _mm256_set1_ps(2);
+
+ __m256 Fraction255 = _mm256_set1_ps(1/255.0f);
+ __m256 Real255 = _mm256_set1_ps(255);
+
+ __m256i FF = _mm256_set1_epi32(0xFF);
+
+ __m256 Alpha = _mm256_set1_ps(FloatColor.a);
+ __m256 AlphaInv = _mm256_set1_ps(1.0f - FloatColor.a);
+
+ __m256 R_Col = _mm256_set1_ps(FloatColor.E[0]);
+ __m256 R_Colx2 = _mm256_mul_ps(R_Col, Two);
+ __m256 R_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[0]);
+
+ __m256 G_Col = _mm256_set1_ps(FloatColor.E[1]);
+ __m256 G_Colx2 = _mm256_mul_ps(G_Col, Two);
+ __m256 G_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[1]);
+
+ __m256 B_Col = _mm256_set1_ps(FloatColor.E[2]);
+ __m256 B_Colx2 = _mm256_mul_ps(B_Col, Two);
+ __m256 B_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[2]);
+
+ for (int16 Y = 0; Y < Source->Info.Height; Y += 2)
+ {
+ for (int16 X = 0; X < Source->Info.Width; X += 4)
+ {
+ uint32 XLookup = (X >> 2)*16 + (X % 4);
+ uint32 YLookup = (Y >> 2)*(Source->Info.Width*4) + (Y % 4)*4;
+ uint32 PixelToSeek = XLookup + YLookup;
+ uint8 *Pixel = (uint8 *)BitmapInfo->BitmapBuffer + PixelToSeek*Source->Info.BytesPerPixel;
+ __m256i DestPixel = _mm256_loadu_si256((const __m256i *)Pixel);
+
+ // normalized values
+ __m256 R_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256( DestPixel, FF)), Fraction255);
+ __m256 G_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(DestPixel, 8), FF)), Fraction255);
+ __m256 B_Dest = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(DestPixel, 16), FF)), Fraction255);
+ __m256i A_Out = _mm256_and_si256(_mm256_srli_epi32(DestPixel, 24), FF);
+
+ __m256 R_Blend = R_Col;
+ __m256 G_Blend = G_Col;
+ __m256 B_Blend = B_Col;
+ switch (BlendMode)
+ {
+ case blend_normal:
+ {
+ } break;
+ case blend_multiply:
+ {
+ R_Blend = _mm256_mul_ps(R_Dest, R_Col);
+ G_Blend = _mm256_mul_ps(G_Dest, G_Col);
+ B_Blend = _mm256_mul_ps(B_Dest, B_Col);
+ } break;
+ case blend_colorburn:
+ {
+ R_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, R_Dest), R_Col));
+ G_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, G_Dest), G_Col));
+ B_Blend = _mm256_sub_ps(One, _mm256_div_ps(_mm256_sub_ps(One, B_Dest), B_Col));
+ } break;
+ case blend_linearburn:
+ {
+ R_Blend = _mm256_sub_ps(_mm256_add_ps(R_Dest, R_Col), One);
+ G_Blend = _mm256_sub_ps(_mm256_add_ps(G_Dest, G_Col), One);
+ B_Blend = _mm256_sub_ps(_mm256_add_ps(B_Dest, B_Col), One);
+ } break;
+ case blend_add:
+ {
+ R_Blend = _mm256_add_ps(R_Dest, R_Col);
+ G_Blend = _mm256_add_ps(G_Dest, G_Col);
+ B_Blend = _mm256_add_ps(B_Dest, B_Col);
+ } break;
+ case blend_screen:
+ {
+ R_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv));
+ G_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv));
+ B_Blend = _mm256_sub_ps(One, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv));
+ } break;
+ case blend_overlay:
+ {
+ __m256 R_Mask = _mm256_cmp_ps(R_Dest, ZeroPointFive, 1);
+ __m256 G_Mask = _mm256_cmp_ps(G_Dest, ZeroPointFive, 1);
+ __m256 B_Mask = _mm256_cmp_ps(B_Dest, ZeroPointFive, 1);
+ __m256 R_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(R_Dest, R_Col));
+ __m256 G_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(G_Dest, G_Col));
+ __m256 B_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(B_Dest, B_Col));
+ __m256 R_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv)));
+ __m256 G_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv)));
+ __m256 B_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv)));
+ R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
+ G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
+ B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
+ } break;
+ case blend_softlight:
+ {
+ // using Pegtop's equation
+ R_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, R_Colx2), _mm256_mul_ps(R_Dest, R_Dest)), _mm256_mul_ps(R_Colx2, R_Dest));
+ G_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, G_Colx2), _mm256_mul_ps(G_Dest, G_Dest)), _mm256_mul_ps(G_Colx2, G_Dest));
+ B_Blend = _mm256_add_ps(_mm256_mul_ps(_mm256_sub_ps(One, B_Colx2), _mm256_mul_ps(B_Dest, B_Dest)), _mm256_mul_ps(B_Colx2, B_Dest));
+ } break;
+ case blend_hardlight:
+ {
+ __m256 R_Mask = _mm256_cmp_ps(R_Dest, ZeroPointFive, 13);
+ __m256 G_Mask = _mm256_cmp_ps(G_Dest, ZeroPointFive, 13);
+ __m256 B_Mask = _mm256_cmp_ps(B_Dest, ZeroPointFive, 13);
+ __m256 R_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(R_Dest, R_Col));
+ __m256 G_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(G_Dest, G_Col));
+ __m256 B_Lower = _mm256_mul_ps(Two, _mm256_mul_ps(B_Dest, B_Col));
+ __m256 R_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, R_Dest), R_ColInv)));
+ __m256 G_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, G_Dest), G_ColInv)));
+ __m256 B_Upper = _mm256_sub_ps(One, _mm256_mul_ps(Two, _mm256_mul_ps(_mm256_sub_ps(One, B_Dest), B_ColInv)));
+ R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
+ G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
+ B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
+ } break;
+ case blend_subtract:
+ {
+ R_Blend = _mm256_sub_ps(R_Dest, R_Col);
+ G_Blend = _mm256_sub_ps(G_Dest, G_Col);
+ B_Blend = _mm256_sub_ps(B_Dest, B_Col);
+ } break;
+ case blend_divide:
+ {
+ R_Blend = _mm256_div_ps(R_Dest, R_Col);
+ G_Blend = _mm256_div_ps(G_Dest, G_Col);
+ B_Blend = _mm256_div_ps(B_Dest, B_Col);
+ } break;
+ case blend_difference:
+ {
+ __m256 R_Lower = _mm256_sub_ps(R_Col, R_Dest);
+ __m256 G_Lower = _mm256_sub_ps(G_Col, G_Dest);
+ __m256 B_Lower = _mm256_sub_ps(B_Col, B_Dest);
+ __m256 R_Upper = _mm256_sub_ps(R_Dest, R_Col);
+ __m256 G_Upper = _mm256_sub_ps(G_Dest, G_Col);
+ __m256 B_Upper = _mm256_sub_ps(B_Dest, B_Col);
+ __m256 R_Mask = _mm256_cmp_ps(R_Lower, ZeroReal, 14);
+ __m256 G_Mask = _mm256_cmp_ps(G_Lower, ZeroReal, 14);
+ __m256 B_Mask = _mm256_cmp_ps(B_Lower, ZeroReal, 14);
+ R_Blend = _mm256_blendv_ps(R_Upper, R_Lower, R_Mask);
+ G_Blend = _mm256_blendv_ps(G_Upper, G_Lower, G_Mask);
+ B_Blend = _mm256_blendv_ps(B_Upper, B_Lower, B_Mask);
+ } break;
+ }
+
+ R_Blend = _mm256_add_ps(_mm256_mul_ps(R_Dest, AlphaInv),
+ _mm256_mul_ps(R_Blend, Alpha));
+ G_Blend = _mm256_add_ps(_mm256_mul_ps(G_Dest, AlphaInv),
+ _mm256_mul_ps(G_Blend, Alpha));
+ B_Blend = _mm256_add_ps(_mm256_mul_ps(B_Dest, AlphaInv),
+ _mm256_mul_ps(B_Blend, Alpha));
+
+ R_Blend = _mm256_max_ps(_mm256_min_ps(One, R_Blend), ZeroReal);
+ G_Blend = _mm256_max_ps(_mm256_min_ps(One, G_Blend), ZeroReal);
+ B_Blend = _mm256_max_ps(_mm256_min_ps(One, B_Blend), ZeroReal);
+
+ __m256i R_Out = _mm256_cvttps_epi32(_mm256_mul_ps(R_Blend, Real255));
+ __m256i G_Out = _mm256_cvttps_epi32(_mm256_mul_ps(G_Blend, Real255));
+ __m256i B_Out = _mm256_cvttps_epi32(_mm256_mul_ps(B_Blend, Real255));
+
+ __m256i OutputPixel = _mm256_or_si256(
+ _mm256_or_si256(R_Out, _mm256_slli_epi32(G_Out, 8)),
+ _mm256_or_si256(_mm256_slli_epi32(B_Out, 16), _mm256_slli_epi32(A_Out, 24)));
+
+ _mm256_storeu_si256((__m256i *)Pixel, OutputPixel);
+ }
+ }
+}
diff --git a/ffmpeg_backend.cpp b/ffmpeg_backend.cpp
index 03d3214..6e16e76 100644
--- a/ffmpeg_backend.cpp
+++ b/ffmpeg_backend.cpp
@@ -45,6 +45,9 @@ bool32 AV_TryFrame(av_info *AV, int32 *err)
while (*err >= 0) {
*err = avcodec_receive_frame(AV->VideoCodecContext, AV->VideoFrame);
if (*err == AVERROR_EOF) {
+ av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD);
+ *err = 0;
+ break;
} else if (*err == AVERROR(EAGAIN)) {
*err = 0;
break;
@@ -209,6 +212,11 @@ void AV_GetPTSAverage(source *Source, av_info *AV, int32 *err)
// TODO(fox): This PTS average isn't exact and causes an occasional
// frame skip. See libav remarks in forum for more details.
+ if (AV->VideoStream->duration == 1) {
+ Source->Info.AvgPTSPerFrame = 1;
+ return;
+ }
+
// TODO(fox): Handle footage under five seconds.
int16 TestAmount = 5;
@@ -234,6 +242,53 @@ void AV_GetPTSAverage(source *Source, av_info *AV, int32 *err)
av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD);
}
+cached_bitmap * AV_LoadStill(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory)
+{
+ av_info *AV = (av_info *)BitmapInfo->AVInfo;
+ int32 *CurrentlyRenderedFrame = &BitmapInfo->CurrentFrame;
+
+ int32 err = 0;
+
+ *CurrentlyRenderedFrame = 0;
+
+ av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_FRAME);
+
+ while (err >= 0) {
+ if (AV_TryFrame(AV, &err))
+ {
+ uint16 Width = Source->Info.Width;
+ uint16 Height = Source->Info.Height;
+ uint16 BytesPerPixel = Source->Info.BytesPerPixel;
+ int32 Pitch = Width*BytesPerPixel;
+
+ cached_bitmap *Bitmap = Memory_RollingBitmap(Memory, Source, 0);
+ void *Buffer = Bitmap->Data;
+
+ int out_linesize[4] = { Pitch, Pitch, Pitch, Pitch };
+ uint8 *dst_data[4] = { (uint8 *)Buffer, (uint8 *)Buffer + Width*Height*BytesPerPixel,
+ (uint8 *)Buffer + Width*Height*BytesPerPixel*2, (uint8 *)Buffer + Width*Height*BytesPerPixel*3 };
+
+ // NOTE(fox): This function will be replaced in the future.
+ AV->RGBContext = sws_getContext(AV->VideoFrame->width, AV->VideoFrame->height, (AVPixelFormat)AV->VideoFrame->format,
+ AV->VideoFrame->width, AV->VideoFrame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR,
+ NULL, NULL, NULL);
+
+ if(!AV->RGBContext) {
+ printf("Libav error: SwsContext creation failed.");
+ }
+
+ sws_scale(AV->RGBContext, AV->VideoFrame->data, AV->VideoFrame->linesize, 0, AV->VideoFrame->height,
+ dst_data, out_linesize);
+
+ av_frame_unref(AV->VideoFrame);
+
+ Assert(BitmapInfo->BitmapBuffer);
+ return Bitmap;
+ }
+ av_frame_unref(AV->VideoFrame);
+ }
+ return 0;
+}
cached_bitmap * AV_LoadVideoFrame(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame)
{
diff --git a/functions.h b/functions.h
index 3d4184d..9b63832 100644
--- a/functions.h
+++ b/functions.h
@@ -6,11 +6,11 @@ static project_layer * Layer_Init(project_data *File, memory *Memory); // Initia
static void Bitmap_CalcPackedDimensions(uint16 Width, uint16 Height, uint16 *WidthP, uint16 *HeightP); // Returns the dimensions a packed bitmap should be in memory.
+static void Bitmap_ConvertPacking(void *Buffer, void *DestBuffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, uint16 Which);
+static void Bitmap_CalcHistogram(void *Data, void *Input, uint16 BytesPerPixel, uint64 TotalBytes);
static uint16 Bitmap_CalcByteOffset(uint16 BytesPerPixel); // Returns the amount of bytes a loop goes through depending on the InstructionMode.
static uint64 Bitmap_CalcTotalBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel); // Returns the total amount of bytes a bitmap takes up.
static uint64 Bitmap_CalcUnpackedBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel);
-static void Bitmap_ConvertPacking(void *Buffer, void *DestBuffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, uint16 Which);
-static void Bitmap_CalcHistogram(void *Data, void *Input, uint16 BytesPerPixel, uint64 TotalBytes);
static bool32 Source_Generate(project_data *File, memory *Memory, void *Path); // Fills out source info if the source is a supported file.
@@ -22,16 +22,18 @@ static cached_bitmap * AV_LoadVideoFrame(source *Source, memory *Memory, int32 T
static cached_bitmap * Cache_CheckBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame);
-static void TestGL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, bool32 Multisample);
-static gl_effect TestGL_MaskInitVerts(mask Mask);
-static void TestGL_InitVerts();
-static gl_vertex_shader TestGL_MaskUploadVerts(project_layer *Layer, mask *Mask);
+// OpenGL
+
+static void GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, bool32 Multisample);
+static void GL_RasterizeShape(project_layer *Layer, mask *Mask);
static v2 Line_RatioToPoint(v2 a, v2 b, float ratio);
static v2 ImGui_ScreenPointToCompUV(ImVec2 ViewportMin, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 MousePos);
void Bezier_CubicCalcPoints(v2 p1, v2 p2, v2 p3, v2 p4, void *Data, uint32 *Increment);
+static void Mask_TriangulateAndRasterize(memory *Memory, project_layer *Layer, mask *Mask);
+
static void History_Undo(memory *Memory);
static void History_Redo(memory *Memory);
@@ -57,3 +59,9 @@ static void Fallback_RenderLayer(transform_info TransformInfo, comp_buffer *Buff
static void PushRect(rectangle RenderRegion);
static bool32 CheckQueue(render_queue RenderInfo, uint16 Index);
+// Effects
+
+static void Effect_DrawColor(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]);
+static void Effect_Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]);
+static void Effect_GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]);
+
diff --git a/gl_calls.cpp b/gl_calls.cpp
index fcb7fd9..8a7b905 100644
--- a/gl_calls.cpp
+++ b/gl_calls.cpp
@@ -1,3 +1,6 @@
+#include "gl_calls.h"
+
+
const char *DefaultVertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n"
@@ -75,7 +78,7 @@ const char *fragmentShaderSource = "#version 330 core\n"
#endif
-static void TestGL_InitDefaultShader() {
+static void GL_InitDefaultShader() {
DefaultVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(DefaultVertexShader, 1, &DefaultVertexShaderSource, NULL);
@@ -121,7 +124,7 @@ static void TestGL_InitDefaultShader() {
glDeleteShader(DefaultFragmentShader);
}
-static void TestGL_InitDefaultVerts() {
+static void GL_InitDefaultVerts() {
unsigned int GLIndices[] = {
0, 1, 3,
@@ -139,7 +142,7 @@ static void TestGL_InitDefaultVerts() {
// Our vertices need to be stored in this buffer.
glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
- glBufferData(GL_ARRAY_BUFFER, sizeof(DefaultVertices), DefaultVertices, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
@@ -150,7 +153,7 @@ static void TestGL_InitDefaultVerts() {
}
void
-TestGL_InitTexture(gl_effect_layer *Test)
+GL_InitTexture(gl_effect_layer *Test)
{
glGenFramebuffers(1, &Test->FramebufferObject);
glGenTextures(1, &Test->Texture);
@@ -160,12 +163,12 @@ TestGL_InitTexture(gl_effect_layer *Test)
}
void
-TestGL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, bool32 Multisample)
+GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, bool32 Multisample)
{
glViewport(0, 0, Width, Height);
if (!Test->Initialized) {
- TestGL_InitTexture(Test);
+ GL_InitTexture(Test);
}
GLenum Target = GL_TEXTURE_2D;
@@ -213,3 +216,99 @@ TestGL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Hei
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
+
+static void
+GL_RasterizeShape(project_layer *Layer, mask *Mask)
+{
+ gl_effect_layer Test = Layer->BitmapInfo.TestM;
+ gl_effect_layer Test2 = Layer->BitmapInfo.Test;
+ gl_vertex_shader VertData;
+
+ uint32 Width = Layer->Source->Info.Width;
+ uint32 Height = Layer->Source->Info.Height;
+
+ uint8 *Data = (uint8 *)Layer->BitmapInfo.BitmapBuffer;
+ glBindFramebuffer(GL_FRAMEBUFFER, Test.FramebufferObject);
+
+ glEnable(GL_STENCIL_TEST);
+ // glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ glStencilFunc(GL_ALWAYS, 0, 0xFF); // always write
+ glStencilMask(0xff); // allow writing; ANDs any writes to the stencil buffer with this
+
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ glUseProgram(DefaultShaderProgram);
+
+ int VertexMode = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ int FragmentMode = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(VertexMode, 1);
+ glUniform1i(FragmentMode, 0);
+
+ // secondary VBO
+ glGenVertexArrays(1, &VertData.VertexArrayObject);
+ glGenBuffers(1, &VertData.VertexBufferObject);
+ glBindVertexArray(VertData.VertexArrayObject);
+ glBindBuffer(GL_ARRAY_BUFFER, VertData.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, Mask->NumberOfVerts*3*sizeof(real32), Mask->TriangulatedPointCache, GL_STREAM_DRAW);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ int Scale = glGetUniformLocation(DefaultShaderProgram, "CompDimensions");
+ glUniform3f(Scale, Width, Height, 0);
+
+
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
+
+ glDisable(GL_CULL_FACE);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Mask->NumberOfVerts);
+
+ // glEnable(GL_CULL_FACE);
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ glBindVertexArray(0);
+
+ // glBindRenderbuffer(GL_RENDERBUFFER, Test.Color_Renderbuffer);
+
+ VertexMode = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ FragmentMode = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(VertexMode, 0);
+ glUniform1i(FragmentMode, 1);
+
+
+ // // Switch to main buffer
+ glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW);
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+ // texture coordinate (note the last parameter's offset)
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+
+ glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+ glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
+
+ glDisable(GL_STENCIL_TEST);
+ glStencilMask(0xFF);
+ glStencilFunc(GL_ALWAYS, 0, 0xFF);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, Test.FramebufferObject);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Test2.FramebufferObject);
+ glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, Test2.FramebufferObject);
+
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
diff --git a/gl_calls.h b/gl_calls.h
index ee4af54..fa0a00c 100644
--- a/gl_calls.h
+++ b/gl_calls.h
@@ -1,2 +1,24 @@
-extern void InitGLShaders();
+struct default_gl_vertex_object {
+ uint32 VertexArrayObject;
+ uint32 VertexBufferObject;
+ uint32 ElementBufferObject;
+};
+
+struct gl_vertex_shader {
+ uint32 VertexArrayObject;
+ uint32 VertexBufferObject;
+};
+
+static default_gl_vertex_object DefaultVerts;
+static gl_vertex_shader GL_DefaultVertexObjects;
+static uint32 DefaultVertexShader;
+static uint32 DefaultShaderProgram;
+static uint32 MaskShaderProgram;
+
+float GL_DefaultVertices[] = {
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+};
diff --git a/main.cpp b/main.cpp
index c6ac662..3456aa8 100644
--- a/main.cpp
+++ b/main.cpp
@@ -34,6 +34,7 @@
#include "defines.h"
#include "my_math.h"
+#include "structs.h"
#include "main.h"
#include "debug.h"
#include "functions.h"
@@ -73,7 +74,7 @@ SDL_sem *Semaphore;
static void
MainFunction(main_sdl *Main, memory *Memory,
project_state *State, project_data *File,
- cache_pool *Cache, comp_buffer *CompBuffer)
+ comp_buffer *CompBuffer)
{
Bitmap_Clear(CompBuffer->PackedBuffer, CompBuffer->Width, CompBuffer->Height, CompBuffer->BytesPerPixel);
Bitmap_Clear(CompBuffer->UnpackedBuffer, CompBuffer->Width, CompBuffer->Height, CompBuffer->BytesPerPixel);
@@ -99,106 +100,6 @@ MainFunction(main_sdl *Main, memory *Memory,
QueueCurrentFrame(File, CompBuffer, State);
}
-#if 0
-static 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
-
-
-static 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 = {};
@@ -249,8 +150,8 @@ int main(int argc, char *argv[]) {
#endif
project_data File = {};
- File.Width = 1280;
- File.Height = 720;
+ File.Width = 1920;
+ File.Height = 1080;
File.NumberOfFrames = 65;
File.FPS = 30;
File.CurrentFrame = 1;
@@ -279,9 +180,6 @@ int main(int argc, char *argv[]) {
CompBuffer.PackedBuffer = Layer_AllocateBitmap(&Memory, CompBuffer.Width, CompBuffer.Height, CompBuffer.BytesPerPixel);
CompBuffer.UnpackedBuffer = Layer_AllocateBitmap(&Memory, CompBuffer.Width, CompBuffer.Height, CompBuffer.BytesPerPixel);
- cache_pool Cache = {};
- Cache.Interact = Inactive;
-
ui UI = {};
// shm_unlink("/testl");
@@ -385,8 +283,8 @@ int main(int argc, char *argv[]) {
return -1;
}
- TestGL_InitDefaultShader();
- TestGL_InitDefaultVerts();
+ GL_InitDefaultShader();
+ GL_InitDefaultVerts();
SDL_GL_MakeCurrent(window, gl_context);
@@ -487,7 +385,7 @@ int main(int argc, char *argv[]) {
// UI never lags.
if (State.UpdateFrame && !IsRendering) {
- MainFunction(0, &Memory, &State, &File, &Cache, &CompBuffer);
+ MainFunction(0, &Memory, &State, &File, &CompBuffer);
State.UpdateFrame = 0;
}
diff --git a/main.h b/main.h
index 122c380..50242c3 100644
--- a/main.h
+++ b/main.h
@@ -8,24 +8,6 @@ enum instruction_mode {
#endif
};
-struct cache {
- void *Address;
- bool32 Cached;
-};
-
-enum whattocallthis {
- Inactive,
- Active,
- Clear
-};
-
-struct cache_pool {
- cache Frame[2048];
- cache Intermediate[3];
- whattocallthis Interact;
- int16 InteractIndex;
-};
-
enum memory_table_list {
// F = file attributes
@@ -111,12 +93,6 @@ struct memory {
struct property_channel;
struct project_layer;
-enum display_type
-{
- standard,
- levels
-};
-
enum keyframe_type
{
linear,
@@ -166,45 +142,6 @@ enum blend_mode
};
-struct gl_effect {
- uint32 ShaderProgram;
-};
-
-struct gl_vertex_shader {
- uint32 VertexArrayObject;
- uint32 VertexBufferObject;
-};
-
-struct default_gl_vertex_object {
- uint32 VertexArrayObject;
- uint32 VertexBufferObject;
- uint32 ElementBufferObject;
-};
-
-static default_gl_vertex_object DefaultVerts;
-static uint32 DefaultVertexShader;
-static uint32 DefaultShaderProgram;
-static uint32 MaskShaderProgram;
-
-float DefaultVertices[] = {
- 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
- 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
- -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
- -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-};
-
-
-struct gl_effect_layer {
- bool32 Initialized;
- GLuint Texture;
- GLuint FramebufferObject;
- uint32 Color_Renderbuffer;
- uint32 Stencil_Renderbuffer;
-};
-
-static gl_vertex_shader GL_Vertices;
-
-
union val {
real32 f;
v4 col;
@@ -285,12 +222,20 @@ struct source {
// Bitmaps from files are loaded into these temporary cache blocks.
+struct gl_effect_layer {
+ bool32 Initialized;
+ GLuint Texture;
+ GLuint FramebufferObject;
+ uint32 Color_Renderbuffer;
+ uint32 Stencil_Renderbuffer;
+};
struct layer_bitmap_info {
// Image and video
void *BitmapBuffer; // Each layer has a persistent bitmap that the source data gets packed into.
int32 FrameOffset; // The "true" position of the layer, separate from StartFrame. Starts at zero and only gets incremented when the layer is moved.
bool32 ToUpdate = 1;
+
gl_effect_layer Test;
gl_effect_layer TestM;
@@ -314,26 +259,6 @@ struct comp_buffer {
void *UnpackedBuffer;
};
-struct effect_header
-{
- char *Name;
- void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
- uint16 NumberOfProperties;
- display_type DisplayType;
- property_header PropertyHeader[MAX_PROPERTIES_PER_EFFECT];
-};
-
-struct effect {
- char *Name;
- void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
- uint16 NumberOfProperties;
- display_type DisplayType;
- gl_effect GL_Effect;
- property_channel Property[MAX_PROPERTIES_PER_EFFECT];
- bool32 UIIsCollapsed = 0;
- bool32 IsActive = 1;
-};
-
struct transform_info {
real32 XAxisPX;
real32 XAxisPY;
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index ea2e314..ac0739e 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -111,7 +111,6 @@ static void
ImGui_DebugUndoTree(project_data *File, memory *Memory)
{
ImGui::SetNextWindowSize(ImVec2(200, 800));
- ImGui::SetNextWindowPos(ImVec2(2498, 10));
ImGui::Begin("undotree");
for (int i = 0; i < Memory->Action.NumberOfEntries; i++) {
action_entry Entry = Memory->Action.Entry[i];
@@ -802,7 +801,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
if (State->DemoButton) {
if (ImGui::Button("Generate demo scene")) {
- // CreateDemoScene(File, Memory);
+ CreateDemoScene(File, State, Memory);
State->UpdateKeyframes = true;
State->UpdateFrame = true;
State->DemoButton = false;
@@ -885,6 +884,7 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui
if (State->filter.PassFilter(EffectList[i].Name)) {
if (EffectSel == p && State->MostRecentlySelectedLayer != -1) {
AddEffect(File->Layer[State->MostRecentlySelectedLayer], Memory, i);
+ State->UpdateFrame = true;
}
p++;
}
@@ -902,6 +902,7 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui
if (ImGui::IsItemClicked()) {
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && State->MostRecentlySelectedLayer != -1) {
AddEffect(File->Layer[State->MostRecentlySelectedLayer], Memory, i);
+ State->UpdateFrame = true;
}
}
p++;
@@ -999,9 +1000,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
UI->DraggingKeyframeThreshold += io.MouseDelta.x;
if (abs(UI->DraggingKeyframeThreshold) >= UI->TimelineZoom) {
int16 Increment = UI->DraggingKeyframeThreshold/UI->TimelineZoom;
- if (File->CurrentFrame <= 0 && Increment < File->StartFrame)
+ if (File->CurrentFrame + Increment <= 0)
File->CurrentFrame = 0;
- else if (File->CurrentFrame >= File->EndFrame && Increment > File->EndFrame) {
+ else if (File->CurrentFrame + Increment >= File->EndFrame) {
File->CurrentFrame = File->EndFrame;
} else {
File->CurrentFrame += Increment;
diff --git a/prenderer.cpp b/prenderer.cpp
index ccacbe8..1fa3e71 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -151,6 +151,7 @@ QueueCurrentFrame(project_data *File, comp_buffer *CompBuffer, project_state *St
{
IsRendering = true;
render_queue RenderInfo = {File, State, CompBuffer};
+
#if PERF
Test = __rdtsc();
#endif
diff --git a/structs.h b/structs.h
new file mode 100644
index 0000000..fbb97ed
--- /dev/null
+++ b/structs.h
@@ -0,0 +1,5 @@
+struct effect;
+
+struct action_entry;
+struct action_entries;
+