मैं ओपनजीएल 4.5 का उपयोग कर त्रिकोण प्रस्तुत करना चाहता हूं। मुझे ओपनजीएल के पुराने संस्करणों का उपयोग करके ऑनलाइन बहुत सारे उदाहरण मिल गए हैं लेकिन ओपनजीएल 4.5 फ़ंक्शंस का उपयोग नहीं कर रहा है। इसलिए मैंने स्वयं कुछ कोड "अपग्रेड" करने का प्रयास किया। यह पुराना कामकाजी कोड है:
// Triangles to render
vec3 vertices[2][3] = { { vec3(-0.90f, -0.90f, 1.0f), vec3(0.85f, -0.90f, 1.0f), vec3(-0.90f, 0.85f, 1.0f) },
{ vec3(0.90f, -0.85f, 1.0f), vec3(0.90f, 0.90f, 1.0f), vec3(-0.85f, 0.90f, 1.0f) } };
//Initialize
glGenVertexArrays(1, &vaos);
glBindVertexArray(vaos);
glGenBuffers(1, &buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangles), triangles, GL_STATIC_DRAW);
ShaderInfo shaders[] = {
{ GL_VERTEX_SHADER, "triangles.vert" },
{ GL_FRAGMENT_SHADER, "triangles.frag" },
{ GL_NONE, NULL }
};
program = LoadShaders(shaders);
glUseProgram(program);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
//Render
GLint index;
index = glGetUniformLocation(program, "projectionMatrix");
glUniformMatrix3fv(index, 1, true, value_ptr(projectionMatrix));
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vaos);
glDrawArrays(GL_TRIANGLES, 0, nvertices);
और मैंने इसे इस कोड में "अपडेट" किया, जो स्क्रीन पर कुछ भी आकर्षित नहीं करता है:
// Same triangles
// Initialize
glCreateVertexArrays(1, &vaos);
glEnableVertexArrayAttrib(vaos, 0);
glVertexArrayAttribFormat(vaos, 0, 3, GL_FLOAT, GL_FALSE, 0);
glCreateBuffers(1, &buffers);
glNamedBufferData(buffers, sizeof(triangles), triangles, GL_STATIC_DRAW);
glVertexArrayAttribBinding(vaos, 0, 0);
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 0);
ShaderInfo shaders[] = {
{ GL_VERTEX_SHADER, "triangles.vert" },
{ GL_FRAGMENT_SHADER, "triangles.frag" },
{ GL_NONE, NULL }
};
program = LoadShaders(shaders);
glUseProgram(program);
// Same render
क्या कोई मुझे बता सकता है कि मैंने क्या गलत किया?
संपादित करें: त्रिकोण.फ्रैग
#version 450
in vec4 gl_FragCoord;
out vec4 fColor;
void main ()
{
fColor = vec4 (0.0, 0.0, 1.0, 1.0);
}
त्रिकोण.वर्ट
#version 450
layout (location = 0) in vec3 vPosition;
uniform mat3 projectionMatrix;
void main ()
{
vec3 tmp = projectionMatrix*vPosition;
gl_Position = vec4 (tmp, 1.0f);
}
1 उत्तर
अपराधी इस लाइन की सबसे अधिक संभावना है:
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 0);
अंतिम पैरामीटर stride
है, जिसका अर्थ है लगातार दो सरणी तत्वों के बीच की दूरी। पारंपरिक glVertexAttribPointer
कॉल में, एक stride
पैरामीटर भी होता है, लेकिन थोड़ा सा अर्थ अंतर होता है:
यदि आप glVertexAttribPointer
में 0
के stride
का उपयोग करते हैं, तो यह count * sizeof(type)
लिखने के लिए एक सुविधाजनक शॉर्टकट है, और एक कसकर पैक की गई विशेषता सरणी मान लेगा।
glVertexArrayVertexBuffer
के साथ 0
के एक स्ट्राइड का अर्थ है 0
, इसलिए यह आपको ड्रॉ कॉल के प्रत्येक शीर्ष के लिए समान तत्व प्रदान करेगा। glVertexArrayVertexBuffer
समान शॉर्टकट प्रदान नहीं कर सकता, क्योंकि यह सीधे किसी भी शीर्ष विशेषता से बंधा नहीं है, और कई विशेषताएँ एक ही बफर इंडेक्स को संदर्भित कर सकती हैं (और आमतौर पर करती हैं)। (और इंटरफ़ेस भी बहुत अजीब होगा, क्योंकि आप बाध्यकारी सेट करने से पहले या बाद में वर्टेक्स प्रारूप सेट कर सकते हैं, इसलिए इसे बाद में मूल्यांकन करना होगा।)
तो अवधारणात्मक रूप से, स्ट्राइड विशेषता प्रारूप का हिस्सा नहीं है। प्रारूप केवल उन सभी चीजों का वर्णन करता है जो एक एकल शीर्ष के लिए आवश्यक हैं। ध्यान दें कि इस परिवर्तन का प्रत्यक्ष राज्य पहुंच से कोई लेना-देना नहीं है। इसे वास्तव में ARB_vertex_attrib_binding
(जीएल 4.3 के बाद से कोर) के साथ पेश किया गया था ), जिसने बफर बाइंडिंग को विशेषता प्रारूप विवरण से अलग किया। उस दस्तावेज़ के मुद्दे (2) और (3) इस प्रश्न के लिए बहुत प्रासंगिक हैं:
(2) शून्य के एक स्ट्राइड की व्याख्या
BindVertexBuffer
में कैसे की जाती है?हल किया गया: कोई त्रुटि उत्पन्न नहीं होती है, किसी दिए गए विशेषता के लिए सभी सरणी तत्व बफर में उसी स्थान से प्राप्त किए जाएंगे।
(3)
VertexAttribPointer
में शून्य के एक स्ट्राइड को कैसे हैंडल किया जाता है?हल किया गया:
BindVertexBuffer
को एट्रिब प्रारूप का कोई ज्ञान नहीं है, इसलिएVertexAttribPointer
को खुद ही स्ट्राइड की गणना करनी होगी। हालाँकि, यदि कोई एप्लिकेशन शून्य का एक चरण निर्दिष्ट करता है और फिर क्वेरी करता हैVERTEX_ATTRIB_ARRAY_STRIDE
, यह शून्य लौटाता है। तो व्युत्पन्न कदम जोBindVertexBuffer
को पास कर दिया गया है, उसे अलग से ट्रैक किया जाना चाहिए स्ट्राइड मूल रूप सेVertexAttribPointer
को पास किया गया था, इसलिए यह युक्ति परिचय देती है राज्य का एक अलग टुकड़ा (VERTEX_BINDING_STRIDE
)। रेंडरिंग हमेशा उपयोग करता हैVERTEX_BINDING_STRIDE
.यह संभावित रूप से भ्रामक राज्य प्रश्नों को जन्म दे सकता है यदि एपीआई का दुरुपयोग किया जाता है। उदाहरण के लिए:
VertexAttribPointer(0, 3, FLOAT, FALSE, 12, 0); // VERTEX_ATTRIB_ARRAY_STRIDE = 12 // VERTEX_BINDING_STRIDE = 12 BindVertexBuffer(0, buffer, 0, 16) // now VERTEX_ATTRIB_ARRAY_STRIDE is still 12, but // VERTEX_BINDING_STRIDE = 16.
एक लंबी कहानी को छोटा करने के लिए: आपके उपयोग के मामले के लिए, आपको आवश्यकता होगी
glVertexArrayVertexBuffer(vaos, 0, buffers, 0, 3*sizeof(GLfloat));
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।