Thread: [PyOpenGL-Users] Using framebuffers
Brought to you by:
mcfletch
From: Uğur G. <ugu...@gm...> - 2016-05-28 00:36:00
|
Dear Pyopengl users, I am a beginner who studies OpenGL using PyOpenGL. I want to learn post-processing effects and as the first step I want to be able to render a scene into a FBO and then render that FBO on a quad that cover the whole screen. The python code I am running is this: https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 I combined parts from several tutorials I found on the internet. I suspect that nothing is written to the texture of FBO. Sometimes I have a solid black window, and sometimes there are random noise at some parts of the window (probably this happens when texture buffer is not filled with zeros). I am using Python 3.5.0 numpy==1.11.0 PyOpenGL==3.1.0 PyOpenGL-accelerate==3.1.0 I appreciate if anyone can direct me on how to render on an offscreen framebuffer via PyOpenGL. Regards, ugur |
From: Ian M. <ia...@ge...> - 2016-05-28 00:45:15
|
On Fri, May 27, 2016 at 5:35 PM, Uğur Güney <ugu...@gm...> wrote: > I am a beginner who studies OpenGL using PyOpenGL. I want to learn > post-processing effects and as the first step I want to be able to render a > scene into a FBO and then render that FBO on a quad that cover the whole > screen. > > The python code I am running is this: > https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 I combined > parts from several tutorials I found on the internet. > > I appreciate if anyone can direct me on how to render on an offscreen > framebuffer via PyOpenGL. > As another reference, you may like to consider some of my code. For example, I wrote a Game of Life simulator <http://geometrian.com/programming/projects/index.php?project=Game%20of%20Life> that uses FBOs (it actually uses two IIRC; feedback requires ping-ponging). The code is well-abstracted and reasonably well-tested, so it should serve as a good example. Ian |
From: Uğur G. <ugu...@gm...> - 2016-05-28 17:10:54
|
Thanks for your response and sharing your code! I started looking at your code. You are using from OpenGL.GL.EXT extensions by importing from OpenGL.GL.EXT.framebuffer_object import * I don't know what GL extensions are for in pyopengl, however, I tried to move from non-extension version to EXT versions of GL functions. Unfortunately, just at the beginning, calling the glGenFramebuffersEXT via fbo = glGenFramebuffersEXT(1) generates this error: OpenGL.error.NullFunctionError: Attempt to call an undefined function glGenFramebuffersEXT, check for bool(glGenFramebuffersEXT) before calling Also bool(glGenFramebuffersEXT) return False, whereas bool(glGenFramebuffers) is True. I am using GLFW to generate the window, and my opengl version on OSX is 4.1. You are using pygame for that purpose. Do you think that might be the source of my problem? I wasn't able to "pip install pygame" to install pygame, hence I am hesitant to use it. But I'll try glut and other window generation options to see whether framebuffer's work in them, or whether EXT functions can be called. Does this make sense? PS: By the way, I saw your amazing explanation on why y-axis should mean upwards direction on your website: "Part of the problem was that Blender, like many other modeling softwares use z for up, which is morally wrong (TL;DR: If y is "up" in 2D (clue: it is), then it should also be "up" in 3D; it's demented to redefine it to mean something literally orthogonal to its original meaning when you simply add a new coordinate)" Even though, as a physicist, I am in the "z is up" camp, I appreciated the persuasion power and simplicity of your argument. Also, my girlfriend agrees with you. :-) Have a good day! u On Fri, May 27, 2016 at 8:44 PM, Ian Mallett <ia...@ge...> wrote: > On Fri, May 27, 2016 at 5:35 PM, Uğur Güney <ugu...@gm...> wrote: > >> I am a beginner who studies OpenGL using PyOpenGL. I want to learn >> post-processing effects and as the first step I want to be able to render a >> scene into a FBO and then render that FBO on a quad that cover the whole >> screen. >> >> The python code I am running is this: >> https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 I combined >> parts from several tutorials I found on the internet. >> > > >> I appreciate if anyone can direct me on how to render on an offscreen >> framebuffer via PyOpenGL. >> > > As another reference, you may like to consider some of my code. For > example, I wrote a Game of Life simulator > <http://geometrian.com/programming/projects/index.php?project=Game%20of%20Life> > that uses FBOs (it actually uses two IIRC; feedback requires ping-ponging). > The code is well-abstracted and reasonably well-tested, so it should serve > as a good example. > > Ian > |
From: Uğur G. <ugu...@gm...> - 2016-05-28 19:35:09
|
I did some more research. It looks like the EXT-framebuffer is deprecated: https://www.opengl.org/wiki/Framebuffer_Object#EXT_Framebuffer_object "EXT_Framebuffer_object Warning: This section describes legacy OpenGL APIs that have been removed from core OpenGL 3.1 and above" Hence, I assume that I should be good to go with non-EXT version. I also tried GLUT instead of GLFW, but that didn't solve my problem. I guess the library to create the window is not related to the framebuffer issue. I uploaded a newer version where you can choose between GLFW and GLUT, and between using offscreen framebuffer or not (via global variables WINDOW_LIBRARY and TRY_FRAMEBUFFER) here: https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 This is how I generate the framebuffer. fbo = GLuint() glGenFramebuffers(1, fbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo) texture = GLuint() glGenTextures(1, texture) glBindTexture(GL_TEXTURE_2D, texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIDE, SIDE, 0, GL_RGB, GL_UNSIGNED_BYTE, None) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0) rbo = GLuint() glGenRenderbuffers(1, rbo) glBindRenderbuffer(GL_RENDERBUFFER, rbo) glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SIDE, SIDE) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo) if not glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE: print('framebuffer binding failed') exit() glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0) glBindRenderbuffer(GL_RENDERBUFFER, 0) Best, u On Sat, May 28, 2016 at 1:10 PM, Uğur Güney <ugu...@gm...> wrote: > Thanks for your response and sharing your code! > > I started looking at your code. You are using from OpenGL.GL.EXT > extensions by importing > > from OpenGL.GL.EXT.framebuffer_object import * > > I don't know what GL extensions are for in pyopengl, however, I tried to > move from non-extension version to EXT versions of GL functions. > Unfortunately, just at the beginning, calling the glGenFramebuffersEXT via > > fbo = glGenFramebuffersEXT(1) > > generates this error: > > OpenGL.error.NullFunctionError: Attempt to call an undefined function > glGenFramebuffersEXT, check for bool(glGenFramebuffersEXT) before calling > > Also bool(glGenFramebuffersEXT) return False, > whereas bool(glGenFramebuffers) is True. > > I am using GLFW to generate the window, and my opengl version on OSX is > 4.1. You are using pygame for that purpose. Do you think that might be the > source of my problem? > > I wasn't able to "pip install pygame" to install pygame, hence I am > hesitant to use it. But I'll try glut and other window generation options > to see whether framebuffer's work in them, or whether EXT functions can be > called. Does this make sense? > > PS: > By the way, I saw your amazing explanation on why y-axis should mean > upwards direction on your website: "Part of the problem was that Blender, > like many other modeling softwares use z for up, which is morally wrong > (TL;DR: If y is "up" in 2D (clue: it is), then it should also be "up" in > 3D; it's demented to redefine it to mean something literally orthogonal to > its original meaning when you simply add a new coordinate)" Even though, as > a physicist, I am in the "z is up" camp, I appreciated the persuasion power > and simplicity of your argument. Also, my girlfriend agrees with you. :-) > > Have a good day! > u > > On Fri, May 27, 2016 at 8:44 PM, Ian Mallett <ia...@ge...> wrote: > >> On Fri, May 27, 2016 at 5:35 PM, Uğur Güney <ugu...@gm...> wrote: >> >>> I am a beginner who studies OpenGL using PyOpenGL. I want to learn >>> post-processing effects and as the first step I want to be able to render a >>> scene into a FBO and then render that FBO on a quad that cover the whole >>> screen. >>> >>> The python code I am running is this: >>> https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 I combined >>> parts from several tutorials I found on the internet. >>> >> >> >>> I appreciate if anyone can direct me on how to render on an offscreen >>> framebuffer via PyOpenGL. >>> >> >> As another reference, you may like to consider some of my code. For >> example, I wrote a Game of Life simulator >> <http://geometrian.com/programming/projects/index.php?project=Game%20of%20Life> >> that uses FBOs (it actually uses two IIRC; feedback requires ping-ponging). >> The code is well-abstracted and reasonably well-tested, so it should serve >> as a good example. >> >> Ian >> > > |
From: Ian M. <ia...@ge...> - 2016-05-28 20:32:57
|
> > I am using GLFW to generate the window, and my opengl version on OSX is > 4.1. You are using pygame for that purpose. Do you think that might be the > source of my problem? > I was at the airport, and couldn't answer this immediately. There are two basic ways to get functionality in GL. Either you load it from an extension (which PyOpenGL handily does for you) or you use the core API. The "Right Thing" is to use the core API if available, with a fallback to the extension, with a fallback to a different algorithm. In practice, people commonly pick one and go with it. I picked the extension, because it's more widely compatible than core, but still not giving up on the functionality entirely. The reason it didn't work for you is probably that GLFW created a forward-compatible-only GL context (which removes older extensions). If you instead request an ordinary context, the FBOs extension should work fine. OTOH, most computers nowadays, even Macs, support a high-enough core GL for the non-extension FBOs, so it sortof doesn't matter whether you pick the extension or the core. I wasn't able to "pip install pygame" to install pygame, hence I am > hesitant to use it. > PyGame is a very good software package, especially for low-perf 2D drawing. It's how I got started in graphics programming and I recommend it still. It is unfortunate that distributions haven't been made available, and this is a source of active . . . consternation . . . on the PyGame list. Unofficial pip wheels can be found here <http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame>, or you can use the (somewhat outdated) installers on the site <http://www.pygame.org/download.shtml>. By the way, I saw your amazing explanation on why y-axis should mean > upwards direction on your website: "Part of the problem was that Blender, > like many other modeling softwares use z for up, which is morally wrong > (TL;DR: If y is "up" in 2D (clue: it is), then it should also be "up" in > 3D; it's demented to redefine it to mean something literally orthogonal to > its original meaning when you simply add a new coordinate)" Even though, as > a physicist, I am in the "z is up" camp, I appreciated the persuasion power > and simplicity of your argument. Also, my girlfriend agrees with you. :-) > I'm glad you enjoyed it <http://geometrian.com/programming/tutorials/graphicstips/zaxis/index.php>! I must say, though, that it's unfortunately not one of my better argumentative pieces. In fact, it's probably my worst--even counting my incredibly poorly received rant on TTD. Rewriting it to be more coherent is on my (long) todo list. Ian |
From: Uğur G. <ugu...@gm...> - 2016-05-29 14:16:41
|
Hi Ian, There are two basic ways to get functionality in GL. Either you load it > from an extension (which PyOpenGL handily does for you) or you use the core > API. The "Right Thing" is to use the core API if available, with a fallback > to the extension, with a fallback to a different algorithm. In practice, > people commonly pick one and go with it. I picked the extension, because > it's more widely compatible than core, but still not giving up on the > functionality entirely. > Thanks for sharing your wisdom with me! If I'll ever write a project for public I'll go with this "use the core if available and fallback to extensions if necessary" method. For now I'll stick with the core one for my study projects. PyGame is a very good software package, especially for low-perf 2D drawing. > It's how I got started in graphics programming and I recommend it still. It > is unfortunate that distributions haven't been made available, and this is > a source of active . . . consternation . . . on the PyGame list. Unofficial > pip wheels can be found here > <http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame>, or you can use the > (somewhat outdated) installers on the site > <http://www.pygame.org/download.shtml>. > Thanks for pointing out pip wheels for pygame. This way I'll be able to try it out. ^_^ Finally, I succeeded to do post-processing using an FBO! Here are screenshots of before and after the colored triange's pixels are inverted: http://imgur.com/a/P2wxt I removed all of the abstractions/classes in your code related to framebuffer and texture generation and pasted to my project and it worked! Then I compared your code with mine and found the source of the problem. When I generate the texture ID, if I use this expressions texture = GLuint() glGenTextures(1, texture) nothing is rendered on the texture. Generating texture ID this way works fine: texture = glGenTextures(1) I don't know whether this is a feature or a bug. :-) I was going with the former way (creating a GLuint object first, and manipulating it in the glGenX function by giving it as the second argument) because it looks more like the C/C++ OpenGL code I find on the Internet. And it works fine with glGenVertexArrays, glGenBuffers, glGenFramebuffers, and glGenRenderbuffers but not with glGenTextures. I updated the code to demonstrate this behavior: https://gist.github.com/vug/2c7953d5fdf750c727af249ded3e9018 Have a good day! u |