2012-10-23 19 views
5

मेरे शिखर शेडर है,अंक 3.1

uniform Block1{ vec4 offset_x1; vec4 offset_x2;}block1; 

out float value; 

in vec4 position; 

void main() 
{ 
    value = block1.offset_x1.x + block1.offset_x2.x;    

    gl_Position = position; 
} 

कोड मैं मान पास करने का उपयोग कर रहा है:

GLfloat color_values[8];// contains valid values 

glGenBuffers(1,&buffer_object); 

glBindBuffer(GL_UNIFORM_BUFFER,buffer_object); 

glBufferData(GL_UNIFORM_BUFFER,sizeof(color_values),color_values,GL_STATIC_DRAW); 

glUniformBlockBinding(psId,blockIndex,0); 

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,0,16);            

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,16,16); 

यहाँ है कि मैं क्या कर रहा है, 16 बाइट्स पारित करने के लिए उम्मीद कर रहा हूँ प्रत्येक vec4 वर्दी के लिए। मुझे ऑफ़सेट = 16 के लिए GL_INVALID_VALUE त्रुटि मिलती है, आकार = 16. मैं ऑफ़सेट मान से उलझन में हूं। स्पेक का कहना है कि यह "buffer_object" के अनुरूप है।

उत्तर

8

बाध्यकारी होने पर यूबीओ के लिए alignment restriction है। कोई भी glBindBufferRange/Base ऑफ़सेट GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT का एक से अधिक होना चाहिए। यह संरेखण कुछ भी हो सकता है, इसलिए आपको वर्दी बफर की अपनी सरणी बनाने से पहले इसे पूछना होगा। इसका मतलब है कि आप सीधे संकलन-समय C++ तर्क में ऐसा नहीं कर सकते हैं; इसे रनटाइम तर्क होना चाहिए।

रनटाइम पर चीजों की पूछताछ के बारे में बोलते हुए, आपका कोड कई अन्य तरीकों से बहुत टूटा हुआ है। आपने अपने वर्दी ब्लॉक के लिए एक लेआउट क्वालीफायर परिभाषित नहीं किया है; इसलिए, डिफ़ॉल्ट का उपयोग किया जाता है: shared। और आप 0 साझा किए गए * लेआउट का उपयोग querying the layout of each block's members from OpenGL.कभी पर कर सकते हैं।

यदि आपने कोई प्रश्न किया है, तो आप जल्दी से पता लगाएंगे कि आपका वर्दी ब्लॉक कम से कम 32 बाइट आकार में 16 नहीं है। और चूंकि आपने केवल अपनी सीमा में 16 बाइट प्रदान किए हैं, अपरिभाषित व्यवहार (जिसमें शामिल है कार्यक्रम की समाप्ति) की संभावना।

आप C/C++ वस्तुओं है कि वर्दी ब्लॉक परिभाषा करने के लिए वास्तव में नक्शा परिभाषित करने के लिए सक्षम होना चाहते हैं, तो आप std140 लेआउट का उपयोग करें और अपने C/C++ वस्तु में std140 के लेआउट के नियमों का पालन करने की जरूरत है।

+0

उत्तर के लिए बहुत बहुत धन्यवाद! मुझे GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT के बारे में पता नहीं था। मैंने पहले से ही अपने आकार (32 बाइट्स) के लिए अपने वर्दी ब्लॉक से पूछताछ की थी, लेकिन मैंने 16 बाइट्स निर्दिष्ट करके सोचा था कि मैं वर्दी ब्लॉक के दूसरे "वीसी 4" घटक के लिए डेटा की आपूर्ति कर सकता हूं, जो मुझे लगता है कि गलत है। मुझे लगता है कि मुझे दूसरे वर्दी के रूप में दूसरे "vec4" घटक का इलाज करना चाहिए। बस जानकारी जोड़ने के लिए, यदि लेआउट std140 नहीं है तो ऑफसेट को GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT का एक बहु होना चाहिए। नतीजतन बाउंड बफर को आकार में GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT का एक से अधिक होना चाहिए। – maverick9888

+0

Cont। - नतीजतन बाउंड बफर को आकार में GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT का एक से अधिक होना चाहिए बशर्ते हम एकाधिक वर्दी ब्लॉक में डेटा की आपूर्ति के लिए एक बफर ऑब्जेक्ट का उपयोग कर रहे हों। – maverick9888

+0

"* यदि लेआउट std140 नहीं है तो ऑफसेट को GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT का एक बहु होना चाहिए। *" नहीं; ऑफ़सेट * हमेशा * उसमें से एक होना चाहिए। 'std140' लेआउट का मतलब है कि आपको बफर के आकार या किसी भी व्यक्तिगत वर्दी के ऑफसेट से पूछताछ नहीं करना है, क्योंकि आप उन्हें सीधे गणना कर सकते हैं। बफर जो भी आकार आप चाहते हैं, लेकिन जब आप किसी सीमा को बांधते हैं, ऑफसेट उस संरेखण का एक बहु होना चाहिए। –