मैं हाल ही में शीर्ष सरणी वस्तुओं के साथ कुछ ओपन 3.3 कोड (VAO) लेखन और बाद में इंटेल ग्राफिक्स एडाप्टर, जहां मैं अपने निराशा करने के लिए मिल गया है, पर यह परीक्षण किया गया था, उस तत्व सरणी बफर बाध्यकारी जाहिर नहीं है VAO राज्य का हिस्सा है, बुला के रूप में:VAO और तत्व सरणी बफर राज्य
glBindVertexArray(my_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, my_index_buffer); // ?
glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_INTEGER, 0);
ज्यामिति गाया:
glBindVertexArray(my_vao);
glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_INTEGER, 0);
जबकि, कोई प्रभाव नहीं पड़ा। मैंने सोचा कि यह ओपन (क्योंकि यह स्पष्ट रूप से (और GL_ARB_vertex_array_object में कहा गया है यहां तक कि GL_OES_vertex_array_object में) उस तत्व सरणी बचाया राज्य के हिस्सा है) का इंटेल कार्यान्वयन में एक मात्र बग था, लेकिन तब यह मोबाइल NVIDIA Quadro 4200 पर हुई है कि कोई मज़ा नहीं।
क्या यह एक ड्राइवर बग, एक चश्मा बग, या मेरे कोड में कहीं एक बग है? कोड GeForce 260 और 480 पर बेकार ढंग से काम करता है।
किसी के पास समान अनुभव था?
क्या भी अजीब बात है कि GL_EXT_direct_state_access VAO को एक तत्व सरणी बफर बाध्य करने के लिए एक समारोह नहीं है (लेकिन यह शीर्ष attrib सरणियों, और इसलिए सरणी बफ़र्स निर्दिष्ट करने के लिए कार्य करता है) है। क्या जीपीयू निर्माता चश्मे को धोखा दे रहे हैं और धोखाधड़ी कर रहे हैं, या क्या?
संपादित:
मैं मूल रूप से, क्योंकि मैं मानना था कि यह यहाँ आवश्यक नहीं था किसी भी स्रोत कोड को दिखाने के लिए इरादा नहीं था। लेकिन के रूप में अनुरोध, यहाँ कम से कम परीक्षण का मामला है कि समस्या को पुनरुत्पादित करता है:
static GLuint n_vertex_buffer_object, p_index_buffer_object_list[3];
static GLuint p_vao[2];
bool InitGLObjects()
{
const float p_quad_verts_colors[] = {
1, 0, 0, -1, 1, 0,
1, 0, 0, 1, 1, 0,
1, 0, 0, 1, -1, 0,
1, 0, 0, -1, -1, 0, // red quad
0, 0, 1, -1, 1, 0,
0, 0, 1, 1, 1, 0,
0, 0, 1, 1, -1, 0,
0, 0, 1, -1, -1, 0, // blue quad
0, 0, 0, -1, 1, 0,
0, 0, 0, 1, 1, 0,
0, 0, 0, 1, -1, 0,
0, 0, 0, -1, -1, 0 // black quad
};
const unsigned int p_quad_indices[][6] = {
{0, 1, 2, 0, 2, 3},
{4, 5, 6, 4, 6, 7},
{8, 9, 10, 8, 10, 11}
};
glGenBuffers(1, &n_vertex_buffer_object);
glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glBufferData(GL_ARRAY_BUFFER, sizeof(p_quad_verts_colors), p_quad_verts_colors, GL_STATIC_DRAW);
glGenBuffers(3, p_index_buffer_object_list);
for(int n = 0; n < 3; ++ n) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[n]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(p_quad_indices[n]), p_quad_indices[n], GL_STATIC_DRAW);
}
glGenVertexArrays(2, p_vao);
glBindVertexArray(p_vao[0]);
{
glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), p_OffsetInVBO(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), p_OffsetInVBO(3 * sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[0]); // red
}
glBindVertexArray(0);
glBindVertexArray(p_vao[1]);
{
glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), p_OffsetInVBO(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), p_OffsetInVBO(3 * sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[1]); // blue
}
glBindVertexArray(0);
#ifdef BIND_BLACK_QUAD_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[2]);
// bind the buffer with the black quad (not inside VAO, should NOT be seen)
#endif // BIND_BLACK_QUAD_ELEMENT_ARRAY_BUFFER
// [compile shaders here]
return true; // success
}
ऊपर कोड तीन quads, लाल एक, नीले और काले एक एक युक्त एक शीर्ष बफर पैदा करता है। फिर यह तीन सूचकांक बफर बनाता है जो व्यक्तिगत quads को इंगित करता है। फिर दो वीएओ बनाए जाते हैं और स्थापित होते हैं, एक में लाल क्वाड इंडेक्स होना चाहिए और दूसरे में ब्लू क्वाड इंडेक्स होना चाहिए। ब्लैक क्वाड को बिल्कुल प्रस्तुत नहीं किया जाना चाहिए (मान लें कि BIND_BLACK_QUAD_ELEMENT_ARRAY_BUFFER परिभाषित है)।
void onDraw()
{
glClearColor(.5f, .5f, .5f, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(n_program_object);
static int n_last_color = -1;
int n_color = (clock()/2000) % 2;
if(n_last_color != n_color) {
printf("now drawing %s quad\n", (n_color)? "blue" : "red");
n_last_color = n_color;
}
glBindVertexArray(p_vao[n_color]);
#ifdef VAO_DOESNT_STORE_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p_index_buffer_object_list[n_color]); // fixes the problem
#endif // VAO_DOESNT_STORE_ELEMENT_ARRAY_BUFFER
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
यह व्यूपोर्ट ग्रे को साफ करता है और तरीके से दोहरा में या तो नीला या लाल ट्रैक्टर renders (यह भी प्रिंट जो एक)। हालांकि यह डेस्कटॉप जीपीयू पर काम करता है, यह नोटबुक जीपीयू पर काम नहीं करता है (ब्लैक क्वाड तब तक प्रस्तुत किया जाता है जब तक कि VAO_DOESNT_STORE_ELEMENT_ARRAY_BUFFER मैक्रो परिभाषित नहीं किया जाता है। BIND_BLACK_QUAD_ELEMENT_ARRAY_BUFFER मैक्रो को परिभाषित करना क्वाड ब्लू बनाता है, क्योंकि ब्लू इंडेक्स बफर आखिरी है। लेकिन यह नहीं है लाल ट्रैक्टर कोई फर्क नहीं पड़ता प्रस्तुत करना क्या।
तो जिस तरह से मैं इसे देख, यह या तो कैसे काम करते हैं, मेरी कोड में एक बग, या एक ड्राइवर बग Vao चाहिए की मेरी समझ में एक घातक गलत धारणा है।
Full source
Binaries (windows, 32 bit)
यह अधिक संभावना है कि आपका कोड प्रारंभ में वीएओ में तत्व बफर नहीं डाल रहा है। आप हमें अपना वीएओ प्रारंभिक कोड क्यों नहीं दिखाते हैं। –
ओह आओ, बेवकूफ नहीं। इसके अलावा मैंने कहा कि यह GeForce 260/480 पर काम करता है। टिप्पणियां लिखने से पहले पोस्ट पढ़ें। मैं अपने ओपनजीएल कोड को डीबग करने में पूरी तरह से सक्षम हूं। यह प्रश्न ओपनजीएल कार्यान्वयन और संगतता के बीच मतभेदों के बारे में है। –
सिर्फ इसलिए कि कोड काम का मतलब यह नहीं है कि यह * सही * है। चाहे सौहार्दपूर्ण परिस्थिति या जो कुछ भी हो, कोड काम करने में सक्षम हो सकता है। तथ्य यह है कि यह दोनों एनवीआईडीआईए ड्राइवरों में विफल रहता है और सफल होता है उपयोगकर्ता त्रुटि का सुझाव देता है। अगर यह एनवीआईडीआईए पर काम करता है और एटीआई में विफल रहता है, या इसके विपरीत, यह ड्राइवर बग होने की अधिक संभावना होगी। लेकिन एनवीआईडीआईए विशेष रूप से बहुत ही समान है। तो अगर यह कभी-कभी कुछ एनवीआईडीआईए हार्डवेयर पर काम करता है और कभी-कभी ऐसा नहीं होता है, तो यह उपयोगकर्ता त्रुटि की तरह लगता है। –