From 3fdd673aae3e4af008be8b4e71f416c9e7a5016e Mon Sep 17 00:00:00 2001 From: Tungstend Date: Thu, 6 Feb 2025 01:43:21 +0800 Subject: [PATCH] fix glDrawBuffers --- app/src/main/cpp/CMakeLists.txt | 1 + app/src/main/cpp/gl/drawing.c | 18 +++++++++- app/src/main/cpp/gl/framebuffer.c | 57 +++++++++++++++++++++++++++++++ app/src/main/cpp/gl/framebuffer.h | 31 +++++++++++++++++ app/src/main/cpp/gl/gl_native.c | 4 +-- 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 app/src/main/cpp/gl/framebuffer.c create mode 100644 app/src/main/cpp/gl/framebuffer.h diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 2a1e4ad..e64823a 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -30,6 +30,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED gl/log.c gl/program.c gl/shader.c + gl/framebuffer.c gl/texture.cpp gl/drawing.c gl/mg.c diff --git a/app/src/main/cpp/gl/drawing.c b/app/src/main/cpp/gl/drawing.c index 5e4fb93..e738e25 100644 --- a/app/src/main/cpp/gl/drawing.c +++ b/app/src/main/cpp/gl/drawing.c @@ -4,6 +4,7 @@ #include "drawing.h" #include "buffer.h" +#include "framebuffer.h" #define DEBUG 0 @@ -84,8 +85,23 @@ void glDrawBuffers(GLsizei n, const GLenum *bufs) { LOG() LOG_D("glDrawBuffers(%d, %p), [0]=0x%x", n, bufs, n ? bufs[0] : 0) + + GLenum new_bufs[n]; + + for (int i = 0; i < n; i++) { + if (bufs[i] >= GL_COLOR_ATTACHMENT0 && bufs <= GL_COLOR_ATTACHMENT0 + getMaxDrawBuffers()) { + GLenum target_attachment = GL_COLOR_ATTACHMENT0 + i; + new_bufs[i] = target_attachment; + if (bufs[i] == target_attachment) + continue; + rebind_framebuffer(bufs[i], target_attachment); + } else { + new_bufs[i] = bufs[i]; + } + } + LOAD_GLES(glDrawBuffers, void, GLsizei n, const GLenum *bufs) - gles_glDrawBuffers(n, bufs); + gles_glDrawBuffers(n, new_bufs); CHECK_GL_ERROR } \ No newline at end of file diff --git a/app/src/main/cpp/gl/framebuffer.c b/app/src/main/cpp/gl/framebuffer.c new file mode 100644 index 0000000..0b8fa44 --- /dev/null +++ b/app/src/main/cpp/gl/framebuffer.c @@ -0,0 +1,57 @@ +// +// Created by hanji on 2025/2/6. +// + +#include "framebuffer.h" +#include "log.h" + +#define DEBUG 0 + +struct framebuffer_t* bound_framebuffer; + +GLint MAX_DRAW_BUFFERS = 0; + +GLint getMaxDrawBuffers() { + if (!MAX_DRAW_BUFFERS) { + LOAD_GLES(glGetIntegerv, void, GLenum pname, GLint *params) + gles_glGetIntegerv(GL_MAX_DRAW_BUFFERS, &MAX_DRAW_BUFFERS); + } + return MAX_DRAW_BUFFERS; +} + +void rebind_framebuffer(GLenum old_attachment, GLenum target_attachment) { + struct attachment_t attachment = bound_framebuffer->attachment[old_attachment - GL_COLOR_ATTACHMENT0]; + + LOAD_GLES(glFramebufferTexture2D, void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + gles_glFramebufferTexture2D(bound_framebuffer->target, target_attachment, attachment.textarget, attachment.texture, attachment.level); +} + +void glBindFramebuffer(GLenum target, GLuint framebuffer) { + LOG() + + LOG_D("glBindFramebuffer(0x%x, %d)", target, framebuffer) + + LOAD_GLES(glBindFramebuffer, void, GLenum target, GLuint framebuffer) + gles_glBindFramebuffer(target, framebuffer); + + bound_framebuffer = NULL; + bound_framebuffer = malloc(sizeof(struct framebuffer_t)); + bound_framebuffer->target = target; + + CHECK_GL_ERROR +} + +void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + LOG() + + LOG_D("glFramebufferTexture2D(0x%x, 0x%x, 0x%x, %d, %d)", target, attachment, textarget, texture, level) + + bound_framebuffer->attachment[attachment - GL_COLOR_ATTACHMENT0].textarget = textarget; + bound_framebuffer->attachment[attachment - GL_COLOR_ATTACHMENT0].texture = texture; + bound_framebuffer->attachment[attachment - GL_COLOR_ATTACHMENT0].level = level; + + LOAD_GLES(glFramebufferTexture2D, void, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + gles_glFramebufferTexture2D(target, attachment, textarget, texture, level); + + CHECK_GL_ERROR +} \ No newline at end of file diff --git a/app/src/main/cpp/gl/framebuffer.h b/app/src/main/cpp/gl/framebuffer.h new file mode 100644 index 0000000..3960ed1 --- /dev/null +++ b/app/src/main/cpp/gl/framebuffer.h @@ -0,0 +1,31 @@ +// +// Created by hanji on 2025/2/6. +// + +#ifndef MOBILEGLUES_FRAMEBUFFER_H +#define MOBILEGLUES_FRAMEBUFFER_H + +#include "gl.h" + +struct attachment_t { + GLenum textarget; + GLuint texture; + GLint level; +}; + +struct framebuffer_t { + GLenum target; + struct attachment_t attachment[]; +}; + +extern struct framebuffer_t* bound_framebuffer; + +GLint getMaxDrawBuffers(); + +void rebind_framebuffer(GLenum old_attachment, GLenum target_attachment); + +GLAPI GLAPIENTRY void glBindFramebuffer(GLenum target, GLuint framebuffer); + +GLAPI GLAPIENTRY void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + +#endif //MOBILEGLUES_FRAMEBUFFER_H diff --git a/app/src/main/cpp/gl/gl_native.c b/app/src/main/cpp/gl/gl_native.c index 08dda26..8ebc8b3 100644 --- a/app/src/main/cpp/gl/gl_native.c +++ b/app/src/main/cpp/gl/gl_native.c @@ -17,7 +17,7 @@ NATIVE_FUNCTION_HEAD(void, glActiveTexture, GLenum texture) NATIVE_FUNCTION_END_ NATIVE_FUNCTION_HEAD(void, glAttachShader, GLuint program, GLuint shader) NATIVE_FUNCTION_END_NO_RETURN(void, glAttachShader, program,shader) NATIVE_FUNCTION_HEAD(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar *name) NATIVE_FUNCTION_END_NO_RETURN(void, glBindAttribLocation, program,index,name) NATIVE_FUNCTION_HEAD(void, glBindBuffer, GLenum target, GLuint buffer) NATIVE_FUNCTION_END_NO_RETURN(void, glBindBuffer, target,buffer) -NATIVE_FUNCTION_HEAD(void, glBindFramebuffer, GLenum target, GLuint framebuffer) NATIVE_FUNCTION_END_NO_RETURN(void, glBindFramebuffer, target,framebuffer) +//NATIVE_FUNCTION_HEAD(void, glBindFramebuffer, GLenum target, GLuint framebuffer) NATIVE_FUNCTION_END_NO_RETURN(void, glBindFramebuffer, target,framebuffer) NATIVE_FUNCTION_HEAD(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) NATIVE_FUNCTION_END_NO_RETURN(void, glBindRenderbuffer, target,renderbuffer) //NATIVE_FUNCTION_HEAD(void, glBindTexture, GLenum target, GLuint texture) NATIVE_FUNCTION_END_NO_RETURN(void, glBindTexture, target,texture) NATIVE_FUNCTION_HEAD(void, glBlendColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) NATIVE_FUNCTION_END_NO_RETURN(void, glBlendColor, red,green,blue,alpha) @@ -60,7 +60,7 @@ NATIVE_FUNCTION_HEAD(void, glEnableVertexAttribArray, GLuint index) NATIVE_FUNCT NATIVE_FUNCTION_HEAD(void, glFinish) NATIVE_FUNCTION_END_NO_RETURN(void, glFinish) NATIVE_FUNCTION_HEAD(void, glFlush) NATIVE_FUNCTION_END_NO_RETURN(void, glFlush) NATIVE_FUNCTION_HEAD(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) NATIVE_FUNCTION_END_NO_RETURN(void, glFramebufferRenderbuffer, target,attachment,renderbuffertarget,renderbuffer) -NATIVE_FUNCTION_HEAD(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) NATIVE_FUNCTION_END_NO_RETURN(void, glFramebufferTexture2D, target,attachment,textarget,texture,level) +//NATIVE_FUNCTION_HEAD(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) NATIVE_FUNCTION_END_NO_RETURN(void, glFramebufferTexture2D, target,attachment,textarget,texture,level) NATIVE_FUNCTION_HEAD(void, glFrontFace, GLenum mode) NATIVE_FUNCTION_END_NO_RETURN(void, glFrontFace, mode) NATIVE_FUNCTION_HEAD(void, glGenBuffers, GLsizei n, GLuint *buffers) NATIVE_FUNCTION_END_NO_RETURN(void, glGenBuffers, n,buffers) NATIVE_FUNCTION_HEAD(void, glGenerateMipmap, GLenum target) NATIVE_FUNCTION_END_NO_RETURN(void, glGenerateMipmap, target)