首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不需要有VAO吗?

不需要有VAO吗?
EN

Stack Overflow用户
提问于 2016-03-04 09:49:19
回答 1查看 330关注 0票数 0

据我所知,顶点抓取阶段是由VAO封装的,VAO需要包含顶点抓取阶段状态,以便在缓冲区对象和顶点属性之间进行管道传输,以及格式化缓冲区对象中的数据。

我读过的两本关于i.Red主题的书,蓝皮书都明确提到VAO必须包含顶点fetch阶段状态数据

然而,当我实际创建2个纹理对象并简单地格式化数据一次而没有VAO来存储关于buffer的信息时,它仍然运行得很好,没有任何问题,然后我再次重新加载第一个对象,它同样工作得很好,没有任何问题,那么这些关于buffer对象中数据格式化的信息是从哪里提取的呢?

我甚至第二次将buffer数据上传到同一个buffer对象,这意味着之前保存在那里的信息将被重置?并且图片仍然可以很好地呈现在窗口上

那么到底是怎么回事呢?书中说了一件事,现实中发生的事情是完全不同和相反的

有人能解释一下这里到底需要什么,不需要什么吗?到底是怎么回事?

什么时候我们真的需要VAO,什么时候我们可以不用呢?当不需要额外的代码处理时,它的意义是什么?

代码如下:

代码语言:javascript
复制
int main(){

   int scrW=1280, scrH=720;

   //create context and shader program
   init(scrW, scrH);
   createShaders();

   //create texture objects and load data from image to server memory
   char object[2][25];
   strcpy(object[0], "back.bmp");
   strcpy(object[1], "256x256.bmp");


   //triangle 1
   GLfloat vertices[] = 
   //  X      Y      U    V
   {  -1.0, -1.0,   0.0, 0.0,
       1.0, -1.0,   1.0, 0.0,
       1.0,  1.0,   1.0, 1.0,
      -1.0,  1.0,   0.0, 1.0};


   //glPointSize(40.0f);

   //create and bound vertex buffer object(memory buffers)   
   GLuint vbo1 = createVbo();

   //The state set by glVertexAttribPointer() is stored in the currently bound vertex array object (VAO) if vertex array object bound
   //associates the format of the data for the currently bound buffer object to the vertex attribute so opengl knows how much and how to read it
   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
   glEnableVertexAttribArray(0);

   //shader vertex attribute for texture coordinates
   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (const GLvoid*)(2 * sizeof(GLfloat)));
   glEnableVertexAttribArray(1);

   //upload vertices to buffer memory
   //will upload data to currently bound/active buffer object
   glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  

   //load and create texture object from image data
   GLuint tex1 = createTexture(object[0]);

   glDrawArrays(GL_QUADS, 0, 4);

   glXSwapBuffers ( dpy, glxWin );
   sleep(3);


   GLuint tex2 = createTexture(object[1]);

   glDrawArrays(GL_QUADS, 0, 4);


   glXSwapBuffers ( dpy, glxWin );
   sleep(3);

   glBindTexture(GL_TEXTURE_2D, tex1);

   glDrawArrays(GL_QUADS, 0, 4);


   glXSwapBuffers ( dpy, glxWin );
   sleep(3);


   //////////////de-initialize
   glXMakeContextCurrent( dpy, 0, 0, NULL );
   glXDestroyContext( dpy, context );
   glXDestroyWindow(dpy, glxWin);
   XDestroyWindow( dpy, win );
   XCloseDisplay( dpy );

   return 0;
}

和着色器

代码语言:javascript
复制
 const char* vertex_shader =
      "#version 400\n"
      "layout(location =  0) in vec2 vp;"
      "layout(location = 1) in vec2 tex;"
      "out vec2 texCoord;"
      "void main () {"
      "  gl_Position = vec4 (vp, 0.0f, 1.0f);"
      "  texCoord = tex; "
      "}";

   const char* fragment_shader =
      "#version 400\n"
      "uniform sampler2D s;"
      "in vec2 texCoord;"
      "out vec4 color;"
      "void main () {"
      "color = texture(s, texCoord);"
      "}";

