gpt4 book ai didi

c++ - 不需要有 VAO?

转载 作者:行者123 更新时间:2023-11-28 00:05:40 27 4
gpt4 key购买 nike

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

我一直在阅读的关于这个主题的两本书,红皮书,蓝皮书都明确提到 VAO 必须包含顶点获取阶段状态数据

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

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

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

有人可以真正解释这里实际需要什么,不需要什么吗?到底发生了什么?

我们什么时候真正需要 VAO,什么时候可以不用?在不需要时进行额外的代码处理有什么意义?

下面的代码:

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;
}

和着色器

 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() 过程

 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"


}

最佳答案

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

在您使用核心 OpenGL 上下文时,您确实需要一个 VAO。如果不这样做,您的代码将无法正常工作。如果你想继续假装你不需要 VAO,你可以创建一个 VAO 并在你的程序的整个持续时间内绑定(bind)它。

选择核心配置文件与兼容性配置文件的问题有其细微差别,但通常建议您在开发新程序时申请核心配置文件。无论如何,并非所有系统都对兼容性配置文件有很好的支持。 Mesa 将兼容性配置文件限制为 3.0,而 OS X 将它们限制为 2.1。如果您想要核心配置文件,则必须在创建上下文时明确请求核心配置文件。

关于c++ - 不需要有 VAO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35786560/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com