Skip to content

Commit 9c81c5d

Browse files
authored
Merge pull request #512 from wysaid/feature/histogram (WaveFormFilter)
WaveFormFilter from #510
2 parents aa6b070 + 9850d74 commit 9c81c5d

File tree

12 files changed

+427
-126
lines changed

12 files changed

+427
-126
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"*.cc": "cpp",
1010
"params.txt": "json",
1111
"CMakeLists*.txt": "cmake",
12-
"__config": "c"
12+
"__config": "c",
13+
"cstdio": "cpp"
1314
}
1415
}

.vscode/tasks.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
// for the documentation about the tasks.json format
44
"version": "2.0.0",
55
"tasks": [
6+
{
7+
"label": "Cleanup workspace (git clean -ffdx)",
8+
"type": "shell",
9+
"command": "git",
10+
"args": [
11+
"clean",
12+
"-ffdx"
13+
],
14+
"options": {
15+
"cwd": "${workspaceFolder}"
16+
},
17+
"group": "build",
18+
"problemMatcher": "$gcc"
19+
},
620
{
721
"label": "[Debug] Build Android Demo",
822
"type": "shell",

cgeDemo/src/main/java/org/wysaid/cgeDemo/MainActivity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class MainActivity extends AppCompatActivity {
3232
public static final String EFFECT_CONFIGS[] = {
3333
"",
3434
"@curve RGB(0,255)(255,0) @style cm mapping0.jpg 80 80 8 3", // ASCII art (字符画效果)
35+
"@style waveform 0.01 0.01 0.4 0.4",
3536
"@beautify face 1 480 640", //Beautify
3637
"@adjust lut edgy_amber.png",
3738
"@adjust lut filmstock.png",

library/src/main/jni/Android.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ LOCAL_SRC_FILES := \
7373
$(CGE_SOURCE)/filters/cgeHalftoneFilter.cpp \
7474
$(CGE_SOURCE)/filters/cgeEdgeFilter.cpp \
7575
$(CGE_SOURCE)/filters/cgeEmbossFilter.cpp \
76+
\
77+
$(CGE_SOURCE)/filters/cgeWaveformFilter.cpp \
78+
\
7679
$(CGE_SOURCE)/filters/cgeCrosshatchFilter.cpp \
7780
$(CGE_SOURCE)/filters/cgeLiquifyFilter.cpp \
7881
$(CGE_SOURCE)/filters/cgeRandomBlurFilter.cpp \

library/src/main/jni/cge/common/cgeCommonDefine.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,14 +300,26 @@ GLuint cgeGenTextureWithBuffer(const void* bufferData, GLint w, GLint h, GLenum
300300
assert(w != 0 && h != 0);
301301
GLuint tex;
302302
static const GLenum eArrs[] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA };
303+
static const GLenum eArrsSized8[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
303304
if (channel <= 0 || channel > 4)
304305
return 0;
305306
const GLenum& internalFormat = eArrs[channel - 1];
306307
glActiveTexture(GL_TEXTURE0 + bindID);
307308
glGenTextures(1, &tex);
308309
glBindTexture(GL_TEXTURE_2D, tex);
309310
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
311+
#ifdef ANDROID_NDK
312+
if (bufferData == nullptr && dataFmt == GL_UNSIGNED_BYTE)
313+
{
314+
glTexStorage2D(GL_TEXTURE_2D, 1, eArrsSized8[channel - 1], w, h);
315+
}
316+
else
317+
{
318+
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, channelFmt, dataFmt, bufferData);
319+
}
320+
#else
310321
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, channelFmt, dataFmt, bufferData);
322+
#endif
311323
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFilter);
312324
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFilter);
313325
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texWrap);

library/src/main/jni/cge/common/cgeGLFunctions.cpp

