I created some working demo out of the code-snipplet above. It may be of use to anyone trying to implement this in his application, or those who just want to try it out.
You have to zoom out before you can see something. (as in pview)
v toggles the color picking buffer
@ treeform: while this is true, in-panda texture painting can be quite intresting. for example to paint road, textures, or heigh of a terrain itself directly in panda. sorta realtime^^
it still works, just zoom out to see the object to paint on. One thing that changed since i released is the mouse-down-repeat thing, so you may want to have a look at the code to be able to continuously paint on the object. (currently you can only put 1 pixel)
Simple. The red value corresponds to the X coordinate, and the green value corresponds to the Y coordinate (flipped upside-down, because of Panda’s v=up convention). Or the other way around, I’m not sure how the original code was set up.
from panda3d.core import PNMImage
x_size = 256
y_size = 256
img = PNMImage(x_size, y_size)
x_fac = 1.0 / (x_size - 1)
y_fac = 1.0 / (y_size - 1)
for x in range(x_size):
for y in range(y_size):
red = x * x_fac
green = (y_size - y) * y_fac
blue = 0
img.set_xel(x, y, red, green, blue)
img.write("gradient.png")
This script produces an image that is black in the lower-left corner, red in the lower-right corner, green in the upper-left corner, and yellow in the upper-right corner.
And the code I gave generates exactly that. Or, use this more compact and more monolithic version that is perhaps easier to understand:
from panda3d.core import PNMImage
img = PNMImage(256, 256)
for x in range(256):
for y in range(256):
img.set_xel_val(x, y, x, 255 - y, 0)
img.write("gradient.png")
The idea being to map colour values to U, V coordinates. For any sampled colour, then the red value will correspond to the U coordinate and the green value will correspond to the V coordinate.
Thanks rdb.
Do we have to create an “invisible” copy of our Actor/NodePath for the offscreen buffer, or can we have a TextureStage only be set to be rendered by a specific camera/display region?
Now, if you want a particular node to be UV-painted on, you simply need to set the tag:
node.set_tag("uv-painting", "on")
This will cause it to get the gradient texture when rendered by the second camera.
If you want all nodes rendered by the secondary camera to have this gradient texture, then you can simply use set_initial_state instead of set_tag_state to set the state, as described by the linked manual page. You may actually wish to combine these approaches to use set_texture_off(999) on all other nodes being rendered, or alternatively you may use draw masks or simply set the scene node for the camera appropriately in order to limit what your second camera is rendering.