OpenGl-glViewport调用重置vao、vbo和着色器程序



因此,我按照本教程从OpenGL开始,并设法使所有内容都画得很好,但当我调整视口大小时,vao、vbo和着色器程序将解除绑定。我需要重新绑定所有内容并重新发送缓冲区数据,我不知道这是否是预期的行为,但这对我来说有点荒谬,所以我可能错过了什么。我做了一些搜索,尝试了几种不同的方法(使用/不使用vaos,使用glVertexAttribFormat/glVertexAttribBinding…(,但没有任何进展。

我制作了一个logGl函数来获取尽可能多的信息:

void logGl() {
int value, value2;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &value);
std::cout << "bound buffer: " << value << std::endl;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &value);
std::cout << "bound vao: " << value << std::endl;
glGetIntegerv(GL_CURRENT_PROGRAM, &value);
std::cout << "bound program: " << value << std::endl;
glGetIntegerv(GL_MAJOR_VERSION, &value);
glGetIntegerv(GL_MINOR_VERSION, &value2);
std::cout << "GL version: " << value << "." << value2 << std::endl;
float data[9];
glGetBufferSubData(GL_ARRAY_BUFFER, 0, 9 * sizeof(float), data);
std::cout << "Buffer Data: ";
for (size_t i=0; i<9; i++) { std::cout << data[i] << " ";};
std::cout << std::endl;
}

这是输出:

Shader Program ID: 3
bound buffer: 1
bound vao: 1
bound program: 3
GL version: 4.6
Buffer Data: -0.5 -0.5 0 0 0.5 0 0.5 -0.5 0 
changing viewport ******* 
bound buffer: 0
bound vao: 0
bound program: 0
GL version: 4.6
Buffer Data: 1.23555e-31 4.59163e-41 28.875 0 30.0201 0 2.05719e+32 4.55772e-41 1.23552e-31 
We see everything is unbound (Here I recreate shader program)
Shader Program ID: 39
Viewport size: 0 0 801 600
In main loop, just before isssuing draw call:
bound buffer: 1
bound vao: 0
bound program: 39
GL version: 4.6
Buffer Data: 3.8357e+34 4.55772e-41 3.47159e+34 4.55772e-41 4.56443e+34 4.55772e-41 1.5695e+11 3.09e-41 1.23552e-31 
Error: 1282
--------------------------------

错误代码1282并没有真正为我提供任何线索,我没有从我的setShaders函数中得到任何编译/链接错误。

这是我的主循环,如果需要,我可以提供着色器函数的实现,但这几乎是教程。。

int main() {
// Init SDL, get GL context, set initial viewport init glew ...
Systems sys = initWindow(800, 600);
// Init a buffer
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
unsigned int vbo, vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);   // bind first!
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
unsigned int shader = setShaders("Shaders.txt");
logGl();
bool running = true;
while (running) {
bool log = false;
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) running = false;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
int dims[4];
std::cout << "changing viewport ******* n";
glViewport(0, 0, event.window.data1, event.window.data2);
//                            glViewport(0, 0, 500, 500);
logGl();
std::cout << "We see everything is unbound" << std::endl;
// Updating viewport unbinds vao, shader program
// and seems to empty vbo data
// since I get this error code after viewport call at glDraw:
shader = setShaders("Shaders.txt");
glUseProgram(shader);
glGetIntegerv(GL_VIEWPORT, dims);
std::cout << "Viewport size: "
<< dims[0] << " "
<< dims[1] << " "
<< dims[2] << " "
<< dims[3] << std::endl;
log = true;
}
}
}
// random bg color
Uint32 rdCol = SDL_GetPerformanceCounter();
glClearColor((float) (rdCol & 0x0000FF00) / 0x0000FF00,
(float) (rdCol & 0x00FF0000) / 0x00FF0000,
(float) (rdCol & 0xFF000000) / 0xFF000000, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Why is this not needed ..???
glBindVertexArray(vao);
///////////////////////////////////////////////////////////////////////
// *** The four lines below are necessary to keep drawing on win resize
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//
//        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);
//        glEnableVertexAttribArray(0);
///////////////////////////////////////////////////////////////////////

if (log) {
std::cout << "In main loop, just before isssuing draw call:" << std::endl;
logGl();
std::cout << "Error: " << glGetError() << std::endl;
std::cout << "--------------------------------" << std::endl;
}
glDrawArrays(GL_TRIANGLES, 0, 3);
/* 'flip' Window */
SDL_GL_SwapWindow(sys.window);
}
SDL_FreeSurface(sys.winSurf);
SDL_DestroyWindow(sys.window);
SDL_Quit();
return 0;
}

因此,最大的问题是,当我调用glViewport时,为什么所有东西都会被解除绑定,因为我认为它应该只通过绑定vao和vbo来保持绘图(这在我调整窗口大小之前一直有效(

我发现了罪魁祸首,那就是在SDL中调整窗口大小时,它会创建一个新的OpenGL上下文,从而删除所有绑定。所以,我可以重新绑定所有内容(荒谬但有效(,也可以使用GLFW、SFML或其他库。如果有人遇到这个问题,我在这里找到了答案。

最新更新