Probleme mit OpenGL 4 VBOs und Numpy Arrays, Pyglet / Python

9

Ich beginne mit der Verwendung von OpenGL 4 in Python (über Pyglet und etwas Framework-Code, den ich vom Netz genommen habe / selbst geschrieben habe, um Shader / Programme zu laden), aber ich verstehe die Dinge ziemlich gut, also nicht Ich denke, irgendwo in meinem Code ist ein Problem.

Was ist mein Problem? Es scheint, dass, wenn entweder numpy Arrays oder die Puffer eine bestimmte Größe erreichen, seltsame Dinge passieren, wenn ich zeichne. Bitte schau dir das verlinkte Bild an, um zu sehen, was ich meine. Ссылка

Auf dem Bild seht ihr, dass ich einige "Roboter" zeichne, von denen jeder aus 8 Boxen besteht. Die Daten für den Roboter wurden nur einmal berechnet, wobei grundlegende Würfel-Vertex- / Farb- / Indexdaten verwendet und dann geeignet übersetzt / skaliert / gedreht und an ein größeres Array angehängt wurden. Im linken Bild zeichne ich 172 dieser Roboter in einem VAO, das rechte Bild hat 173 Roboter. Wie du sehen kannst, passiert seltsames Zeug, wenn ich über diese "magische" Nummer gehe. Es sieht so aus, als ob alle Scheitelpunkte irgendwie mit dem ersten Punkt verbunden sind, der auf dem Bildschirm gezeichnet wird (oberer rechter vorderer Teil des ersten gezeichneten "Körpers" des Roboters). Wenn ich den ersten Roboter irgendwohin bewege, sind alle Punkte immer noch mit diesem Punkt verbunden - um zu verdeutlichen, dass ich dafür gesorgt habe, dass der Punkt im Bild nicht auf (0,0,0) oder etwas Ähnliches zentriert ist. Das linke Bild hat Vertex- und Farbdaten mit 131328 floats, Indexdaten sind 49248 long. Das rechte Bild enthält Vertex- und Farbdaten mit 132096 Floats, während Indexdaten 49536 Floats lang sind. Wenn ich die Daten in mehr als einen VAO unterteile, dann kann ich mühelos Roboter im 100-fachen (mit 100 VAOs natürlich) problemlos zeichnen (sogar 1000-fache Roboter mit 1000 VAOs haben gut funktioniert, abgesehen davon, dass sie ziemlich viel genommen haben) von Gedächtnis und mit ungefähr 0.2 FPS arbeitend).

Um herauszufinden, ob etwas mit den Pyglets-Klassen (oder meiner eigenen) falsch ist, habe ich das Ganze auch mit OpenGL-Aufrufen umgeschrieben und bin auf das gleiche Problem gestoßen. Also, sind VBOs einfach nicht so groß gemeint (ich bezweifle irgendwie, dass VBOs nur etwa 17k Dreiecke haben könnten)? Oder hat es etwas mit Numpy zu tun? (Ich habe schon früher mit größeren Arrays in Numpy gearbeitet und kann mich nicht erinnern, irgendwelche Probleme gehabt zu haben)? Ach übrigens, die Größe der Floats scheint keine Rolle zu spielen (dasselbe passiert, wenn alle Vertices in der [-1,1] -Skala sind, wenn sie bis zu [-35000, 35000] gehen.)

Ich habe das Thema ziemlich ausführlich recherchiert, aber bei meiner Suche habe ich nichts Ähnliches gefunden - wenn es so ist, entschuldige ich mich. Alles, was ich finden konnte, war der MemoryError, wenn ich wirklich große numpy Arrays benutze, aber meine Arrays sind nicht annähernd so groß, um das zu erzeugen.

Meine Systemspezifikationen sind:

  • Intel Core i7
  • Nvidia GeForce GTX 465
  • Windows 8 64-Bit
  • Python 3.3 (64-Bit)
  • Pyglet 1.2alpha1
  • Numpy-Binärpaket für Python 3.3 64-bit von hier

Und während ich fast sicher bin, dass an meinem Code nichts auszusetzen ist, knipse ich immer noch die Snippets, die mit der Zeichnung in Zusammenhang stehen (ich habe es auch mit Basis-OpenGL-Aufrufen versucht und es hat nicht funktioniert etwas besser).

Als Erstes habe ich eine "Handler" -Klasse, die viele statische Daten speichern soll, damit ich sie mit einem glDraw * -Aufruf zeichnen kann (zum Beispiel das Level des Spiels oder etwas Ähnliches). Es hat Methoden zum Hinzufügen zu seinen Daten, eine Methode, um seine VBOs und VAO und eine Zeichenfunktion zu initialisieren, die einen Stapel bekommt und daraus ableitet. Es erhält auch das Programm (Vertex / Color Shader), mit dem es zeichnet.

%Vor%

Und ich initialisiere den Handler mit einem sehr einfachen Code, wobei translateMatrix (x, y, z) eine Translationsmatrix zurückgibt und applyTrans (basis, trans) trans an jede Ecke (x, y, z, w) in der Basis anwendet .

%Vor%

Und rufe es im on_draw-Teil des Pyglet-Fensters mit

auf %Vor%

UPDATE:

Ich habe herausgefunden, was das Problem ist, und ich fühle mich jetzt völlig und völlig dumm: P. Anscheinend habe ich vergessen, den dtype eines der numpy Arrays zu spezifizieren, und es wurde standardmäßig auf 'int32' gesetzt. Da ich mit dem GL_UNSIGNED_SHORT-Flag (aka 'uint16') gezeichnet habe, wurde es ein Problem. Ich habe jetzt sichergestellt, dass es 'uint16' so lange wie möglich bleibt (bis der Höchstwert der Indexdaten höher als 2 ^ 16 wird) und fügte hinzu, ob indexData 'uint16' oder 'uint32' ist und fügte das entsprechende hinzu Flag auf glDraw-Befehl.

Dies scheint es behoben zu haben, da ich jetzt leicht ein paar tausend (mit max. 5.000 Robotern probiert) Roboter zu einem VBO hinzufügen kann und es funktioniert immer noch.

Was ich immer noch nicht verstehe, ist warum es so aussah (es waren alle mit dem ersten verbundenen Scheitelpunkte) und warum es begann, als es geschah. Der maximale Wert von indexData, als es noch in Ordnung war, war 32831, der maximale Wert beim Start war 33023. Also sind beide Werte offensichtlich niedriger als 2 ^ 16, also warum hat GL_UNSIGNED_SHORT nicht funktioniert?Ich lasse die Frage für ein bisschen mehr offen für den Fall, dass jemand das beantworten kann und wird nach ein paar Tagen schließen / wenn ich eine Antwort bekomme. Danke!

    
NightmareBadger 24.02.2013, 03:03
quelle

1 Antwort

1

Sie können Numpy-Float-Arrays direkt mit Vertex-Pufferobjekten verwenden. Ich habe sie jedoch nicht im Zusammenhang mit Pyglet verwendet. Etwas wie:

%Vor%     
Navjot Singh 07.06.2013 18:57
quelle