Lines changed: 159 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -212,71 +212,182 @@ char* cgeGetScaledBufferInSize(const void* buffer, int& w, int& h, int channel,
212212

213213
/////////////////////////////////////////////////
214214

215-
SharedTexture::SharedTexture(GLuint textureID, int w, int h)
215+
TextureObject::TextureObject(GLuint texture, const CGESizei& size) :
216+
m_texture(texture), m_size(size)
216217
{
217-
m_textureID = textureID;
218-
m_refCount = new int(1);
219-
width = w;
220-
height = h;
221-
CGE_LOG_CODE(
222-
if (m_textureID == 0)
223-
CGE_LOG_ERROR("CGESharedTexture : Invalid TextureID!");
224-
else {
225-
CGE_LOG_INFO("---CGESharedTexture creating, textureID %d, total : %d ###\n", textureID, ++sTextureCount);
226-
});
218+
if (texture == 0 && size.width != 0 && size.height != 0)
219+
{
220+
resize(size.width, size.height);
221+
}
222+
}
223+
224+
TextureObject::TextureObject(TextureObject&& t) noexcept :
225+
m_texture(t.texture()), m_size(t.size())
226+
{
227+
t.cleanup(false);
227228
}
228229

229-
SharedTexture::~SharedTexture()
230+
TextureObject::~TextureObject()
230231
{
231-
if (m_refCount == nullptr)
232+
if (m_texture != 0)
232233
{
233-
CGE_LOG_CODE(
234-
if (m_textureID != 0) {
235-
CGE_LOG_ERROR("SharedTexture : Error occurred!");
236-
});
237-
return;
234+
cleanup(true);
238235
}
236+
}
239237

240-
--*m_refCount;
241-
if (*m_refCount <= 0)
238+
TextureObject& TextureObject::operator=(TextureObject&& t) noexcept
239+
{
240+
if (this == &t)
242241
{
243-
clear();
242+
return *this;
244243
}
245-
CGE_LOG_CODE(
246-
else {
247-
CGE_LOG_INFO("@@@ Texture %d deRef count: %d\n", m_textureID, *m_refCount);
248-
})
244+
m_texture = t.texture();
245+
m_size = t.size();
246+
t.cleanup(false);
247+
return *this;
249248
}
250249

251-
void SharedTexture::forceRelease(bool bDelTexture)
250+
TextureObject& TextureObject::operator=(TextureInfo&& t)
252251
{
253-
assert(m_refCount == nullptr || *m_refCount == 1); // 使用 forceRelease 时 SharedTexture 必须保证只存在一个实例
254-
if (bDelTexture)
255-
glDeleteTextures(1, &m_textureID);
256-
m_textureID = 0;
257-
CGE_DELETE(m_refCount);
258-
width = 0;
259-
height = 0;
260-
CGE_LOG_CODE(
261-
--sTextureCount;);
252+
m_texture = t.name;
253+
m_size = { t.width, t.height };
254+
t.name = 0;
255+
return *this;
262256
}
263257

264-
void SharedTexture::clear()
258+
void TextureObject::cleanup(bool deleteTexture)
265259
{
266-
CGE_LOG_CODE(
267-
if (m_textureID == 0) {
268-
CGE_LOG_ERROR("!!!CGESharedTexture - Invalid TextureID To Release!\n");
269-
} else {
270-
CGE_LOG_INFO("###CGESharedTexture deleting, textureID %d, now total : %d ###\n", m_textureID, --sTextureCount);
271-
});
260+
if (deleteTexture && m_texture != 0)
261+
{
262+
assert(glIsTexture(m_texture));
263+
CGE_DELETE_GL_OBJS(glDeleteTextures, m_texture);
264+
}
265+
m_texture = 0;
266+
m_size.set(0, 0);
267+
}
272268

273-
assert(*m_refCount == 0); // 未知错误
269+
bool TextureObject::resize(int w, int h, const void* buffer, GLenum format)
270+
{
271+
if (m_texture == 0 || m_size.width != w || m_size.height != h || buffer != nullptr)
272+
{
273+
if (w == 0 || h == 0)
274+
{
275+
assert(0 && "TextureObject::resize must not be 0!");
276+
return false;
277+
}
274278

275-
glDeleteTextures(1, &m_textureID);
276-
m_textureID = 0;
279+
int channel;
280+
switch (format)
281+
{
282+
case GL_LUMINANCE:
283+
channel = 1;
284+
break;
285+
case GL_LUMINANCE_ALPHA:
286+
channel = 2;
287+
break;
288+
case GL_RGB:
289+
channel = 3;
290+
break;
291+
case GL_RGBA:
292+
channel = 4;
293+
break;
294+
default:
295+
assert(0);
296+
channel = 4;
297+
break;
298+
}
277299

278-
CGE_DELETE(m_refCount);
279-
width = 0;
280-
height = 0;
300+
if (m_texture == 0)
301+
{
302+
m_texture = cgeGenTextureWithBuffer(buffer, w, h, format, GL_UNSIGNED_BYTE, channel);
303+
m_size.set(w, h);
304+
}
305+
else
306+
{
307+
glBindTexture(GL_TEXTURE_2D, m_texture);
308+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
309+
if (m_size.width != w || m_size.height != h)
310+
{
311+
m_size.set(w, h);
312+
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, buffer);
313+
}
314+
else
315+
{
316+
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, buffer);
317+
}
318+
}
319+
320+
return true;
321+
}
322+
return false;
281323
}
324+
325+
//////////////
326+
327+
FrameBufferWithTexture::~FrameBufferWithTexture()
328+
{
329+
if (m_renderBuffer != 0)
330+
{
331+
CGE_DELETE_GL_OBJS(glDeleteRenderbuffers, m_renderBuffer);
332+
}
333+
}
334+
335+
void FrameBufferWithTexture::bindTexture2D(GLsizei w, GLsizei h, const void* buffer)
336+
{
337+
if (resize(w, h, buffer))
338+
{
339+
FrameBuffer::bindTexture2D(m_texture);
340+
341+
// auto resize renderbuffer if exist.
342+
if (m_renderBuffer != 0)
343+
{
344+
attachDepthBuffer();
345+
}
346+
assert(checkStatus());
347+
}
348+
else
349+
{
350+
FrameBuffer::bind();
351+
}
352+
}
353+
354+
void FrameBufferWithTexture::attachDepthBuffer()
355+
{
356+
bool shouldCreate = false;
357+
358+
if (m_renderBuffer == 0)
359+
{
360+
shouldCreate = true;
361+
}
362+
else
363+
{
364+
GLint param[2] = { 0, 0 };
365+
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
366+
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, param);
367+
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, param + 1);
368+
shouldCreate = (param[0] != m_size.width || param[1] != m_size.height);
369+
}
370+
371+
if (shouldCreate)
372+
{
373+
if (m_renderBuffer == 0)
374+
glGenRenderbuffers(1, &m_renderBuffer);
375+
376+
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
377+
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
378+
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_size.width, m_size.height);
379+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer);
380+
}
381+
}
382+
383+
bool FrameBufferWithTexture::checkStatus()
384+
{
385+
GLenum ret = glCheckFramebufferStatus(GL_FRAMEBUFFER);
386+
if (ret != GL_FRAMEBUFFER_COMPLETE)
387+
{
388+
CGE_LOG_ERROR("Frame buffer incomplete: %x!\n", ret);
389+
}
390+
return ret == GL_FRAMEBUFFER_COMPLETE;
391+
}
392+
282393
} // namespace CGE

0 commit comments

Comments
 (0)