From 5f85e2a5005de48f146ffb8e52012f555c1f8b3e Mon Sep 17 00:00:00 2001 From: xiaodi86 <1287548549@qq.com> Date: Sat, 18 Feb 2023 14:17:14 +0800 Subject: [PATCH 01/10] Brightness table special effects try --- .../java/org/wysaid/cgeDemo/MainActivity.java | 3 +- library/src/main/jni/Android.mk | 1 + .../jni/cge/filters/cgeAdvancedEffects.cpp | 5 + .../main/jni/cge/filters/cgeAdvancedEffects.h | 2 + .../jni/cge/filters/cgeDataParsingEngine.cpp | 18 ++++ .../jni/cge/filters/cgeHistogramFilter.cpp | 101 ++++++++++++++++++ .../main/jni/cge/filters/cgeHistogramFilter.h | 41 +++++++ 7 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 library/src/main/jni/cge/filters/cgeHistogramFilter.cpp create mode 100644 library/src/main/jni/cge/filters/cgeHistogramFilter.h diff --git a/cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java b/cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java index 9ab17665..00d12207 100644 --- a/cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java +++ b/cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java @@ -31,8 +31,9 @@ public class MainActivity extends AppCompatActivity { public static final String EFFECT_CONFIGS[] = { "", - "@curve RGB(0,255)(255,0) @style cm mapping0.jpg 80 80 8 3", // ASCII art (字符画效果) + "@style hist 0.01 0.01 0.4 0.4 0.0 0.0 0.0 0.9", "@style waveform 0.01 0.01 0.4 0.4", + "@curve RGB(0,255)(255,0) @style cm mapping0.jpg 80 80 8 3", // ASCII art (字符画效果) "@beautify face 1 480 640", //Beautify "@adjust lut edgy_amber.png", "@adjust lut filmstock.png", diff --git a/library/src/main/jni/Android.mk b/library/src/main/jni/Android.mk index b8e8c6fb..6459ed47 100644 --- a/library/src/main/jni/Android.mk +++ b/library/src/main/jni/Android.mk @@ -75,6 +75,7 @@ LOCAL_SRC_FILES := \ $(CGE_SOURCE)/filters/cgeEmbossFilter.cpp \ \ $(CGE_SOURCE)/filters/cgeWaveformFilter.cpp \ + $(CGE_SOURCE)/filters/cgeHistogramFilter.cpp \ \ $(CGE_SOURCE)/filters/cgeCrosshatchFilter.cpp \ $(CGE_SOURCE)/filters/cgeLiquifyFilter.cpp \ diff --git a/library/src/main/jni/cge/filters/cgeAdvancedEffects.cpp b/library/src/main/jni/cge/filters/cgeAdvancedEffects.cpp index 8ba92182..bf161dc2 100644 --- a/library/src/main/jni/cge/filters/cgeAdvancedEffects.cpp +++ b/library/src/main/jni/cge/filters/cgeAdvancedEffects.cpp @@ -137,6 +137,11 @@ CGEBeautifyFilter* createBeautifyFilter() COMMON_FUNC(CGEBeautifyFilter); } +CGEHistogramFilter* createHistogramFilter() +{ + COMMON_FUNC(CGEHistogramFilter); +} + CGEWaveformFilter* createWaveformFilter() { COMMON_FUNC(CGEWaveformFilter); diff --git a/library/src/main/jni/cge/filters/cgeAdvancedEffects.h b/library/src/main/jni/cge/filters/cgeAdvancedEffects.h index a5c756e4..aac44680 100644 --- a/library/src/main/jni/cge/filters/cgeAdvancedEffects.h +++ b/library/src/main/jni/cge/filters/cgeAdvancedEffects.h @@ -23,6 +23,7 @@ #include "cgeRandomBlurFilter.h" #include "cgeSketchFilter.h" #include "cgeWaveformFilter.h" +#include "cgeHistogramFilter.h" namespace CGE { @@ -51,6 +52,7 @@ CGESketchFilter* createSketchFilter(); CGEBeautifyFilter* createBeautifyFilter(); CGEWaveformFilter* createWaveformFilter(); +CGEHistogramFilter* createHistogramFilter(); } // namespace CGE #endif diff --git a/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp b/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp index 92fc3fb6..ea1be8f7 100644 --- a/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp +++ b/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp @@ -1093,6 +1093,24 @@ CGEImageFilterInterface* CGEDataParsingEngine::advancedStyleParser(const char* p { ADJUSTHELP_COMMON_FUNC2(pstr, CGECrosshatchFilter, setCrosshatchSpacing, setLineWidth); } + else if (strcmp(buffer, "hist") == 0) + { + float x, y, value1, value2, r, g, b, a = 1.0f; + if (sscanf(pstr, "%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f", &x, &y, &value1, &value2, &r, &g, &b, &a) < 7) + { + LOG_ERROR_PARAM(pstr); + return nullptr; + } + + CGEHistogramFilter* filter = createHistogramFilter(); + if (filter != nullptr) + { + proc = filter; + filter->setFormPosition(x, y); + filter->setFormSize(value1, value2); + filter->setColor(r, g, b, a); + } + } else if (strcmp(buffer, "waveform") == 0) { float x, y, width, height; diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp new file mode 100644 index 00000000..00318ce1 --- /dev/null +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp @@ -0,0 +1,101 @@ +#include "cgeHistogramFilter.h" + +#include <EGL/egl.h> + +static CGEConstString s_vshHistogram = "#version 320 es\n" CGE_SHADER_STRING_PRECISION_H( +layout(location = 0) in vec2 position; +layout(location = 0) out vec2 textureCoordinate; +void main() { + gl_Position = vec4(position, 0.0, 1.0); + textureCoordinate = (position.xy + 1.0) / 2.0; +}); + +static CGEConstString s_fshHistogram = "#version 320 es\n" CGE_SHADER_STRING( + precision highp float; +precision highp int; +// GLSL代码 +layout(location = 0) in vec2 textureCoordinate; +layout(binding = 0) uniform sampler2D inputImageTexture; +layout (binding = 1, rgba32f) uniform writeonly highp image2D histogram; // 直方图 +void main() { + vec4 color = texture(inputImageTexture, textureCoordinate); + + int binIndex = int(clamp(color.r * 255.0f, 0.0f, 254.99999)); + + imageAtomicAdd(histogram, ivec2(binIndex), 1); +}); + + +namespace CGE +{ + CGEHistogramFilter::~CGEHistogramFilter(){} + + bool CGEHistogramFilter::init() + { + if (initShadersFromString(s_vshHistogram, s_fshHistogram)) + { + m_program.bind(); + setFormPosition(0.1f, 0.1f); + setFormSize(0.3f, 0.3f); + setColor(0.0f, 0.0f, 0.0f, 0.5f); + m_drawer.reset(TextureDrawer::create()); + m_drawer->setFlipScale(1.0f, -1.0f); // flip upside down, meet the gl coord. + m_renderTarget = std::make_unique<FrameBufferWithTexture>(); + return true; + } + + return false; + } + + void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) + { + auto&& sz = handler->getOutputFBOSize(); + if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) + { + m_renderTarget->bindTexture2D(256, sz.height); + } + + m_renderTarget->bind(); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glFinish(); + + m_program.bind(); + /// 渲染不写入, 使用 imageStore 写入. + glColorMask(false, false, false, false); + + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, srcTexture); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glBindImageTexture(1, m_renderTarget->texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glColorMask(true, true, true, true); + glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + + handler->setAsTarget(); + glViewport(m_position[0] * sz.width, m_position[1] * sz.height, m_size[0] * sz.width, m_size[1] * sz.height); + m_drawer->drawTexture(m_renderTarget->texture()); + } + + void CGEHistogramFilter::setFormPosition(float left, float top) + { + m_position = { left, top }; + } + + void CGEHistogramFilter::setFormSize(float width, float height) + { + m_size = { width, height }; + } + + void CGEHistogramFilter::setColor(float r, float g, float b, float a) + { + m_color = { r, g, b, a }; + } +} // namespace CGE \ No newline at end of file diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.h b/library/src/main/jni/cge/filters/cgeHistogramFilter.h new file mode 100644 index 00000000..1e238fe9 --- /dev/null +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.h @@ -0,0 +1,41 @@ +#ifndef _HISTOGRAMFILTER_H_ +#define _HISTOGRAMFILTER_H_ + +#include "cgeImageFilter.h" +#include "cgeTextureUtils.h" +#include "cgeVec.h" +namespace CGE +{ + class CGEHistogramFilter : public CGEImageFilterInterface + { + public: + ~CGEHistogramFilter() override; + + /** + * @brief 左上角的点 + */ + void setFormPosition(float left, float top); + /** + * @brief 相对大小 + */ + void setFormSize(float width, float height); + + /** + * @brief 背景色 + */ + void setColor(float r, float g, float b, float a); + + bool init() override; + + void render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) override; + + protected: + std::unique_ptr<TextureDrawer> m_drawer; + std::unique_ptr<FrameBufferWithTexture> m_renderTarget; + Vec2f m_position; + Vec2f m_size; + Vec4f m_color; + }; +} // namespace CGE + +#endif \ No newline at end of file From 8f12da3e87070176c2a8699f644a55d7b0df6bfe Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 08:53:28 +0800 Subject: [PATCH 02/10] Fix Histogram render2Texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正获取纹理像素,直方图数据传入图像数据方式 --- .../jni/cge/filters/cgeHistogramFilter.cpp | 210 ++++++++++-------- 1 file changed, 119 insertions(+), 91 deletions(-) diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp index 00318ce1..bb27bca0 100644 --- a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp @@ -1,101 +1,129 @@ + #include "cgeHistogramFilter.h" #include <EGL/egl.h> +#include <array> +#include <GLES3/gl3.h> static CGEConstString s_vshHistogram = "#version 320 es\n" CGE_SHADER_STRING_PRECISION_H( -layout(location = 0) in vec2 position; -layout(location = 0) out vec2 textureCoordinate; -void main() { - gl_Position = vec4(position, 0.0, 1.0); - textureCoordinate = (position.xy + 1.0) / 2.0; -}); + layout(location = 0) in vec2 position; + layout(location = 0) out vec2 textureCoordinate; + void main() { + gl_Position = vec4(position, 0.0, 1.0); + textureCoordinate = (position.xy + 1.0) / 2.0; + }); static CGEConstString s_fshHistogram = "#version 320 es\n" CGE_SHADER_STRING( - precision highp float; -precision highp int; -// GLSL代码 -layout(location = 0) in vec2 textureCoordinate; -layout(binding = 0) uniform sampler2D inputImageTexture; -layout (binding = 1, rgba32f) uniform writeonly highp image2D histogram; // 直方图 -void main() { - vec4 color = texture(inputImageTexture, textureCoordinate); - - int binIndex = int(clamp(color.r * 255.0f, 0.0f, 254.99999)); - - imageAtomicAdd(histogram, ivec2(binIndex), 1); -}); - + precision highp float; + precision highp int; + layout(location = 0) in vec2 textureCoordinate; + layout(binding = 0) uniform sampler2D inputImageTexture; + layout(rgba8, binding = 1) writeonly uniform highp uimage2D outputImage; + layout(location = 0) out vec4 fragColor; + + void main() { + vec4 color = texture(inputImageTexture, textureCoordinate); + float lum = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + int newLoc = int(lum * 255.0); + if (newLoc >= 0 && newLoc < 256) { + imageAtomicAdd(outputImage, ivec2(newLoc, 0), 1); + } + fragColor = vec4(1.0); + }); namespace CGE { - CGEHistogramFilter::~CGEHistogramFilter(){} - - bool CGEHistogramFilter::init() - { - if (initShadersFromString(s_vshHistogram, s_fshHistogram)) - { - m_program.bind(); - setFormPosition(0.1f, 0.1f); - setFormSize(0.3f, 0.3f); - setColor(0.0f, 0.0f, 0.0f, 0.5f); - m_drawer.reset(TextureDrawer::create()); - m_drawer->setFlipScale(1.0f, -1.0f); // flip upside down, meet the gl coord. - m_renderTarget = std::make_unique<FrameBufferWithTexture>(); - return true; - } - - return false; - } - - void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) - { - auto&& sz = handler->getOutputFBOSize(); - if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) - { - m_renderTarget->bindTexture2D(256, sz.height); - } - - m_renderTarget->bind(); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glFinish(); - - m_program.bind(); - /// 渲染不写入, 使用 imageStore 写入. - glColorMask(false, false, false, false); - - glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, srcTexture); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glBindImageTexture(1, m_renderTarget->texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glColorMask(true, true, true, true); - glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - - handler->setAsTarget(); - glViewport(m_position[0] * sz.width, m_position[1] * sz.height, m_size[0] * sz.width, m_size[1] * sz.height); - m_drawer->drawTexture(m_renderTarget->texture()); - } - - void CGEHistogramFilter::setFormPosition(float left, float top) - { - m_position = { left, top }; - } - - void CGEHistogramFilter::setFormSize(float width, float height) - { - m_size = { width, height }; - } - - void CGEHistogramFilter::setColor(float r, float g, float b, float a) - { - m_color = { r, g, b, a }; - } -} // namespace CGE \ No newline at end of file + CGEHistogramFilter::~CGEHistogramFilter(){} + + bool CGEHistogramFilter::init() + { + if (initShadersFromString(s_vshHistogram, s_fshHistogram)) + { + m_program.bind(); + setFormPosition(0.1f, 0.1f); + setFormSize(0.3f, 0.3f); + setColor(0.0f, 0.0f, 0.0f, 0.5f); + m_drawer.reset(TextureDraw::create()); + m_drawer->setFlipScale(1.0f, -1.0f); + m_renderTarget = std::make_unique<FrameBufferWithTexture>(); + return true; + } + + return false; + } + + void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) + { + auto&& sz = handler->getOutputFBOSize(); + if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) + { + m_renderTarget->bindTexture2D(sz.width, 256); + } + + m_renderTarget->bind(); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glFinish(); + + m_program.bind(); + glColorMask(false, false, false, false); + + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, srcTexture); + + glUniform1i(m_program.uniformLocation("inputImageTexture"), 0); + + // 获取纹理尺寸,用于计算像素位置 + const auto texSize = handler->getOutputFBOSize(); + // 清空直方图数组 + std::array<float, 256> histogram{}; + // 遍历纹理像素,计算亮度直方图 + std::vector<unsigned char> pixels(texSize.width * texSize.height * 4); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); + for (int i = 0; i < pixels.size(); i += 4) { + const auto r = pixels[i]; + const auto g = pixels[i + 1]; + const auto b = pixels[i + 2]; + const auto lum = 0.299f * r + 0.587f * g + 0.114f * b; + histogram[static_cast<int>(lum * 255)]++; + } + + // 将直方图数据传入图像数据,写入 GLSL Image 中 + auto data = m_renderTarget->mapBuffer(); + for (int i = 0; i < histogram.size(); i++) { + const auto height = static_cast<int>(histogram[i] * 256); + for (int j = 0; j < height; j++) { + const auto offset = i + j * 256; + data[offset] = 255; + } + } + m_renderTarget->unmapBuffer(); + + // 绘制直方图 + const auto position = m_position * Vec2f(sz.width, sz.height); + const auto size = m_size * Vec2f(sz.width, sz.height); + m_drawer->setTexture(m_renderTarget->texture(), 256, 256); + m_drawer->setColor(m_color); + m_drawer->setDrawRect(position[0], position[1], size[0], size[1]); + m_drawer->draw(); + + } + void CGEHistogramFilter::setFormPosition(float left, float top) + { + m_position = {left, top}; + } + + void CGEHistogramFilter::setFormSize(float width, float height) + { + m_size = {width, height}; + } + + void CGEHistogramFilter::setColor(float r, float g, float b, float a) + { + m_color = {r, g, b, a}; + } +} From 1e9b233b084a2703a73e4fc0ff039720902a3fa3 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 08:58:56 +0800 Subject: [PATCH 03/10] Fix FrameBufferWithTexture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在FrameBufferWithTexture类中如何定义mapBuffer()和unmapBuffer() --- .../main/jni/cge/common/cgeGLFunctions.cpp | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/library/src/main/jni/cge/common/cgeGLFunctions.cpp b/library/src/main/jni/cge/common/cgeGLFunctions.cpp index fd4a53fa..cbec232f 100644 --- a/library/src/main/jni/cge/common/cgeGLFunctions.cpp +++ b/library/src/main/jni/cge/common/cgeGLFunctions.cpp @@ -1,4 +1,4 @@ -/* +/* * cgeGLFunctions.cpp * * Created on: 2013-12-5 @@ -6,7 +6,7 @@ */ #include "cgeGLFunctions.h" - +#include <EGL/egl.h> #include <cmath> CGE_LOG_CODE( @@ -390,4 +390,74 @@ bool FrameBufferWithTexture::checkStatus() return ret == GL_FRAMEBUFFER_COMPLETE; } +////////////// + + FrameBufferTexture::FrameBufferTexture() : m_fbo(0), m_texture(0), m_width(0), m_height(0) + { + glGenFramebuffers(1, &m_fbo); + assert(m_fbo != 0); + } + + FrameBufferTexture::~FrameBufferTexture() + { + glDeleteFramebuffers(1, &m_fbo); + glDeleteTextures(1, &m_texture); + } + + GLuint FrameBufferTexture::texture() const + { + return m_texture; + } + + GLsizei FrameBufferTexture::width() const + { + return m_width; + } + + GLsizei FrameBufferTexture::height() const + { + return m_height; + } + + void FrameBufferTexture::bindTexture2D(GLsizei width, GLsizei height) + { + if (m_texture == 0) + { + glGenTextures(1, &m_texture); + assert(m_texture != 0); + } + + glBindTexture(GL_TEXTURE_2D, m_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, nullptr); + 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); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindTexture(GL_TEXTURE_2D, 0); + + m_width = width; + m_height = height; + } + + void FrameBufferTexture::bind() + { + glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); + } + + unsigned char* FrameBufferTexture::mapBuffer() + { + glBindTexture(GL_TEXTURE_2D, m_texture); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + const auto bufferSize = m_width * m_height * sizeof(float); + auto buffer = new unsigned char[bufferSize]; + glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); + return buffer; + } + + void FrameBufferTexture::unmapBuffer() + { + glBindTexture(GL_TEXTURE_2D, 0); + } + } // namespace CGE From 6bdf355726b3678edc7ab60cfc2b0f6b241c82c8 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 09:01:24 +0800 Subject: [PATCH 04/10] Fix FrameBufferWithTexture support Histogram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在FrameBufferWithTexture类中如何定义mapBuffer()和unmapBuffer() --- .../src/main/jni/cge/common/cgeGLFunctions.h | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/library/src/main/jni/cge/common/cgeGLFunctions.h b/library/src/main/jni/cge/common/cgeGLFunctions.h index f317cdcd..d1596248 100644 --- a/library/src/main/jni/cge/common/cgeGLFunctions.h +++ b/library/src/main/jni/cge/common/cgeGLFunctions.h @@ -1,4 +1,4 @@ -/* +/* * cgeGLFunctions.h * * Created on: 2013-12-5 @@ -103,13 +103,14 @@ class FrameBuffer bindTexture2D(texID, attachment); glViewport(x, y, w, h); } - inline GLuint fbo() { return m_framebuffer; } + protected: GLuint m_framebuffer; }; + struct CGESizei { CGESizei() : @@ -210,6 +211,27 @@ class FrameBufferWithTexture : protected FrameBuffer, public TextureObject GLuint m_renderBuffer = 0; }; +class FrameBufferTexture + { + public: + FrameBufferTexture(); + ~FrameBufferTexture(); + + GLuint texture() const; + GLsizei width() const; + GLsizei height() const; + void bindTexture2D(GLsizei width, GLsizei height); + void bind(); + unsigned char* mapBuffer(); + void unmapBuffer(); + + private: + GLuint m_fbo; + GLuint m_texture; + GLsizei m_width; + GLsizei m_height; +}; + struct CGELuminance { enum From 615498bee018ac331ae3fa0c1d01e673fd6cce2b Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 09:48:33 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=83=8F=E7=B4=A0=E6=95=B0=E6=8D=AE=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit delete glGetTexImage --- .../jni/cge/filters/cgeHistogramFilter.cpp | 99 +++++++++---------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp index bb27bca0..1833731c 100644 --- a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp @@ -3,63 +3,58 @@ #include <EGL/egl.h> #include <array> -#include <GLES3/gl3.h> static CGEConstString s_vshHistogram = "#version 320 es\n" CGE_SHADER_STRING_PRECISION_H( - layout(location = 0) in vec2 position; - layout(location = 0) out vec2 textureCoordinate; - void main() { - gl_Position = vec4(position, 0.0, 1.0); - textureCoordinate = (position.xy + 1.0) / 2.0; - }); + layout(location = 0) in vec2 position; + layout(location = 0) out vec2 textureCoordinate; + void main() { + gl_Position = vec4(position, 0.0, 1.0); + textureCoordinate = (position.xy + 1.0) / 2.0; + }); static CGEConstString s_fshHistogram = "#version 320 es\n" CGE_SHADER_STRING( - precision highp float; - precision highp int; - layout(location = 0) in vec2 textureCoordinate; - layout(binding = 0) uniform sampler2D inputImageTexture; - layout(rgba8, binding = 1) writeonly uniform highp uimage2D outputImage; - layout(location = 0) out vec4 fragColor; - - void main() { - vec4 color = texture(inputImageTexture, textureCoordinate); - float lum = dot(color.rgb, vec3(0.299, 0.587, 0.114)); - int newLoc = int(lum * 255.0); - if (newLoc >= 0 && newLoc < 256) { - imageAtomicAdd(outputImage, ivec2(newLoc, 0), 1); - } - fragColor = vec4(1.0); - }); + precision highp float; + precision highp int; + layout(location = 0) in vec2 textureCoordinate; + layout(rgba8ui, binding = 0) uniform readonly highp uimage2D inputImageTexture; + layout(rgba8ui, binding = 1) uniform writeonly highp uimage2D outputImage; + layout(location = 0) out vec4 fragColor; + + void main() { + fragColor = vec4(1.0); + + vec4 color = texture(inputImageTexture, textureCoordinate); + float lum = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + int newLoc = int(lum * 255.0); + if (newLoc >= 0 && newLoc < 256) { + ivec2 location = ivec2(newLoc, 0); + atomicAdd(imageAtomic(outputImage, location), 1); + } + }); -namespace CGE -{ - CGEHistogramFilter::~CGEHistogramFilter(){} +namespace CGE { - bool CGEHistogramFilter::init() - { - if (initShadersFromString(s_vshHistogram, s_fshHistogram)) - { + CGEHistogramFilter::~CGEHistogramFilter() {} + + bool CGEHistogramFilter::init() { + if (initShadersFromString(s_vshHistogram, s_fshHistogram)) { m_program.bind(); setFormPosition(0.1f, 0.1f); setFormSize(0.3f, 0.3f); - setColor(0.0f, 0.0f, 0.0f, 0.5f); - m_drawer.reset(TextureDraw::create()); + m_drawer.reset(TextureDrawer::create()); m_drawer->setFlipScale(1.0f, -1.0f); - m_renderTarget = std::make_unique<FrameBufferWithTexture>(); + m_renderTarget = std::make_unique<FrameBufferTexture>(); return true; } return false; } - void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) - { + void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) { auto&& sz = handler->getOutputFBOSize(); - if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) - { + if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) { m_renderTarget->bindTexture2D(sz.width, 256); } - m_renderTarget->bind(); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); @@ -83,7 +78,8 @@ namespace CGE std::array<float, 256> histogram{}; // 遍历纹理像素,计算亮度直方图 std::vector<unsigned char> pixels(texSize.width * texSize.height * 4); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); + glReadPixels(0, 0, texSize.width, texSize.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); +// glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); for (int i = 0; i < pixels.size(); i += 4) { const auto r = pixels[i]; const auto g = pixels[i + 1]; @@ -97,21 +93,25 @@ namespace CGE for (int i = 0; i < histogram.size(); i++) { const auto height = static_cast<int>(histogram[i] * 256); for (int j = 0; j < height; j++) { - const auto offset = i + j * 256; - data[offset] = 255; + const auto pixel = reinterpret_cast<unsigned char*>(data) + j * m_renderTarget->width() * 4 + i * 4; + pixel[0] = 255; + pixel[1] = 255; + pixel[2] = 255; + pixel[3] = 255; } } m_renderTarget->unmapBuffer(); + glViewport(m_position[0] * sz.width, m_position[1] * sz.height, m_size[0] * sz.width, m_size[1] * sz.height); // 绘制直方图 - const auto position = m_position * Vec2f(sz.width, sz.height); - const auto size = m_size * Vec2f(sz.width, sz.height); - m_drawer->setTexture(m_renderTarget->texture(), 256, 256); - m_drawer->setColor(m_color); - m_drawer->setDrawRect(position[0], position[1], size[0], size[1]); - m_drawer->draw(); + m_drawer->drawTexture(m_renderTarget->texture()); + glColorMask(true, true, true, true); + + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } + void CGEHistogramFilter::setFormPosition(float left, float top) { m_position = {left, top}; @@ -121,9 +121,4 @@ namespace CGE { m_size = {width, height}; } - - void CGEHistogramFilter::setColor(float r, float g, float b, float a) - { - m_color = {r, g, b, a}; - } } From 5c0cf5a02b5ec48a3b9681de283bfc99862809d2 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 09:50:32 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E8=AE=BE=E8=AE=BE=E7=BD=AEsetColor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除背景设设置setColor --- .../main/jni/cge/filters/cgeHistogramFilter.h | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.h b/library/src/main/jni/cge/filters/cgeHistogramFilter.h index 1e238fe9..3b032b2a 100644 --- a/library/src/main/jni/cge/filters/cgeHistogramFilter.h +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.h @@ -4,38 +4,26 @@ #include "cgeImageFilter.h" #include "cgeTextureUtils.h" #include "cgeVec.h" -namespace CGE -{ - class CGEHistogramFilter : public CGEImageFilterInterface - { - public: - ~CGEHistogramFilter() override; - /** - * @brief 左上角的点 - */ - void setFormPosition(float left, float top); - /** - * @brief 相对大小 - */ - void setFormSize(float width, float height); +namespace CGE{ +class CGEHistogramFilter : public CGEImageFilterInterface + { + public: + ~CGEHistogramFilter() override; - /** - * @brief 背景色 - */ - void setColor(float r, float g, float b, float a); + void setFormPosition(float left, float top); - bool init() override; + void setFormSize(float width, float height); - void render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) override; + bool init() override; - protected: - std::unique_ptr<TextureDrawer> m_drawer; - std::unique_ptr<FrameBufferWithTexture> m_renderTarget; - Vec2f m_position; - Vec2f m_size; - Vec4f m_color; - }; -} // namespace CGE + void render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) override; -#endif \ No newline at end of file + protected: + std::unique_ptr<TextureDrawer> m_drawer; + std::unique_ptr<FrameBufferTexture> m_renderTarget; + Vec2f m_position; + Vec2f m_size; + }; +} +#endif From 15b06e821cd95f7f89cf1a14b66471d1119ea579 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Wed, 1 Mar 2023 09:54:13 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=BF=AE=E6=94=B9Histogram=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改Histogram 参数 --- .../jni/cge/filters/cgeDataParsingEngine.cpp | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp b/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp index ea1be8f7..3bcfd6e8 100644 --- a/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp +++ b/library/src/main/jni/cge/filters/cgeDataParsingEngine.cpp @@ -1093,24 +1093,23 @@ CGEImageFilterInterface* CGEDataParsingEngine::advancedStyleParser(const char* p { ADJUSTHELP_COMMON_FUNC2(pstr, CGECrosshatchFilter, setCrosshatchSpacing, setLineWidth); } - else if (strcmp(buffer, "hist") == 0) - { - float x, y, value1, value2, r, g, b, a = 1.0f; - if (sscanf(pstr, "%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f%*c%f", &x, &y, &value1, &value2, &r, &g, &b, &a) < 7) + else if (strcmp(buffer, "hist") == 0) { - LOG_ERROR_PARAM(pstr); - return nullptr; - } + float x, y, width, height; + if (sscanf(pstr, "%f%*c%f%*c%f%*c%f", &x, &y, &width, &height) < 4) + { + LOG_ERROR_PARAM(pstr); + return nullptr; + } - CGEHistogramFilter* filter = createHistogramFilter(); - if (filter != nullptr) - { - proc = filter; - filter->setFormPosition(x, y); - filter->setFormSize(value1, value2); - filter->setColor(r, g, b, a); + CGEHistogramFilter* filter = createHistogramFilter(); + if (filter != nullptr) + { + proc = filter; + filter->setFormPosition(x, y); + filter->setFormSize(width, height); + } } - } else if (strcmp(buffer, "waveform") == 0) { float x, y, width, height; From 00539c96ae87b1566af27c54454d0dff5996da86 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Thu, 2 Mar 2023 17:29:08 +0800 Subject: [PATCH 08/10] Fix erro Fix error: use of undeclared identifier 'glGetTexImage' --- library/src/main/jni/cge/common/cgeGLFunctions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/src/main/jni/cge/common/cgeGLFunctions.cpp b/library/src/main/jni/cge/common/cgeGLFunctions.cpp index cbec232f..ff20ff20 100644 --- a/library/src/main/jni/cge/common/cgeGLFunctions.cpp +++ b/library/src/main/jni/cge/common/cgeGLFunctions.cpp @@ -451,7 +451,8 @@ bool FrameBufferWithTexture::checkStatus() glPixelStorei(GL_PACK_ALIGNMENT, 1); const auto bufferSize = m_width * m_height * sizeof(float); auto buffer = new unsigned char[bufferSize]; - glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); + glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); +// glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, buffer); return buffer; } From 9006143de4da8c7de5a57c618a8277ae58f97428 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Thu, 2 Mar 2023 18:24:39 +0800 Subject: [PATCH 09/10] try fix 'imageAtomic' try fix No matching function for call to 'imageAtomic' --- library/src/main/jni/cge/filters/cgeHistogramFilter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp index 1833731c..7b5882cb 100644 --- a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp @@ -27,8 +27,10 @@ static CGEConstString s_fshHistogram = "#version 320 es\n" CGE_SHADER_STRING( float lum = dot(color.rgb, vec3(0.299, 0.587, 0.114)); int newLoc = int(lum * 255.0); if (newLoc >= 0 && newLoc < 256) { + //vec2 location = vec2(newLoc, 0.0); ivec2 location = ivec2(newLoc, 0); atomicAdd(imageAtomic(outputImage, location), 1); + //imageAtomic(outputImage, ivec2(location.x, location.y), uvec4(1, 0, 0, 0)); } }); From 5b720861c323069ab0e6c17105cd87cf28ee4a96 Mon Sep 17 00:00:00 2001 From: xiaodi86 <51728141+xiaodi86@users.noreply.github.com> Date: Fri, 3 Mar 2023 08:40:41 +0800 Subject: [PATCH 10/10] Update cgeHistogramFilter.cpp --- library/src/main/jni/cge/filters/cgeHistogramFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp index 7b5882cb..7e50c6ff 100644 --- a/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp +++ b/library/src/main/jni/cge/filters/cgeHistogramFilter.cpp @@ -55,7 +55,7 @@ namespace CGE { void CGEHistogramFilter::render2Texture(CGEImageHandlerInterface* handler, GLuint srcTexture, GLuint vertexBufferID) { auto&& sz = handler->getOutputFBOSize(); if (sz.width != m_renderTarget->width() || m_renderTarget->texture() == 0) { - m_renderTarget->bindTexture2D(sz.width, 256); + m_renderTarget->bindTexture2D(sz.width, sz.height); } m_renderTarget->bind(); glClearColor(0, 0, 0, 1);