Low-Level Render to Texture¶
Render to Texture Basics
In Panda3D, rendering to a texture consists of three basic steps:
- Create a hidden window (class GraphicsBuffer).
- Render into the hidden window.
- Transfer the contents of the hidden window into a texture.
When I say “transfer” the contents of a window into a texture, I don’t necessarily mean “copy.” There are other ways to transfer the contents of a window into a texture that may be faster. For example, if the OpenGL implementation supports the ARB_pbuffers extension, then the transfer might be achieved using wglBindTexImageARB. The Panda user does not need to worry about how the transfer is done. It is only important that you know that Panda will use the fastest means available to transfer the contents of the window into the texture.
To generalize that a bit, although render-to-texture is usually done with a hidden window (class GraphicsBuffer), it can also be done with a visible window (class GraphicsWindow). You can transfer the contents of any window, hidden or not, into a texture. That’s potentially useful - for example, you can transfer the contents of the main window into a texture, which you can then use when rendering the next frame. This can be used to create accumulation-buffer-like effects without an accumulation buffer.
The Simple API: makeTextureBuffer
Here is a short snippet of code that creates a hidden window, creates a camera that renders into that window, and creates a scene graph for that camera:
mybuffer = base.win.makeTextureBuffer("My Buffer", 512, 512)
mytexture = mybuffer.getTexture()
mybuffer.setSort(-100)
mycamera = base.makeCamera(mybuffer)
myscene = NodePath("My Scene")
mycamera.reparentTo(myscene)
The makeTextureBuffer is the simple
interface to the render-to-texture functionality. It creates a new hidden
window (usually a GraphicsBuffer), creates a texture to render into, and
connects the texture to the hidden window. The (512, 512) in the function call
specifies the size of the hidden window and texture. Of course, you need to
use a power-of-two size. The
getTexture method retrieves the
texture, which will be rendered into every frame.
The setSort method sets a
window’s sort order. This controls the order in which panda renders the
various windows. The main window’s sort order is zero. By setting the sort
order of mybuffer to a negative number, we ensure that mybuffer will be
rendered first. That, in turn, ensures that mytexture will be ready to use by
the time that the main window is rendered.
The new hidden window is not automatically connected to the scene graph. In this example, we create a separate scene graph rooted at myscene, create a camera to view that scene graph, and connect the camera to mybuffer.
The function makeTextureBuffer usually
creates a GraphicsBuffer (hidden window), but if the video card is not
powerful enough to create an offscreen window, it may not be able to do so. In
that case, makeTextureBuffer will create
a parasiteBuffer instead. A parasite
buffer is primarily a trick to emulate a GraphicsBuffer on video cards that
are less powerful. The trick is this: instead of rendering to an offscreen
window and then transferring the data into a texture, panda renders into the
main window and then copies the data into the texture. The limitations of this
trick are self-evident. First, it garbles the contents of the main window.
This is usually no big deal, since the main window is usually cleared and
rendered from scratch every frame anyway. The other problem with this trick is
that it fails if the main window is smaller than the desired texture. Since
neither of these problems is common in practice,
makeTextureBuffer will use parasite
buffers transparently if GraphicsBuffers are not available.
There is a debugging mode in which
makeTextureBuffer will create a visible
window (class GraphicsWindow) instead of a hidden one (class GraphicsBuffer).
To enable this debugging mode, set the boolean variable “show-buffers #t” in
your panda configuration file.
The Advanced API: addRenderTexture
The simple API is convenient, but there are a few things it can not do. For instance, it can not:
- Copy the main window into a texture.
- Copy the Z-buffer into a depth texture.
- Copy the window into a texture, but not every frame.
- Limit or force the use of Parasite buffers.
If you need this level of control, you need to use a lower-level API. The documentation for the lower-level API is not currently written. However, several of the Sample Programs use the lower-level API.
Incomplete Section¶
Note: this section is incomplete. It will be updated soon.