Question

Edit: A minimal failing test case is now on github here: https://github.com/shadowmint/Panda-setRamImage-problem

--

I have a C library that passes an unsigned char * pointer back to python with RGB pixel data in it.

The python api to do this is:

# unsigned char *ar_get_rgb(void *handle);
libar.ar_get_rgb.argtypes = [ c_void_p ]
libar.ar_get_rgb.restype = POINTER(c_char)

In panda3d I'm trying to render this data as a texture. There's a blog post here about how to that: http://www.panda3d.org/blog/?p=96

However, I found that doing this has some pretty serious limitations, which I've discussed here: http://www.panda3d.org/forums/viewtopic.php?t=13183, and as I result I'm now trying to use the setRamImage() api to set texture memory.

There seems like there must be a way to do this, but the only way I'm able to at the moment is using a pixel-by-pixel set call on the texture, as follows:

  def updateTextureTask(self, t):
    expectedSize = self.getExpectedRamImageSize()
    print("Expected length: " + str(expectedSize))
    (rgb, depth) = self.__vision.next()
    p = PTAUchar.emptyArray(expectedSize)
    for i in range(0, self.__vision.width * self.__vision.height * 3):
      p.setElement(i, ord(rgb[i]))
    print("PTAU length: " + str(p.size()))
    self.setRamImage(CPTAUchar(p))
    return Task.cont

This works...but it runs at a stunning 1 frame every 2 seconds.

If I call p.setData(rgb) to set the data of the PTAUchar (hint: http://www.panda3d.org/dox/python/html/classpanda3d_1_1core_1_1PTAUchar.html) I get:

Expected length: 921600
RGB buffer size: 921600 <-- C debugging data
PTAU length: 4
Assertion failed: compression != CM_off || image.size() == do_get_expected_ram_image_size() at line 833 of panda/src/gobj/texture.cxx
Traceback (most recent call last):

I'm puzzled as to where this '4' length comes from, because of a dump of the first 20 odd values in the RGB array is like:

0: 163, 1: 151, 2: 162, 3: 85, 4: 83, 5: 190, 6: 241, 7: 252, 8: 249, 9: 121, 10: 107, 11: 82, 12: 20, 13: 19, 14: 233, 15: 226, 16: 45, 17: 81, 18: 142, 19: 31
PTAU length: 4

There must be a way to convert my unsigned char * array into something that can feed into PTAUchar.setData or PTAUchar.setSubdata, but I can't figure it out.

help!

Was it helpful?

Solution

The definition for the setData function is:

PTAUchar.setData(string data)

You're not passing a string. You're passing a pointer to a string. I think what you want to do is have your C library pass a python byte string back to your python code, and then pass that to setData.

PS: Coming to #panda3d on freenode is a great place to get real-time help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top