2013-02-24 93 views
9

में समस्याएं मैं पाइथन में ओपनजीएल 4 (पायगलेट के माध्यम से और कुछ फ्रेमवर्क कोड जो नेट से निकल गया/शेडर्स/प्रोग्राम लोड करने के लिए खुद को लिखा) के साथ शुरू कर रहा हूं, लेकिन मैं मुझे लगता है कि मैं चीजों को काफी अच्छी तरह समझता हूं, इसलिए मुझे नहीं लगता कि मेरे कोड में कहीं समस्या है।ओपनजीएल 4 वीबीओ और न्यूम्पी एरेज़, पायगलेट/पायथन

तो मेरी समस्या क्या है? ऐसा लगता है कि जब कोई भी numpy arrays या बफर एक निश्चित आकार तक पहुंचते हैं, तो जब मैं ड्राइंग कर रहा हूं तो अजीब चीजें होती हैं। मेरा मतलब क्या है इसका देखने के लिए कृपया लिंक की गई तस्वीर देखें। http://i.imgur.com/8Oym6VA.png?1

तस्वीर पर आप देख सकते हैं कि मैं कुछ "रोबोट" चित्रित कर रहा हूं, जिनमें से प्रत्येक 8 बक्से से बना है। रोबोट के लिए डेटा की गणना केवल एक बार गणना की गई थी, मूल क्यूब वर्टेक्स/रंग/अनुक्रमणिका डेटा का उपयोग करके और फिर उचित रूप से अनुवादित/स्केल/घुमाया गया और एक बड़ी सरणी में जोड़ा गया। बाईं ओर की तस्वीर में मैं एक वीएओ में उन रोबोटों में से 172 चित्रित कर रहा हूं, सही तस्वीर में 173 रोबोट हैं। जैसा कि आप देख सकते हैं, जब मैं उस "जादुई" संख्या पर जाता हूं तो अजीब चीजें होती हैं। ऐसा लगता है कि सभी शिखर किसी भी तरह स्क्रीन पर खींचे जाने वाले पहले बिंदु से जुड़े होते हैं (पहले खींचे गए रोबोट "बॉडी" के ऊपरी-दाएं-सामने भाग)। यदि मैं पहले रोबोट को कहीं और स्थानांतरित करता हूं, तो सभी बिंदु अभी भी उस बिंदु से जुड़े हुए हैं - यह स्पष्ट करने के लिए कि मैंने सुनिश्चित किया है कि चित्र में बिंदु (0,0,0) या कुछ समान नहीं है। बाएं तस्वीर में 131328 फ्लोट के साथ कशेरुका और रंग डेटा है, सूचकांक डेटा 49248 लंबा है। सही तस्वीर में 1320 9 6 फ्लोट के साथ कशेरुका और रंग डेटा है जबकि सूचकांक डेटा 49536 लंबा है। यदि मैं डेटा को एक और वीएओ में विभाजित करता हूं, तो मैं आसानी से बिना किसी समस्या के 100 गुना रोबोट (100 निश्चित रूप से 100 वीएओ के साथ) खींच सकता हूं (1000 वीएओ के साथ 1000 गुना रोबोट भी अच्छी तरह से काम करता है, काफी कुछ लेने के अलावा बहुत सारी मेमोरी और लगभग 0.2 एफपीएस के साथ काम करना)।

