带有两个立方体的图像是使用BLIT Call - Test Code
带有一个多维数据集的图像是不使用BLIT CALL - 测试代码
民间, 请按照附图和&代码如下..
过去2天挣扎于此......
在下面的代码中使用FBO时遇到问题,我可以附加&成功渲染到FBo,但有些人不能在同一个程序中使用它作为纹理(颜色和深度缓冲区),渲染到FBO后调用MY glReadpixel向我显示所有Zero的数据......
当生成FBO(颜色,深度)用于GLSL着色器代码时,从Draw2()函数调用该函数会显示没有纹理的混合白色立方体。
请建议......,下面是完整的代码...,我正在创建一个FBO&使用2个着色器一个用于Normal渲染&另一个使用颜色&来自FBO的深度已经处理过了..
这是我的SHADER代码
init_gl()
{
此片段着色器代码用于在draw()下的程序中使用的正常渲染
static const char *fragment_shader_source =
"precision mediump float; \n"
" \n"
"varying vec4 vVaryingColor; \n"
" \n"
"void main() \n"
"{ \n"
" gl_FragColor = vVaryingColor; \n"
"} \n";
此片段着色器代码在draw2()
下的Program2中使用 static const char *fragment_shader_source2 =
"precision mediump float; \n"
" \n"
"varying vec4 vVaryingColor; \n"
"uniform sampler2D color; \n"
"uniform sampler2D depth; \n"
" \n"
"void main() \n"
"{ \n"
"float r = pow(texture2D(color, gl_FragCoord.xy / vec2(256, 256)).a, 128.0); \n"
"float g = texture2D(depth, gl_FragCoord.xy / vec2(256, 256)).a;\n"
"float b = pow(texture2D(depth, gl_FragCoord.xy / vec2(256, 256)).a, 128.0); \n"
"gl_FragColor = vec4(r, g, b, 1.); \n"
"} \n";
我在FBO上的第一张图
static void draw(uint32_t i)
{
EGL_CHECK(glEnable(GL_DEPTH_TEST));
glEnable(GL_TEXTURE_2D);
EGL_CHECK(glDepthFunc(GL_ALWAYS));
EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fboInfo.id));
EGL_CHECK(glUseProgram(program));
//CUBE DRAWING
在此处执行Read Pixel,它返回所有零
GLubyte *pixels = malloc(4 * 256 * 256);
EGL_CHECK(glReadBuffer(GL_COLOR_ATTACHMENT0));
EGL_CHECK(glReadPixels(0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
//**TO TEST my FBO , IF ITS HAVING SOME RENDER DATA**
EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboInfo.id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
//TEST CODE ONLY
glBindTexture(GL_TEXTURE_2D, fboInfo.id);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
draw2(i);
}
没有FBO的第二次绘图(但这使用可以访问FBO数据颜色,深度的FRAG SHADER)
static void draw2(uint32_t i)
{
glUseProgram(program2);
//Draw Same Kind of Cube , Which we draw in draw() function
}
这些是创建FBO(颜色,深度)
的功能 GLuint createTexture2D(const int w, const int h, GLint internalFormat, GLenum format, GLenum type)
{
GLuint textureIdX;
EGL_CHECK(glGenTextures(1, &textureIdX));
EGL_CHECK(glBindTexture(GL_TEXTURE_2D, textureIdX));
EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
EGL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
if (GL_DEPTH_COMPONENT == format) {
EGL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE));
EGL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY));
}
EGL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, format, type, 0));
EGL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
return textureIdX;
}
int createFBO(void)
{
int result = 0;
unsigned int fb = 0;
fboInfo.color = createTexture2D(WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
fboInfo.depth = createTexture2D(WINDOW_WIDTH, WINDOW_HEIGHT, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_FLOAT);
EGL_CHECK(glGenFramebuffers(1, &fboInfo.id));
EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fboInfo.id));
EGL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboInfo.color, 0));
EGL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboInfo.depth, 0));
int data = EGL_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER));
if (GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
printf("FBO %d set up successfully\n", fboInfo.id);
result = 1;
}
else {
printf("FBO %d NOT set up properly!\n", fboInfo.id);
}
EGL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
return result;
}
这就是我的FBO Struct看起来像
typedef struct {
GLuint id;
GLuint color;
GLuint depth;
}FBOInfo;
我的主要功能在下面我创建FBO&然后调用我的绘图功能&交换缓冲区..
unsigned long i = 0;
int ret = init_gl();
ret = createFBO();
draw(i);
EGL_CHECK(eglSwapBuffers(eglDisplay, eglSurface));
答案 0 :(得分:1)
由于这是相当多的代码,并且您建议问题在于FBO设置,我专注于该部分。我确实发现了设置附件的代码部分中的一个严重问题:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fboInfo.depth, 0);
如果在此之后调用glGetError()
,则会看到返回错误,因为GL_RENDERBUFFER
不是第3个参数的有效值。唯一有效的参数是GL_TEXTURE_2D
和GL_TEXTURE_CUBE_MAP_*
值。在这种情况下,您必须使用GL_TEXTURE_2D
。
如果你从不将它用作纹理,那么使用渲染缓冲区实际上可能会更好。但要做到这一点,你必须使用所有相应的调用:
glGenRenderbuffers
创建ID。glBindRenderbuffer
绑定。glRenderbufferStorage
分配。glFramebufferRenderbuffer