2015-05-05 5 views
8

मुझे वर्टेक्स बफर ऑब्जेक्ट्स का उपयोग करके बिना किसी वर्टेक्स सरणी ऑब्जेक्ट का उपयोग करने में समस्या हो रही है।ओपनजीएल कोर प्रोफाइल के साथ वीएओ के बिना वीबीओ का उपयोग कैसे करें?

मेरी समझ यह थी कि वीएओ सिर्फ वीबीओ के आसपास राज्य को घेर रहे हैं। लेकिन क्या वीबीओ वीएओ के बिना प्रयोग योग्य नहीं होना चाहिए?

यहां एक छोटा उदाहरण है। use_vao=true के साथ यह सही ढंग से काम करता है (नारंगी आयताकार प्रस्तुत करता है)। use_vao=false के साथ यह कुछ भी प्रस्तुत नहीं करता है और glDrawElements पर GL_INVALID_OPERATION त्रुटि उत्पन्न करता है।

// make sure the modern opengl headers are included before any others 
#include <OpenGL/gl3.h> 
#define __gl_h_ 
#include <GLUT/glut.h> 
#include <string> 
#include <cassert> 

// For rendering a full-viewport quad, set tex-coord from position 
std::string tex_v_shader = R"(
#version 330 core 
in vec3 position; 
void main() 
{ 
    gl_Position = vec4(position,1.); 
} 
)"; 
// Render directly from color or depth texture 
std::string tex_f_shader = R"(
#version 330 core 
out vec4 color; 
void main() 
{ 
    color = vec4(0.8,0.4,0.0,0.75); 
} 
)"; 
// shader id, vertex array object 
GLuint tex_p_id; 
int w=1440,h=480; 
const GLfloat V[] = {-0.5,-0.5,0,0.5,-0.5,0,0.5,0.5,0,-0.5,0.5,0}; 
const GLuint F[] ={0,1,2, 0,2,3}; 
int main(int argc, char * argv[]) 
{ 
    // Init glut and create window + OpenGL context 
    glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_3_2_CORE_PROFILE|GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); 
    glutInitWindowSize(w,h); 
    glutCreateWindow("test"); 
    // Compile shaders 
    const auto & compile = [](const char * src,const GLenum type)->GLuint 
    { 
    GLuint s = glCreateShader(type); 
    glShaderSource(s, 1, &src, NULL); 
    glCompileShader(s); 
    return s; 
    }; 
    tex_p_id = glCreateProgram(); 
    glAttachShader(tex_p_id,compile(tex_v_shader.c_str(), GL_VERTEX_SHADER)); 
    glAttachShader(tex_p_id,compile(tex_f_shader.c_str(), GL_FRAGMENT_SHADER)); 
    glLinkProgram(tex_p_id); 
    glutDisplayFunc(
    []() 
    { 
     glViewport(0,0,w,h); 
     glUseProgram(tex_p_id); 
     glClearColor(0.0,0.4,0.7,0.); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     const bool use_vao = true; 
     GLuint VAO; 
     if(use_vao) 
     { 
     glGenVertexArrays(1, &VAO); 
     glBindVertexArray(VAO); 
     } 
     GLuint VBO, EBO; 
     glGenBuffers(1, &VBO); 
     glGenBuffers(1, &EBO); 
     glBindBuffer(GL_ARRAY_BUFFER, VBO); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(V), V, GL_STATIC_DRAW); 
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(F), F, GL_STATIC_DRAW); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 
     glBindBuffer(GL_ARRAY_BUFFER, VBO); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
     if(use_vao) 
     { 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 
     } 
     assert(glGetError() == GL_NO_ERROR); 
     glDrawElements(GL_TRIANGLES,sizeof(F)/sizeof(GLuint),GL_UNSIGNED_INT, 0); 
     assert(glGetError() == GL_NO_ERROR); 
     glutSwapBuffers(); 
    } 
    ); 
    glutReshapeFunc([](int w,int h){::h=h, ::w=w;}); 
    glutMainLoop(); 
} 

मेरी मशीन glGetString(GL_VERSION) पर 4.1 INTEL-10.6.20 पैदा करता है।

उत्तर

13

VAOs का उपयोग करते हुए कोर प्रोफ़ाइल में आवश्यक है। ओपनजीएल 3.3 spec से, पृष्ठ 342, खंड E.2.2 में "हटाई गई विशेषताएं":

डिफ़ॉल्ट वर्टेक्स सरणी ऑब्जेक्ट (नाम शून्य) भी बहिष्कृत किया गया है।

इसका मतलब है कि आप अपने स्वयं के वीएओ बनाने और बाध्य किए बिना वर्टेक्स विशेषताओं को सेट नहीं कर सकते हैं।

9

कोर 3.3+ प्रोफ़ाइल के साथ कोई प्रस्तुत करने के लिए एक वीएओ की आवश्यकता है।

हालांकि आप केवल वीएओ बना सकते हैं और बांध सकते हैं और इसके बारे में भूल सकते हैं (इसे बाध्य रखें)।

इसके अलावा glEnableVertexAttribArray(0); को अभी भी संगतता प्रोफ़ाइल का उपयोग करते समय और वीएओ का उपयोग न करने के दौरान भी बुलाया जाना चाहिए।

कुछ अन्य टिप्पणियां यह है कि आप सभी बफर और वीएओ को हर फ्रेम को पुन: उत्पन्न करते हैं लेकिन इसे साफ़ नहीं करते हैं। आप प्रारंभ के दौरान एक बार है कि क्या करना चाहिए और उसके बाद rebind जब ड्राइंग:

if(!use_vao){ 
     glBindBuffer(GL_ARRAY_BUFFER, VBO); 
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
} 
else 
{ 
     glBindVertexArray(VAO); 
} 
+1

धन्यवाद। क्या आपके पास एक संदर्भ है जिसमें कहा गया है कि वीएओ अनिवार्य है? मैं उत्सुक हूं जहां यह लिखा गया है, क्योंकि मुझे यह खुद नहीं मिला। –

संबंधित मुद्दे