यह जांचने के लिए कि क्या पिगलेट कक्षाओं (या मेरे अपने) के साथ कुछ भी गलत है, मैं ओपनजीएल कॉल के साथ पूरी चीज को फिर से लिखता हूं और मैं एक ही समस्या में आया हूं। तो, क्या वीबीओ बस इतना बड़ा नहीं है (मुझे किसी भी तरह संदेह है कि वीबीओ में केवल 17k त्रिकोण प्रत्येक हो सकते हैं)? या क्या इसमें नम्पी के साथ कुछ करने के लिए कुछ है (मैंने पहले अम्पी में बड़े सरणी के साथ काम किया है और मुझे कोई समस्या नहीं है)? ओह बीटीडब्ल्यू, फ्लोट्स का आकार कोई फर्क नहीं पड़ता है (वही चीजें तब होती हैं जब सभी शिखर [-1,1] पैमाने पर होते हैं [-35000, 35000] तक जाते हैं।

I ' मैंने विषय को काफी व्यापक रूप से खोजा है, लेकिन मेरी खोज में समान कुछ भी नहीं आया है - यदि वहां है, तो मैं क्षमा चाहता हूं। मुझे लगता है कि वास्तव में बड़े numpy arrays का उपयोग करते समय मेमोरी एरर था, लेकिन मेरे सरणी आकार के करीब कहीं भी नहीं हैं । का उत्पादन है कि

मेरे प्रणाली ऐनक हैं:

  • इंटेल कोर i7
  • Nvidia GeForce GTX 465
  • Windows 8 64-बिट
  • अजगर 3.3 (64-बिट)
  • Pyglet 1.2alpha1
  • Numpy द्विआधारी अजगर 3.3 के लिए here

से और जब मैं लगभग हूँ 64-बिट पैकेज यकीन है कि मेरे कोड में कुछ भी गलत नहीं है, मैं अभी भी चित्रों से संबंधित स्निपेट पॉपिंग कर रहा हूं (फिर से, मैंने बेस ओपनजीएल कॉल के साथ भी कोशिश की है और यह किसी भी बेहतर काम नहीं करता है)।

सबसे पहले मेरे पास "हैंडलर" वर्ग है, जिसका मतलब बहुत से स्थिर डेटा को स्टोर करना है, इसलिए मैं इसे एक glDraw * कॉल (उदाहरण के लिए खेल का स्तर या कुछ समान) के साथ खींच सकता हूं।इसमें इसके डेटा को जोड़ने के तरीके हैं, इसके वीबीओ और वीएओ और ड्रॉ फ़ंक्शन को शुरू करने के लिए एक तरीका है, जो एक स्टैक प्राप्त करता है और उस पर आकर्षित करता है। यह प्रोग्राम (वर्टेक्स/रंग शेडर) भी प्राप्त करता है जिसके साथ यह आकर्षित होता है।

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

और मैं प्रारंभ कुछ बहुत ही सरल कोड है, जहां translateMatrix (एक्स, वाई, जेड) की ओर से एक का अनुवाद मैट्रिक्स और applyTrans (आधार, ट्रांस) के साथ हैंडलर हर vertice करने के लिए ट्रांस लागू होता है (एक्स, वाई, जेड, डब्ल्यू) आधार में।

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

और Pyglet विंडो की on_draw भाग में इसे कहते साथ

self.handler.draw() 

अद्यतन:

मुझे पता चला गया है कि समस्या क्या है और मैं पूरी तरह से और पूरी तरह से बेवकूफ अब महसूस हो रहा है : पी। स्पष्ट रूप से मैं numpy arrays में से एक के प्रकार को निर्दिष्ट करना भूल गया, और यह 'int32' पर डिफॉल्ट हो गया। चूंकि मैं GL_UNSIGNED_SHORT ध्वज (उर्फ 'uint16') के साथ चित्रण कर रहा था, यह एक समस्या बन गई। मैंने अब सुनिश्चित किया है कि यह यथासंभव 'uint16' रहता है (जब तक सूचकांक डेटा का अधिकतम 2^16 नहीं हो जाता) और यह देखने के लिए एक चेक जोड़ा गया कि क्या इंडेक्सडाटा 'uint16' या 'uint32' है और जोड़ा गया है glDraw कमांड पर उचित ध्वज।

ऐसा लगता है कि इसे ठीक कर दिया गया है, क्योंकि अब मैं आसानी से कुछ हजार (5000 अधिकतम के साथ कोशिश की) रोबोट को एक वीबीओ में जोड़ सकता हूं और यह अभी भी काम करता है।

जो भी मुझे अभी भी समझ में नहीं आता है, ऐसा क्यों लगता है कि ऐसा हुआ (सभी पहले से जुड़े सभी कोष्ठक) और यह क्यों शुरू हुआ जब यह शुरू हुआ। इंडेक्सडाटा का अधिकतम मूल्य जब यह अभी भी ठीक था 32831 था, तो अधिकतम मूल्य जब यह अभिनय करना शुरू हुआ तो 33023 था। इसलिए दोनों मान स्पष्ट रूप से कम हैं 2^16, तो फिर भी GL_UNSIGNED_SHORT क्यों काम नहीं किया? अगर कोई इसका उत्तर दे सकता है तो मैं थोड़ा और अधिक प्रश्न खोलूंगा और कुछ दिनों के बाद बंद हो जाएगा/जब मुझे जवाब मिल जाएगा। धन्यवाद!

+0

_Blind आदमी का शॉट: यह इस तरह दिखता है: एक त्रिकोण को पार करती है तो 'z = 0' प्रक्षेपण से पहले,' जेड के साथ अंक <0' -inf' 'की ओर, मैप की जाती हैं और 'z> 0' के साथ' + inf' की ओर। हाँ, इन त्रिकोणों को स्पष्ट रूप से फिसल जाना चाहिए ... –

+0

विचार के लिए धन्यवाद, भले ही यह गलत था। वर्टिस मूल्यों ने इस समस्या में कोई भूमिका नहीं निभाई है (वे सभी < or > तब 0 हो सकते हैं और यह अभी भी दिखाई दे रहा है) और पॉइंट को + -inf की तरफ मैप नहीं किया गया था, वे सभी शुरुआती बिंदु पर गए थे (यदि आप घूमते हैं तो आप इसे देख सकते हैं उस बिंदु पर रुक गया)। मैंने यह पता लगाया है कि समस्या क्या थी और सवाल को अद्यतन किया गया। यदि आपके पास अद्यतन प्रश्न के बारे में कोई विचार है, तो मुझे उन्हें सुनना अच्छा लगेगा! :) – NightmareBadger

+0

मुझे अपने स्काइप अवतार के लिए वह रोबोट चाहिए ... :) – mlvljr

उत्तर

1

आप वर्टेक्स बफर ऑब्जेक्ट्स के साथ सीधे न्यूम्पी फ्लोट एरे का उपयोग कर सकते हैं। हालांकि मैंने उन्हें पिगलेट के संदर्भ में उपयोग नहीं किया है। कुछ की तरह:

from OpenGL.arrays import vbo 

# setup 
vertices_gl = vbo.VBO(vertPoints) 
colours_gl = vbo.VBO(vertPoints) 

# in drawing code 
vertices.bind() 
colours.bind() 
glVertexPointer(2, gl.GL_FLOAT, 0, vertices_gl) 
glColorPointer(2, gl.GL_FLOAT, 0, vertices_gl) 
dark_ में