summaryrefslogtreecommitdiff
path: root/effects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'effects.cpp')
-rw-r--r--effects.cpp130
1 files changed, 124 insertions, 6 deletions
diff --git a/effects.cpp b/effects.cpp
index 6d27df1..d006941 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -187,6 +187,78 @@ DrawGradient(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, prop
static void
Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
+ real32 All_Start = Property[0].CurrentValue.f;
+ real32 All_Mid = Property[1].CurrentValue.f;
+ real32 All_End = Property[2].CurrentValue.f;
+ v4 Start = Property[3].CurrentValue.col;
+ v4 Mid = Property[4].CurrentValue.col;
+ v4 End = Property[5].CurrentValue.col;
+ if (!BitmapInfo->HistogramVals) {
+ uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel);
+ BitmapInfo->HistogramVals = AllocateMemory(Memory, (sizeof(uint32) * 5 * 256), P_MiscCache);
+ Bitmap_CalcHistogram(BitmapInfo->HistogramVals, BitmapInfo->BitmapBuffer, Source->Info.BytesPerPixel, Size);
+ }
+
+ Assert(&BitmapInfo->Test);
+ gl_effect_layer Test = BitmapInfo->Test;
+ glBindRenderbuffer(GL_RENDERBUFFER, Test.RBO);
+ glUseProgram(TGL.ShaderProgram);
+
+ int vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "Start");
+ glUniform1f(vertexColorLocation, All_Start);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "Mid");
+ glUniform1f(vertexColorLocation, All_Mid);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "End");
+ glUniform1f(vertexColorLocation, All_End);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "StartCol");
+ glUniform4f(vertexColorLocation, Start.r, Start.g, Start.b, Start.a);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "MidCol");
+ glUniform4f(vertexColorLocation, Mid.r, Mid.g, Mid.b, Mid.a);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "EndCol");
+ glUniform4f(vertexColorLocation, End.r, End.g, End.b, End.a);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ uint16 Width = Source->Info.Width;
+ uint16 Height = Source->Info.Height;
+ uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer;
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+static void
+GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
+{
+ real32 Radius = Property[0].CurrentValue.f;
+
+ gl_effect_layer *Test = &BitmapInfo->Test;
+ glBindRenderbuffer(GL_RENDERBUFFER, Test->RBO);
+ glUseProgram(TGL.ShaderProgram);
+
+ int vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "Radius");
+ glUniform1f(vertexColorLocation, Radius + 1.60f);
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "Direction");
+ glUniform2f(vertexColorLocation, 1.0f, 0.0f);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ uint16 Width = Source->Info.Width;
+ uint16 Height = Source->Info.Height;
+ uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer;
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
+
+ TestGL_InitTexture(&BitmapInfo->Test, Data, Width, Height);
+ glBindRenderbuffer(GL_RENDERBUFFER, Test->RBO);
+ glUseProgram(TGL.ShaderProgram);
+
+ vertexColorLocation = glGetUniformLocation(TGL.ShaderProgram, "Direction");
+ glUniform2f(vertexColorLocation, 0.0f, 1.0f);
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
#if WINDOWS
@@ -219,6 +291,12 @@ static effect_header EffectList[] {
{"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
@@ -236,12 +314,6 @@ static effect_header EffectList[] {
}
},
{
- "Gaussian Blur",
- &GaussianBlur, standard, {
- {"Radius", {2.0f}, real},
- }
- },
- {
"Canny edges",
&Canny, standard, {
{"Blur Radius", {1.0f}, real},
@@ -778,3 +850,49 @@ GaussianBlur(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
Gaussian(Buffer, Buffer->Scratch, Radius);
}
#endif
+
+// AVX2 effect example code
+/*
+ __m256 Fraction255 = _mm256_set1_ps(1/255.0f);
+ __m256 Real255 = _mm256_set1_ps(255);
+ __m256 One = _mm256_set1_ps(1);
+
+ __m256i FF = _mm256_set1_epi32(0xFF);
+ __m256 ZeroReal = _mm256_set1_ps(0);
+ __m256i Int255 = _mm256_set1_epi8((uint8)255);
+
+ 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);
+
+ __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_Dest;
+ __m256 G_Blend = G_Dest;
+ __m256 B_Blend = B_Dest;
+
+ 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);
+ }
+ }
+*/