为了避免混淆,下面是init()过程

代码语言:javascript
复制
 static int att[] =
   {
      GLX_X_RENDERABLE    , True,
      GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
      GLX_RENDER_TYPE     , GLX_RGBA_BIT,
      GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
      GLX_RED_SIZE        , 8,
      GLX_GREEN_SIZE      , 8,
      GLX_BLUE_SIZE       , 8,
      GLX_ALPHA_SIZE      , 8,
      GLX_DEPTH_SIZE      , 24,
      GLX_STENCIL_SIZE    , 8,
      GLX_DOUBLEBUFFER    , True,
      //GLX_SAMPLE_BUFFERS  , 1,
      //GLX_SAMPLES         , 4,
      None
   };

   Display                          *dpy;
   Window                            root;   
   XVisualInfo                      *vi;
   Colormap                          cmap;
   XSetWindowAttributes              swa;
   Window                            win;
   GLXContext                        context;
   GLXFBConfig                      *fbc;
   GLXWindow                         glxWin; 
   int                               fbcount;


void init(int width, int height){

   //set and choose displays for creating window
   dpy = XOpenDisplay(NULL);
   if (!dpy){
      printf("Failed to open X display\n");
      exit(1);
   }   

   root = DefaultRootWindow(dpy);

   //request a framebuffer configuration
   fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), att, &fbcount);

   if (!fbc){
      printf( "Failed to retrieve a framebuffer config\n" );
      exit(1);
   }

   vi = glXGetVisualFromFBConfig( dpy, fbc[0] );

   if(vi==NULL){
      printf("Error getting visual info\n");
      exit(1);
   }
   swa.colormap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );

   swa.background_pixmap = None ;
   swa.border_pixel            = 0;
   swa.event_mask            = StructureNotifyMask;

   //Window XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valuemask, attributes) 

   win = XCreateWindow( dpy, RootWindow( dpy, vi->screen ), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa );
   if ( !win ){
      printf( "Failed to create window.\n" );
      exit(1);
   }

   context = glXCreateNewContext( dpy, fbc[0], GLX_RGBA_TYPE, NULL, True );

   glxWin = glXCreateWindow(dpy, fbc[0], win, NULL);

   XMapWindow(dpy, win);

   glXMakeContextCurrent(dpy, glxWin, glxWin, context);

   // start GLEW extension handler
   glewExperimental = GL_TRUE;
   GLuint err = glewInit();

   if(err!=GLEW_OK){
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
      exit(1);
   }


   XSelectInput(dpy, win, ButtonPressMask|KeyPressMask);

   // tell GL to only draw onto a pixel if the shape is closer to the viewer
   //glEnable (GL_DEPTH_TEST); // enable depth-testing
   //glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"


}
EN

回答 1

Stack Overflow用户

发布于 2016-03-04 09:55:32

如果使用兼容性OpenGL上下文,则不需要VAO。从某种意义上说,有一个“默认”的VAO总是被绑定的。这就是它在OpenGL 2.x中的工作方式,这也是“兼容性配置文件”中“兼容性”含义的一部分。

在使用核心OpenGL上下文时,您确实需要一个VAO。如果你不这样做,你的代码就不能工作。如果你想继续假装你不需要一个VAO,你可以创建一个单独的VAO,并在整个程序期间绑定它。

选择核心配置文件与兼容性配置文件的问题有其细微差别,但一般来说,如果您正在开发新程序,建议您请求核心配置文件。无论如何,并不是所有的系统都对兼容性配置文件有很好的支持。Mesa将兼容性配置文件限制为3.0,而OS X将其限制为2.1。如果您需要核心概要文件,则必须在创建上下文时显式请求核心概要文件。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35786560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档