如何在没有VAO的情况下使用VBO和OpenGL核心配置文件?

问题描述 投票:8回答:2

我在使用顶点缓冲区对象时遇到了麻烦,而没有使用顶点数组对象。

我的理解是VAO只是封装了VBO周围的状态。但是,如果没有VAO,VBO不应该可用吗?

这是一个小例子。使用qazxsw poi这可以正常工作(呈现橙色反应)。使用qazxsw poi,这没有任何结果,并在use_vao=true上产生use_vao=false错误。

GL_INVALID_OPERATION

在我的机器上,glDrawElements生产// 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(); }

c++ opengl opengl-3 opengl-4
2个回答
17
投票

核心配置文件中需要使用VAO。从OpenGL 3.3规范,第342页,在E.2.2“删除的功能”部分中:

默认的顶点数组对象(名称为零)也不推荐使用。

这意味着您无法在不创建和绑定自己的VAO的情况下设置顶点属性。


10
投票

没有核心3.3+配置文件,您需要VAO进行渲染。

然而,您可以创建并绑定VAO并忘记它(保持绑定)。

除此之外,即使使用兼容性配置文件而不使用VAO,仍必须调用glGetString(GL_VERSION)

其他一些评论是您每帧重新生成所有缓冲区和VAO但不清理它们。您应该在初始化期间执行一次,然后在绘制时重新绑定:

4.1 INTEL-10.6.20
© www.soinside.com 2019 - 2024. All rights reserved.