Zaczynam od używania OpenGL 4 w Pythonie (przez Pyglet i niektóre kody kodu, które dostałem z sieci/napisałem sam do ładowania Shaderów/Programów), ale ja wydaje mi się, że rozumiem dość dobrze, więc nie sądzę, że gdzieś w moim kodzie jest jakiś problem.Problemy z OpenGL 4 VBOs i tablicami Numpy, Pyglet/Python
Jaki jest mój problem? Wygląda na to, że kiedy albo numpy tablice lub bufory osiągną pewien rozmiar, dziwne rzeczy zdarzają się, gdy rysuję. Proszę spojrzeć na połączony obraz, aby zobaczyć, co mam na myśli. http://i.imgur.com/8Oym6VA.png?1
Na zdjęciu widać, że rysuję niektóre "Roboty", z których każdy składa się z 8 pudełek. Dane dla robota zostały obliczone tylko raz, przy użyciu podstawowych danych wierzchołków/kolorów/indeksów kostki, a następnie odpowiednio przetłumaczone/skalowane/obrócone i dołączone do większej tablicy. Na rysunku po lewej rysuję 172 tych robotów w jednym VAO, prawy obrazek ma 173 roboty. Jak widać, dziwne rzeczy zdarzają się, gdy przejdę do tej "magicznej" liczby. Wygląda na to, że wszystkie wierzchołki są w jakiś sposób połączone z pierwszym punktem, który zostanie narysowany na ekranie (górna, prawa-przednia część "ciała" pierwszego wyciągniętego robota). Jeśli przeniesię pierwszego robota gdzie indziej, wszystkie punkty są nadal połączone z tym punktem - dla zilustrowania tego upewniłem się, że punkt na obrazie nie jest wycentrowany do (0,0,0) lub coś podobnego. Lewy obraz ma dane wierzchołków i kolorów z 131328 zmiennymi, dane indeksowe mają długość 49248. Prawy obrazek ma dane wierzchołków i kolorów z 132096 zmiennymi, a indeksy 49536 długimi. Jeśli podzielę dane na więcej niż jedno VAO, mogę bez problemu narysować sto razy robotów (z 100 VAO oczywiście) bez żadnych problemów (nawet 1000 razy więcej robotów z 1000 VAO działało dobrze, oprócz brania całkiem dużo pamięci i działa z około 0,2 FPS).
Aby przetestować, czy coś jest nie tak z klasami Pyglets (lub moimi własnymi), przepisałem całą sprawę wywołaniami OpenGL i natknąłem się na ten sam problem. Czy VBO po prostu nie są tak duże (jakoś wątpię, że VBO może mieć tylko około 17k trójkątów)? Czy ma to coś wspólnego z Numpy (wcześniej pracowałem z większymi tablicami w Numpy i nie pamiętam żadnych problemów)? Przy okazji rozmiar plyw nie ma znaczenia (to samo dzieje się, jeśli wszystkie wierzchołki są w skali [-1,1], jeśli wzrosną do [-35000, 35000].
I ' Szukałem tego tematu dość szeroko, ale nie natknąłem się na nic podobnego w moich poszukiwaniach - jeśli tak, przepraszam, jedyne, co mogłem znaleźć, to MemoryError, kiedy używam naprawdę dużych, pozbawionych liczb tablic, ale moje tablice są na tyle bliskie, aby . Produkujemy że
Moi specyfikacje systemu są:
- Intel Core i7
- Nvidia GeForce GTX 465
- Windows 8 64-bit
- Python 3.3 (64-bit)
- pyglet 1.2alpha1
- Numpy pakiet binarny dla Pythona 3.3 64-bit z here
I choć jestem prawie jasne, że nie ma w tym nic złego, ciągle pojawia się fragmenty, które są związane z rysunkiem tutaj (znowu, próbowałem tego z podstawowymi wywołaniami OpenGL również i nie działało to lepiej).
Po pierwsze mam klasę "Handler", która służy do przechowywania dużej ilości statycznych danych, więc mogę ją narysować za pomocą jednego wywołania glDraw * (na przykład poziomu gry lub czegoś podobnego).Tworzy metody dodawania danych, metodę inicjowania swoich VBO i VAO oraz funkcję rysowania, która pobiera stos i rysuje na nim. Otrzymuje również program (vertex/color shader), z którym rysuje.
class Handler:
def __init__(self, program):
self.vertexData = numpy.array((), dtype=GLfloat)
self.colorData = numpy.array((), dtype=GLfloat)
self.indexData = numpy.array((), dtype=GLshort)
self.program = program
def initBuffers(self):
self.vao = GLuint()
glGenVertexArrays(1, self.vao)
glBindVertexArray(self.vao)
#=======================================================================
# Vertices
#=======================================================================
self.vertexBufferObject = pyglet.graphics.vertexbuffer.create_buffer(self.vertexData.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.vertexBufferObject.bind()
self.vertexBufferObject.set_data(self.vertexData.ctypes.data)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
#=======================================================================
# Color
#=======================================================================
self.colorBufferObject = pyglet.graphics.vertexbuffer.create_buffer(self.colorData.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.colorBufferObject.bind()
self.colorBufferObject.set_data(self.colorData.ctypes.data)
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0)
#=======================================================================
# Index
#=======================================================================
self.indexBufferObject = pyglet.graphics.vertexbuffer.create_buffer(self.indexData.nbytes, GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW)
self.indexBufferObject.bind()
self.indexBufferObject.set_data(self.indexData.ctypes.data)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindVertexArray(0)
self.len = len(self.indexData)
def addTo(self, vertices, color = None, index = None):
if(color != None):
self.colorData = numpy.append(self.colorData, color)
if(index != None):
self.indexData = numpy.append(self.indexData, index + len(self.vertexData)//4)
self.vertexData = numpy.append(self.vertexData, vertices)
def draw(self, stack):
glBindVertexArray(self.vao)
self.indexBufferObject.bind()
self.program.install()
stack.push()
self.program.usetM4F("modelToWorldMatrix", stack.ready(), row = GL_FALSE)
glDrawElements(GL_TRIANGLES, self.len, GL_UNSIGNED_SHORT, 0)
stack.pop()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindVertexArray(0)
self.program.uninstall()
i zainicjować program obsługi z bardzo prostego kodu, gdzie translateMatrix (x, y, z) Zwraca tłumaczyć matrycy i applyTrans (zasada, trans) stosuje się w położeniu trans względem każdego vértice (x, y, z w) w podstawie.
self.handler = Handler(self.ObjectColor)
for i in range(1,n):
self.handler.addTo(applyTrans(self.robots.vertexData, translateMatrix(2*i*(-1)**(i//2), 1.5*i*(-1)**i, 0.5*i*(-1)**i)), self.robots.colorData, self.robots.indexData)
self.handler.initBuffers()
i nazywają to w on_draw części pyglet Okno z
self.handler.draw()
UPDATE:
Znalazłem się na czym polega problem i czuję się całkowicie i zupełnie głupi teraz : P. Najwyraźniej zapomniałem podać typ jednej z wielu tablic, a domyślnie "int32". Ponieważ rysowałem flagą GL_UNSIGNED_SHORT (inaczej "uint16"), stało się problemem. Upewniłem się, że pozostanie on "uint16" tak długo, jak to możliwe (dopóki maksimum danych indeksu nie wzrośnie powyżej 2^16) i doda czek, aby sprawdzić, czy indexData ma wartość "uint16" lub "uint32" i dodał Odpowiednia flaga na komendzie glDraw.
Wydaje się, że to naprawiłem, ponieważ mogę teraz łatwo dodać kilka tysięcy (próbowałem z 5000 maks.) Robotów do jednego VBO i nadal działa.
Czego jednak wciąż nie rozumiem, to dlaczego tak wyglądało (wszystkie wierzchołki połączone z pierwszym) i dlaczego zaczęło się, kiedy to się stało. Maksymalna wartość indexData, gdy była nadal w porządku, wynosiła 32831, a maksymalna wartość, gdy zaczynała działać, wynosiła 33023. Więc obie wartości są oczywiście niższe niż 2^16, więc dlaczego GL_UNSIGNED_SHORT nadal działał? Zostawię pytanie otwarte jeszcze trochę, na wypadek gdyby ktoś mógł odpowiedzieć na to pytanie i zamknie się po kilku dniach/kiedy otrzymam odpowiedź. Dzięki!
_Blind człowieka strzał w dark_: Wygląda to tak: Jeśli trójkąt krzyże 'z = 0' przed projekcją, punkty z' z <0' są odwzorowywane w kierunku '-inf' i te z 'z> 0' w kierunku' + inf'. Tak, te trójkąty powinny być oczywiście obcięte ... –
Dzięki za pomysł, nawet jeśli było źle. Wartości Vertice nie odgrywały żadnej roli w tym problemie (wszystkie mogły być < or >, a następnie 0 i nadal się pojawiały), a także punkty nie były odwzorowane w kierunku + -inf, wszystkie przeszły do punktu początkowego (jeśli obróciłeś, zobaczysz, że zatrzymał się w tym momencie). Zorientowałem się, na czym polega problem i zaktualizowałem to pytanie. Jeśli masz jakieś pomysły na temat zaktualizowanego pytania, bardzo chciałbym je usłyszeć! :) – NightmareBadger
Chcę tego robota dla mojego awatara skype ... :) – mlvljr