From bc5375149c0ecb416848a2d3657ea41ae97177b3 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 10 Aug 2022 21:24:03 -0400 Subject: path rasterization started with opengl --- createcalls.cpp | 194 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 166 insertions(+), 28 deletions(-) (limited to 'createcalls.cpp') diff --git a/createcalls.cpp b/createcalls.cpp index 5144cf0..4ddaa7e 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -180,6 +180,96 @@ STB_LoadStill(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory) return Bitmap; } +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 { + real32 *Data = (real32 *)Mask->TriangulatedPointCache + Mask->NumberOfVerts*3; + *(Data++) = Point0.Pos.x; + *(Data++) = Point0.Pos.y; + *(Data++) = 0; + Mask->NumberOfVerts += 1; + } + } +} + +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.Test; + + glBindFramebuffer(GL_FRAMEBUFFER, Test.FramebufferObject); + + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glStencilFunc(GL_ALWAYS, 1, 0xFF); // always write + glStencilMask(0xff); // allow writing; ANDs any writes to the stencil buffer with this + + glUseProgram(MaskShaderProgram); + + // 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(MaskShaderProgram, "CompDimensions"); + glUniform3f(Scale, (real32)Layer->Source->Info.Width, (real32)Layer->Source->Info.Height, 0); + + glDrawArrays(GL_TRIANGLE_FAN, 0, Mask->NumberOfVerts); + + glBindVertexArray(0); + glStencilFunc(GL_EQUAL, 1, 0xFF); + glStencilMask(0x00); // disables stencil writing + + glBindRenderbuffer(GL_RENDERBUFFER, Test.Color_Renderbuffer); + glUseProgram(DefaultShaderProgram); + + // // 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); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + + glDisable(GL_STENCIL_TEST); + glStencilMask(0xFF); + glStencilFunc(GL_ALWAYS, 0, 0xFF); + + uint8 *Data = (uint8 *)Layer->BitmapInfo.BitmapBuffer; + glReadPixels(0, 0, Layer->Source->Info.Width, Layer->Source->Info.Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + static void Layer_UpdateBitmap(project_layer *Layer, memory *Memory, int32 CurrentFrame) { @@ -199,7 +289,16 @@ Layer_UpdateBitmap(project_layer *Layer, memory *Memory, int32 CurrentFrame) { void *DestBuffer = BitmapInfo->BitmapBuffer; uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); Bitmap_CopyToPointer(Bitmap->Data, DestBuffer, BytesPerPixel, Size); + TestGL_InitTexture(&BitmapInfo->Test, DestBuffer, Width, Height); + + if (Layer->NumberOfMasks) { + for (int i = 0; i < Layer->NumberOfMasks; i++) { + mask *Mask = &Layer->Mask[i]; + Mask_TriangulateAndRasterize(Memory, Layer, Mask); + } + } + for (int i = 0; i < Layer->NumberOfEffects; i++) { if (Layer->Effect[i]->IsActive) @@ -255,6 +354,25 @@ Layer_LocalToScreenSpace(project_layer *Layer, ui *UI, comp_buffer CompBuffer, v return ImVec2(ScreenPoint.x, ScreenPoint.y); } +static v2 +Layer_ScreenSpaceToLocal(project_layer *Layer, ui *UI, comp_buffer CompBuffer, ImVec2 ViewportMin, ImVec2 Point) +{ + source *Source = Layer->Source; + v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, Point); + v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, CompUV); + return V2(LayerUV.x * Source->Info.Width, LayerUV.y * Source->Info.Height); +} + +static void +Mask_AddPointToLine(mask *Mask, uint16 Index, v2 Pos) +{ + for (int i = Mask->NumberOfPoints - 1; i > Index; i--) { + Mask->Point[i+1] = Mask->Point[i]; + } + mask_point *PointToAdd = &Mask->Point[Index+1]; + PointToAdd->Pos = Pos; + Mask->NumberOfPoints++; +} static void Mask_PushPoint(mask *Mask, v2 Pos) @@ -265,22 +383,31 @@ Mask_PushPoint(mask *Mask, v2 Pos) } static void -Mask_AddPointToCurve(mask *Mask, ImVec2 Pos, ImVec2 TangentLeft, ImVec2 TangentRight, - ImVec2 Ratio0, ImVec2 Ratio1, uint16 Index) +Mask_AddPointToCurve(mask *Mask, uint16 Index, real32 ratio) { - mask_point *Point = &Mask->Point[Index]; - mask_point *NextPoint = &Mask->Point[Index+1]; + mask_point *Point0 = &Mask->Point[Index]; + mask_point *Point1 = &Mask->Point[Index+1]; + + v2 Point0_Pos_Right = Point0->Pos + Point0->TangentRight; + v2 Point1_Pos_Left = Point1->Pos + Point1->TangentLeft; + v2 Handle0_Half = Line_RatioToPoint(Point0->Pos, Point0_Pos_Right, ratio); + v2 Handle1_Half = Line_RatioToPoint(Point1_Pos_Left, Point1->Pos, ratio); + v2 Top_Half = Line_RatioToPoint(Point0_Pos_Right, Point1_Pos_Left, ratio); + v2 NewHandleLeft = Line_RatioToPoint(Handle0_Half, Top_Half, ratio); + v2 NewHandleRight = Line_RatioToPoint(Top_Half, Handle1_Half, ratio); + v2 NewPos = Line_RatioToPoint(NewHandleLeft, NewHandleRight, ratio); - Point->TangentRight = -V2(Ratio0); - NextPoint->TangentLeft = -V2(Ratio1); + Point0->TangentRight = -(Point0->Pos - Handle0_Half); + Point1->TangentLeft = -(Point1->Pos - Handle1_Half); for (int i = Mask->NumberOfPoints - 1; i > Index; i--) { Mask->Point[i+1] = Mask->Point[i]; } mask_point *PointToAdd = &Mask->Point[Index+1]; - PointToAdd->Pos = {Pos.x, Pos.y}; - PointToAdd->TangentLeft = {-TangentLeft.x, -TangentLeft.y}; - PointToAdd->TangentRight = {-TangentRight.x, -TangentRight.y}; + + PointToAdd->Pos = NewPos; + PointToAdd->TangentLeft = -(NewPos - NewHandleLeft); + PointToAdd->TangentRight = -(NewPos - NewHandleRight); Mask->NumberOfPoints++; } @@ -292,25 +419,36 @@ LoadTestFootage(project_data *File, project_state *State, memory *Memory) source *Source = &File->Source[0]; Layer_CreateFromSource(File, State, Memory, Source); SelectLayer(File->Layer[0], State, 0); - 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); - // Mask->Point[1].Pos = V2(1280, 0); - // Mask->Point[2].Pos = V2(1280, 720); - // Mask->Point[3].Pos = V2(0, 720); - - // Mask->Point[0].TangentLeft = V2(-50, 0); - // Mask->Point[1].TangentLeft = V2(-50, 0); - // Mask->Point[2].TangentLeft = V2(-50, 0); - // Mask->Point[3].TangentLeft = V2(-50, 0); - - // Mask->Point[0].TangentRight = V2(50, 0); - // Mask->Point[1].TangentRight = V2(50, 0); - // Mask->Point[2].TangentRight = V2(50, 0); - // Mask->Point[3].TangentRight = V2(50, 0); - // Mask->NumberOfPoints = 4; + // 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); + Mask->Point[1].Pos = V2(200, 400); + Mask->Point[2].Pos = V2(200, 520); + Mask->Point[3].Pos = V2(1080, 520); + Mask->Point[4].Pos = V2(1080, 200); + + Mask->Point[0].TangentLeft = V2(-50, 0); + Mask->Point[1].TangentLeft = V2(-50, 0); + Mask->Point[2].TangentLeft = V2(-50, 0); + Mask->Point[3].TangentLeft = V2(-50, 0); + Mask->Point[4].TangentLeft = V2(-50, 0); + + Mask->Point[0].TangentRight = V2(50, 0); + Mask->Point[1].TangentRight = V2(50, 0); + Mask->Point[2].TangentRight = V2(50, 0); + Mask->Point[3].TangentRight = V2(50, 0); + Mask->Point[4].TangentRight = V2(50, 0); + + Mask->Point[0].HandleBezier = true; + Mask->Point[1].HandleBezier = true; + Mask->Point[2].HandleBezier = true; + Mask->Point[3].HandleBezier = true; + Mask->Point[4].HandleBezier = true; + + + Mask->NumberOfPoints = 5; // property_channel *Property = &File->Layer[0]->x; // ManualKeyframeInsertF(Property, Memory, 1, 500); -- cgit v1.2.3