據我瞭解,頂點提取階段被VAO封裝,並且VAO需要包含緩衝區對象和頂點屬性之間的管道的頂點提取階段狀態以及格式化緩衝區對象中的數據。不需要有一個VAO?
這兩本書,我一直在閱讀關於這個問題i.Red書,藍皮書都明確提及當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的,你沒有在你的回答中解決所有問題 – hopjopper
@hopjopper是什麼讓你如此相信你有一個核心配置文件的上下文?我在發佈的代碼中沒有看到特別要求核心上下文的任何內容。 –
以及我相信,兼容性配置文件不是默認的,並被要求,而核心配置文件是默認的,我真的不知道你爲什麼試圖回答一個假設的問題,誠實地..... – hopjopper