Rendering off-screen

I am new to OpenGL. I am trying to use pyopengl to do some graphics, but I find OpenGL very complicated and frightening. I am OK with replies in C++, and I don’t think this is specific to Python OpenGL. Also, I am doing 2D graphics.

Here is a description of what I think I want to do. Terminology may be misunderstood on my side. The TLDR of it is that I want to draw graphics off screen, for caching, and then later copy into the window.

Help to implement any of following functions would very useful to me:

def open_window() :

	# Initialize the window and its framebuffer object.


def close_window() :

	# Clean up everything.


def render_offscreen( height, width, draw_function ) :

	# Initialize a new framebuffer object.

	draw_function()	# Do the drawing.

	# The drawing can involve pasting other renderbuffers into current framebuffer object using the draw_from_renderbuffer mentioned next.

	# Clean up framebuffer, but keep the renderbuffer.

	return renderbuffer


def draw_from_renderbuffer( renderbuffer, x, y, width, height ) :

	# Draw renderbuffer into the current framebuffer object at x, y with given width and height.


def renderbuffer_to_ram( renderbuffer ) :

	# If renderbuffer is in VRAM, move it to RAM, and free the VRAM it occupied.

	# Wait for transfere to finnish.

return width, height, data


def renderbuffer_to_vram( width, height, data ) :

	# If renderbuffer is in RAM, move it to VRAM, and free the RAM it occupied.

	# Wait for transfer to finish.

	return renderbuffer

I am aware that I may need to render to a texture instead of a renderbuffer. I have tried to do this, but with no luck. I followed some tutorials and got the following to attach a texture to a framebuffer object:

texture = glGenTextures( 1 )
glBindTexture( GL_TEXTURE_2D, texture )
glTexStorage2D( GL_TEXTURE_2D, 1, GL_RGBA, w, h )	# This fails, with 'invalid argument'.
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texturebuffer ) 

I am sorry if this is trivial stuff that I should be able to figure out my self ( and also, it is Python and not C++ ), but I need this for a project. I need it a lot!

You only need to use a texture if you want to perform additional rendering using the rendered image as a texture. Whether that’s the case depends exactly what draw_from_renderbuffer needs to do. If it’s simply pasting a rectangular region from a renderbuffer, you can use glBlitFrameBuffer. The only form of “processing” which is supported by that function is scaling (with either nearest-neighbour sampling or linear sampling). If you need any other processing (e.g. blending, logic operations, alpha test), then you’ll need to render into a texture then render a textured quad. That makes the entire OpenGL rendering pipeline (including shaders) available.

“Invalid argument” isn’t an OpenGL error. The Python error will include the actual OpenGL error type, which is probably GL_INVALID_ENUM due to using GL_RGBA as the internal format (you need to use a sized format, e.g. GL_RGBA8).

Right. With the caveat that the GL man pages aren’t the GL spec…

glTexStorage2D():

I think I would probably question the source you got that from.

glFramebufferTexture2D() attaches a 2D texture to a buffer of a framebuffer. GL_RENDERBUFFER is never a valid enum which can be provided to its 3rd parameter. This must be a texture type enum. What you likely want here is GL_TEXTURE_2D.

Also, 4th arg should probably be texture, not texturebuffer, since that’s the 2D texture you just allocated storage (texels) for and presumably want to draw to with that FBO.

See:

We’ve all been there! Push through that and resolve to do more reading and ask questions here when confused. Don’t just stress about it. From a user’s perspective, it’s really not that deep!

And take solace in the fact that OpenGL is like a tricycle compared to newer GPU APIs. You don’t even have to balance! It’s constantly trying to help you out when you do something wrong (checking for errors, etc.), and it simplifies a lot of the inherent complexity associated with talking with and rendering on a GPU.

I’m opting for render to texture, since it is more flexible. I’ve gotten render to texture and save to PIL image to work. Now I’m reading up on texturing a quad. I think the big challenge is to get familiar enough with OpenGL to make sense of the documentation.

I got this to work:

texturebuffer = glGenTextures( 1 )
glBindTexture( GL_TEXTURE_2D, texturebuffer )
glTexStorage2D( GL_TEXTURE_2D, 1, GL_RGBA8, w, h )
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texturebuffer, 0 ) |