Skip to content

Commit

Permalink
Merge pull request #512 from wysaid/feature/histogram (WaveFormFilter)
Browse files Browse the repository at this point in the history
WaveFormFilter from #510
  • Loading branch information
wysaid authored Feb 14, 2023
2 parents aa6b070 + 9850d74 commit 9c81c5d
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 126 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"*.cc": "cpp",
"params.txt": "json",
"CMakeLists*.txt": "cmake",
"__config": "c"
"__config": "c",
"cstdio": "cpp"
}
}
14 changes: 14 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Cleanup workspace (git clean -ffdx)",
"type": "shell",
"command": "git",
"args": [
"clean",
"-ffdx"
],
"options": {
"cwd": "${workspaceFolder}"
},
"group": "build",
"problemMatcher": "$gcc"
},
{
"label": "[Debug] Build Android Demo",
"type": "shell",
Expand Down
1 change: 1 addition & 0 deletions cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ 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 waveform 0.01 0.01 0.4 0.4",
"@beautify face 1 480 640", //Beautify
"@adjust lut edgy_amber.png",
"@adjust lut filmstock.png",
Expand Down
3 changes: 3 additions & 0 deletions library/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ LOCAL_SRC_FILES := \
$(CGE_SOURCE)/filters/cgeHalftoneFilter.cpp \
$(CGE_SOURCE)/filters/cgeEdgeFilter.cpp \
$(CGE_SOURCE)/filters/cgeEmbossFilter.cpp \
\
$(CGE_SOURCE)/filters/cgeWaveformFilter.cpp \
\
$(CGE_SOURCE)/filters/cgeCrosshatchFilter.cpp \
$(CGE_SOURCE)/filters/cgeLiquifyFilter.cpp \
$(CGE_SOURCE)/filters/cgeRandomBlurFilter.cpp \
Expand Down
12 changes: 12 additions & 0 deletions library/src/main/jni/cge/common/cgeCommonDefine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,26 @@ GLuint cgeGenTextureWithBuffer(const void* bufferData, GLint w, GLint h, GLenum
assert(w != 0 && h != 0);
GLuint tex;
static const GLenum eArrs[] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA };
static const GLenum eArrsSized8[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
if (channel <= 0 || channel > 4)
return 0;
const GLenum& internalFormat = eArrs[channel - 1];
glActiveTexture(GL_TEXTURE0 + bindID);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
#ifdef ANDROID_NDK
if (bufferData == nullptr && dataFmt == GL_UNSIGNED_BYTE)
{
glTexStorage2D(GL_TEXTURE_2D, 1, eArrsSized8[channel - 1], w, h);
}
else
{
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, channelFmt, dataFmt, bufferData);
}
#else
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, channelFmt, dataFmt, bufferData);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texWrap);
Expand Down
207 changes: 159 additions & 48 deletions library/src/main/jni/cge/common/cgeGLFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,71 +212,182 @@ char* cgeGetScaledBufferInSize(const void* buffer, int& w, int& h, int channel,

/////////////////////////////////////////////////

SharedTexture::SharedTexture(GLuint textureID, int w, int h)
TextureObject::TextureObject(GLuint texture, const CGESizei& size) :
m_texture(texture), m_size(size)
{
m_textureID = textureID;
m_refCount = new int(1);
width = w;
height = h;
CGE_LOG_CODE(
if (m_textureID == 0)
CGE_LOG_ERROR("CGESharedTexture : Invalid TextureID!");
else {
CGE_LOG_INFO("---CGESharedTexture creating, textureID %d, total : %d ###\n", textureID, ++sTextureCount);
});
if (texture == 0 && size.width != 0 && size.height != 0)
{
resize(size.width, size.height);
}
}

TextureObject::TextureObject(TextureObject&& t) noexcept :
m_texture(t.texture()), m_size(t.size())
{
t.cleanup(false);
}

SharedTexture::~SharedTexture()
TextureObject::~TextureObject()
{
if (m_refCount == nullptr)
if (m_texture != 0)
{
CGE_LOG_CODE(
if (m_textureID != 0) {
CGE_LOG_ERROR("SharedTexture : Error occurred!");
});
return;
cleanup(true);
}
}

--*m_refCount;
if (*m_refCount <= 0)
TextureObject& TextureObject::operator=(TextureObject&& t) noexcept
{
if (this == &t)
{
clear();
return *this;
}
CGE_LOG_CODE(
else {
CGE_LOG_INFO("@@@ Texture %d deRef count: %d\n", m_textureID, *m_refCount);
})
m_texture = t.texture();
m_size = t.size();
t.cleanup(false);
return *this;
}

void SharedTexture::forceRelease(bool bDelTexture)
TextureObject& TextureObject::operator=(TextureInfo&& t)
{
assert(m_refCount == nullptr || *m_refCount == 1); // 使用 forceRelease 时 SharedTexture 必须保证只存在一个实例
if (bDelTexture)
glDeleteTextures(1, &m_textureID);
m_textureID = 0;
CGE_DELETE(m_refCount);
width = 0;
height = 0;
CGE_LOG_CODE(
--sTextureCount;);
m_texture = t.name;
m_size = { t.width, t.height };
t.name = 0;
return *this;
}

void SharedTexture::clear()
void TextureObject::cleanup(bool deleteTexture)
{
CGE_LOG_CODE(
if (m_textureID == 0) {
CGE_LOG_ERROR("!!!CGESharedTexture - Invalid TextureID To Release!\n");
} else {
CGE_LOG_INFO("###CGESharedTexture deleting, textureID %d, now total : %d ###\n", m_textureID, --sTextureCount);
});
if (deleteTexture && m_texture != 0)
{
assert(glIsTexture(m_texture));
CGE_DELETE_GL_OBJS(glDeleteTextures, m_texture);
}
m_texture = 0;
m_size.set(0, 0);
}

assert(*m_refCount == 0); // 未知错误
bool TextureObject::resize(int w, int h, const void* buffer, GLenum format)
{
if (m_texture == 0 || m_size.width != w || m_size.height != h || buffer != nullptr)
{
if (w == 0 || h == 0)
{
assert(0 && "TextureObject::resize must not be 0!");
return false;
}

glDeleteTextures(1, &m_textureID);
m_textureID = 0;
int channel;
switch (format)
{
case GL_LUMINANCE:
channel = 1;
break;
case GL_LUMINANCE_ALPHA:
channel = 2;
break;
case GL_RGB:
channel = 3;
break;
case GL_RGBA:
channel = 4;
break;
default:
assert(0);
channel = 4;
break;
}

CGE_DELETE(m_refCount);
width = 0;
height = 0;
if (m_texture == 0)
{
m_texture = cgeGenTextureWithBuffer(buffer, w, h, format, GL_UNSIGNED_BYTE, channel);
m_size.set(w, h);
}
else
{
glBindTexture(GL_TEXTURE_2D, m_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (m_size.width != w || m_size.height != h)
{
m_size.set(w, h);
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, buffer);
}
else
{
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, buffer);
}
}

return true;
}
return false;
}

