2012-04-09 11 views
0

Edit: Ein minimaler andernfalls Testfall ist jetzt auf GitHub hier: https://github.com/shadowmint/Panda-setRamImage-problemWie benutzt man setRamImage in panda3d?

-

Ich habe eine C-Bibliothek, die ein unsigned char gibt * zu Python mit RGB-Pixeldaten darin Zeiger zurück.

Der Python-API, dies zu tun ist:

# 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 Ich versuche, diese Daten als Textur zu machen. Es gibt eine Blog-Post hier darüber, wie das: http://www.panda3d.org/blog/?p=96

Allerdings habe ich festgestellt, dass dies zu tun einige ziemlich ernste Einschränkungen, die ich hier besprochen habe: http://www.panda3d.org/forums/viewtopic.php?t=13183, und als ich zur Folge ich jetzt versuchen, das zu verwenden, setRamImage() api zum Festlegen des Texturspeichers.

Es scheint so, muss es eine Möglichkeit, dies zu tun, aber der einzige Weg, ich Moment in der Lage bin, ist ein Pixel-für-Pixel-Set Anruf auf der Textur verwendet wird, wie folgt:

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 

Das funktioniert ... aber es läuft alle 2 Sekunden in einem atemberaubenden 1 Rahmen.

Wenn ich rufe p.setData (rgb) die Daten des PTAUchar (Hinweis: http://www.panda3d.org/dox/python/html/classpanda3d_1_1core_1_1PTAUchar.html) gesetzt ich:

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): 

ich verwirrt bin, wo dieses '4' Länge herkommt, wegen eines Dump der ersten 20 ungeradeen Werte im RGB-Array ist wie:

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 

es eine Möglichkeit sein muss mein unsigned char * array in etwas zu konvertieren, die in PTAUchar.setData oder PTAUchar.setSubdata ernähren können, aber ich kann es nicht herausfinden.

Hilfe!

+0

Wenn Sie eine neuere Entwicklungsversion von Panda verwenden, sollten Sie in der Lage sein, jedes Objekt, das das Python-Pufferprotokoll dem PTAUchar-Konstruktor aussetzt, zu übergeben. Dies wäre weitaus effizienter als das Kopieren über eine Zeichenfolge. Siehe auch den neuesten Post auf dem Panda3D Blog. – rdb

Antwort

1

Die Definition für die setData Funktion ist:

PTAUchar.setData(string data) 

Sie sind nicht eine Zeichenfolge übergeben. Sie übergeben einen Zeiger an eine Zeichenfolge. Ich denke, was Sie tun möchten, ist Ihre C-Bibliothek übergeben Sie eine Python-Byte-Zeichenfolge zurück zu Ihrem Python-Code, und dann übergeben Sie das an .

PS: Kommen Sie zu # panda3d auf Freenode ist ein großartiger Ort, um Echtzeit-Hilfe zu bekommen.

+0

Hilfreich, aber das ist wirklich generischer Rat. Kannst du genauer sein? Ein c_char_p-Typ bewirkt, dass c eine Python-Zeichenkette zurückgibt, aber sie ist NULL-terminiert, was bedeutet, dass Sie beispielsweise BLACK PIXELS (oder ein Pixel mit einer 0-Komponente) nicht zurückgeben können, wodurch die API völlig unbrauchbar wird. – Doug

+0

Eine Python-Zeichenfolge kann definitiv ein 0-Byte enthalten. Vielleicht möchtest du PyString_FromStringAndSize? – jterrace

+0

Der fehlende Schritt bestand darin, den POINTER (c_char) mit rgb = rgb [: expectedSize] // PTAUchar.setData (rgb) in einen String umzuwandeln. – Doug