OpenGL应用窗口调整时画面冻结,仅拖动过程中更新问题求助
问题解决:OpenGL窗口拖拽调整大小时画面停止更新
问题分析
核心问题有两点:一是窗口拖拽过程中按住鼠标不动时,操作系统会接管窗口消息循环,导致程序主循环被阻塞,无法持续执行渲染;二是你在帧缓冲尺寸回调中额外调用draw()的逻辑不仅冗余,还会导致time变量异常增长,引发渲染逻辑混乱。此外draw()函数中glClearColor与glClear的调用顺序错误,会导致清除颜色的设置无法及时生效。
修复步骤
修正渲染顺序
glClearColor用于设置帧缓冲的清除颜色,必须在glClear之前调用,否则当前帧的清除操作无法使用新设置的颜色。移除回调中的冗余渲染调用
帧缓冲尺寸回调仅需负责更新视口,所有渲染逻辑统一放在主循环中,避免重复渲染导致的状态异常。优化事件循环,避免拖拽阻塞
使用glfwWaitEventsTimeout()替代glfwPollEvents(),让程序在等待事件的同时,每隔固定时间(如1/60秒,对应60帧刷新率)唤醒执行渲染,确保拖拽过程中画面持续更新。
修正后的代码
framebuffercallback.c
void frame_buffer_callback(GLFWwindow* window, int width, int height){ glViewport(0,0,width,height); printf("Window resized x:%d\ty:%d\n", width, height); }
draw.c
float time = 0.0f; void draw(GLFWwindow *window){ // 先设置清除颜色,再执行帧缓冲清除 glClearColor(cos(time), sin(time), 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); time += 0.01667f; glfwSwapBuffers(window); }
main.c
#define WIDTH 640 #define HEIGHT 480 int main(int argc, char* argv[]){ if(!glfwInit()){ fprintf(stderr, "Could not initialize glfw\n"); exit(EXIT_FAILURE); } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(WIDTH,HEIGHT, "My Window", NULL, NULL); if(window == NULL){ fprintf(stderr, "Could not open window"); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, frame_buffer_callback); frame_buffer_callback(window, WIDTH, HEIGHT); while(!glfwWindowShouldClose(window)){ draw(window); // 等待事件并设置超时,确保每秒至少渲染60次 glfwWaitEventsTimeout(1.0/60.0); } glfwDestroyWindow(window); glfwTerminate(); // 释放GLFW资源 return 0; }
额外说明
glfwWaitEventsTimeout()兼顾了事件响应与渲染连续性,彻底解决窗口拖拽时画面停止更新的问题。- 添加
glfwTerminate()是规范的资源释放操作,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Luca Rossin
相关产品推荐
相关产品推荐

