- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在尝试在 OpenGL 图像处理算法中实现。
我想连续使用多个着色器以执行多个过滤器(Sobel Gaussian,...)。我知道要做到这一点,我必须借助 FBO 渲染到纹理。我读了很多关于它的东西,并写了一个代码。但我没有得到预期的结果。
目前,我只是尝试使用两个着色器。所以,我有一个原始图像,它是我的第一个着色器的输入。然后,我想将着色器的输出渲染为纹理,然后将其作为我的第二个着色器的输入(乒乓技术)。最后,我想显示第二个着色器的输出。
但结果是,我得到了原始图像。
我的代码如下:
/******************** Shaders Function *******************************/
void setupShaders(char *vert, char *frag, GLuint p) {
GLuint v, f;
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead(vert);
fs = textFileRead(frag);
const char * ff = fs;
const char * vv = vs;
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glLinkProgram(p);
glUseProgram(p);
}
/******************** Texture Function ***********************************/
void setupTexture(void) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
/******************** Quad Drawing Function ******************************/
void ShaderDraw(void){
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, height, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(width, height, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(width, height, 0.0);
glEnd();
}
/******************** Initialization Function ***************************/
void init(void)
{
//Checking GLSL
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
exit(1);
}
// Init
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
}
/******************** Display Function **********************************/
void display(void)
{
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-4.0, -4.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-4.0, 4.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(4.0, 4.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(4.0, -4.0, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
/******************** Reshape Function *********************************/
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -7.0);
}
/******************** Main Function *************************************/
int main(int argc, char** argv)
{
// Glut Initialisation
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
// Window Generation
glutInitWindowSize(1000,800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Night Vision");
// Initialisation Function
init();
// Downloading Image
data = cLoadBitmap("lena.bmp", &height, &width);
checkGLErrors ("Downloading Image");
int read_tex = 0;
int write_tex = 1;
// Generating Texture
glEnable(GL_TEXTURE_2D);
glGenTextures(2, texImg);
// Init Texture0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
checkGLErrors ("InitTexture0");
// Init Texture1
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkGLErrors ("InitTexture1");
// Setup Framebuffer Object
GLuint fb;
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
checkGLErrors ("Framebuffer->fb");
GLenum att_point[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[read_tex], GL_TEXTURE_2D, texImg[read_tex], 0);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[write_tex], GL_TEXTURE_2D, texImg[write_tex], 0);
checkFramebufferStatus();
//set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shader
setupShaders("filter.vert", "sobel_filter_3.frag", p1);
checkGLErrors ("Shaders 1");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
GLuint texLoc;
texLoc = glGetUniformLocation(p1,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// swap the buffers
read_tex = 1;
write_tex = 0;
// Delete program 1
glDeleteProgram(p1);
// set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shaders
setupShaders("filter.vert", "gaussian7.frag", p2);
checkGLErrors ("Shaders 2");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
texLoc = glGetUniformLocation(p2,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// Delete program 2 & disable the FBO
glDeleteProgram(p2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glUseProgram(0);
// Bind the texture to display
glBindTexture(GL_TEXTURE_2D,texImg[0]);
// Glut Functions: Display, Reshape, Keyboard
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
// Calling Main
glutMainLoop();
return 0;
}
有人知道哪里出了问题吗???
最佳答案
您正在尝试同时使用 FBO 作为渲染源和渲染目标。 Afaik 你不能那样做 - 如果你想使用绑定(bind)到 FBO 的纹理作为渲染源,你需要取消绑定(bind) FBO(通过调用 glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
或通过绑定(bind)另一个 FBO ).
看起来您正试图通过使用您的起始纹理作为 FBO 的颜色缓冲区来以这种方式节省内存。我不确定这是否可行。
所以你可能想尝试创建两个 FBO,每个都有一个颜色缓冲区,然后交换整个 FBO,然后开始将你的纹理渲染到第一个 FBO。此外,不要将起始纹理用作 FBO 的颜色缓冲区,而是为每个 FBO 创建一个单独的颜色缓冲区。
在将纹理附加到 FBO 之前,您也不需要将纹理绑定(bind)到纹理单元。
关于c++ - GPU 上的图像处理 - 滤镜的连续着色器 - FBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3215245/
我有以下 OpenGL 设置来解决帧缓冲区问题: 我将立方体渲染到帧缓冲区中。 我使用此帧缓冲区中的目标纹理绘制带纹理的四边形,它在我的视口(viewport)中显示立方体。 当流程的两个阶段都在同一
我一直在研究乒乓球着色,并认为在我上一个问题之后我已经破解了它。但是,随着对着色器的进一步了解,看起来虽然我能够在 FBO A 和 FBO B 上运行着色器,但 A 的输出并未用作 B 的源。换句话说
平台是iPhone OpenGL ES 2.0 框架已经创建了一个带有渲染缓冲区的主fbo,因为它是颜色附件。 我有自己的 fbo ,其中 texture2D 作为颜色附件。我想将主 fbo 的内容复
我有一个应用程序需要执行以下操作: 将纹理从磁盘加载到 GL 纹理 在其上运行图像过滤器(通过 FBO 将其渲染到另一个纹理上) 在屏幕上显示生成的纹理 我有那么多工作。 接下来,我希望能够将第 2
我正在尝试创建一个 FBO 来绘制 3D 场景,并创建另一个 FBO 来绘制 HUD。然后,我尝试通过将 3D 场景 block 传输到默认 FBO,然后将 HUD block 传输到默认 FBO,来
除了默认的帧缓冲区之外,在什么情况下我希望在 OpenGL FBO 中添加渲染缓冲区附件而不是纹理附件?因为,纹理附件似乎更加通用。 最佳答案 纹理为您提供更多功能(采样!、格式多样性),因此更有可能
我正在考虑重构我的渲染代码的很大一部分,然后我想到了一个问题:是否可以使用帧缓冲区对象中的多个颜色附件渲染到屏幕和纹理?尽管它有许多有用的应用程序,但我找不到任何信息是否可能。我想将我的纹理作为颜色a
我尝试在 OpenGL 中使用 FBO 的模板缓冲区,但无法正常工作。我将深度和模板目标的 depth24_stencil8 纹理绑定(bind)到 FBO。作为一个简单的测试,我尝试了: /* En
到目前为止,在对自定义 FBO 进行深度测试时,我一直在使用渲染缓冲区。现在我需要用深度纹理替换它们(因为我需要在着色器中读取它)。我正在查看不同的来源,如 here并看到 GL_FLOAT 用作数据
我现在正在尝试实现阴影贴图几天,我想我开始看到手头的真正问题:我有一个附加了深度纹理的 FBO,用于阴影贴图的光 channel ,但是其中没有任何内容被渲染。甚至没有硬编码值。 我已经仔细检查了程序
我正在尝试关注 ThinMatrix's water tutorial 。为此,我需要创建一个 FBO 并将其渲染为纹理。 但是正如您所看到的,水是完全黑色的: 我正在使用source code pr
我正在使用 A FBO 捕捉四边形表面上方的反射。前提是将相机移动到水面下然后渲染场景到fbo,然后恢复到原来的观看位置,像这样: WaterFrameBuffer fbos; Water test(
我有一个按以下方式创建的 FBO: glGenRenderbuffers(1, &m_depthStencilBuffer); glBindRenderbuffer(GL_RENDERBUFFER,
我无法使用 glreadpixels 函数从深度纹理读取正确的深度值。 FBO 状态完成。其他渲染目标在传输到另一个 FBO 后看起来也很好。 代码片段: // Create the FBO
我正在尝试将多采样场景渲染为纹理,这是我正在使用的代码。我得到一个黑屏。我在 init 结束时检查了 fbo 的完整性,他们报告两个 fbo 都是完整的。 void init_rendered_FBO
我读到在分层渲染中,我们创建了一个 2D 纹理数组(GL_TEXTURE_2D_ARRAY): glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTU
我在网上看到了很多示例(for example),它们执行以下操作 创建和绑定(bind) FBO 创建和绑定(bind)缓冲区 (纹理、渲染、深度、模板) 然后,解除绑定(bind)缓冲区 要使用
我想使用片段着色器输出到 FBO,然后将其纹理附件绘制到默认帧缓冲区。最终,我希望能够输出到一个 FBO,然后使用另一个着色器将其传递给另一个 FBO,依此类推。但我认为让它在默认帧缓冲区上工作是一个
在我的渲染器中,我在多重采样的 FBO 上生成抗锯齿场景,该场景被位 block 传输到颜色附件为纹理的 FBO。然后在渲染到帧缓冲区期间读取纹理。 我想更新它,以便获得 Gamma 正确的结果。使用
我想将图像处理 OpenGL 着色器程序的输出保存到图像文件中,并在屏幕上显示结果。我知道如何使用 glReadPixels() 保存窗口帧缓冲区。然而,屏幕的分辨率小于图像的尺寸。 如果我渲染到 F
我是一名优秀的程序员,十分优秀!