//////////////

FrameBufferWithTexture::~FrameBufferWithTexture()
{
if (m_renderBuffer != 0)
{
CGE_DELETE_GL_OBJS(glDeleteRenderbuffers, m_renderBuffer);
}
}

void FrameBufferWithTexture::bindTexture2D(GLsizei w, GLsizei h, const void* buffer)
{
if (resize(w, h, buffer))
{
FrameBuffer::bindTexture2D(m_texture);

// auto resize renderbuffer if exist.
if (m_renderBuffer != 0)
{
attachDepthBuffer();
}
assert(checkStatus());
}
else
{
FrameBuffer::bind();
}
}

void FrameBufferWithTexture::attachDepthBuffer()
{
bool shouldCreate = false;

if (m_renderBuffer == 0)
{
shouldCreate = true;
}
else
{
GLint param[2] = { 0, 0 };
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, param);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, param + 1);
shouldCreate = (param[0] != m_size.width || param[1] != m_size.height);
}

if (shouldCreate)
{
if (m_renderBuffer == 0)
glGenRenderbuffers(1, &m_renderBuffer);

glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_size.width, m_size.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer);
}
}

bool FrameBufferWithTexture::checkStatus()
{
GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (ret != GL_FRAMEBUFFER_COMPLETE)
{
CGE_LOG_ERROR("Frame buffer incomplete: %x!\n", ret);
}
return ret == GL_FRAMEBUFFER_COMPLETE;
}

} // namespace CGE
Loading

0 comments on commit 9c81c5d

Please sign in to comment.