Linux/Ubuntu下SDL窗口不显示但事件循环正常的问题求助
SDL2 OpenGL窗口无法显示的问题修复(初代Surface Book + Ubuntu)
在初代Surface Book的Ubuntu系统中使用SDL2编写OpenGL程序,程序编译运行正常,事件循环经
cout验证可正常工作,但SDL窗口始终无法显示。已将Mesa更新至20.3.0,设备支持OpenGL 4.6,且尝试在SDL_Init()前调用SDL_SetMainReady(),问题仍未解决。
解决方案
针对该问题,可通过以下几点修改修复:
- 显式添加窗口显示标志:确保窗口创建后立即显示
- 初始化OpenGL视口并清除缓冲:避免因无绘制内容导致窗口“空白不可见”
- 设置垂直同步:确保缓冲交换逻辑正常触发
- 处理双显卡切换(Surface Book特有):强制程序指定使用集成/独立显卡
修改后的完整代码
#include <SDL2/SDL.h> #include <iostream> // Globals int gScreenWidth = 640; int gScreenHeight = 480; SDL_Window* gWindow = nullptr; SDL_GLContext gContext = nullptr; bool gQuit = false; // if true we quit void InitializeProgram(){ if(SDL_Init(SDL_INIT_VIDEO) < 0){ std::cout << "SDL2 could not initialize video subsystem" << std::endl; exit(1); } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // 添加SDL_WINDOW_SHOWN标志确保窗口显示 gWindow = SDL_CreateWindow("OpenGL First Program", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, gScreenWidth, gScreenHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if(gWindow == nullptr){ std::cout << "SDL Window could not be created" << std::endl; exit(1); } gContext = SDL_GL_CreateContext(gWindow); if(gContext == nullptr){ std::cout << "OpenGL Context could not be created" << std::endl; exit(1); } // 设置OpenGL视口 glViewport(0, 0, gScreenWidth, gScreenHeight); // 启用垂直同步,确保缓冲交换正常 SDL_GL_SetSwapInterval(1); } void Input(){ SDL_Event e; while(SDL_PollEvent(&e)){ if(e.type == SDL_QUIT){ std::cout << "Goodbye!" << std::endl; gQuit = true; } } } void PreDraw(){ // 清除颜色缓冲,设置背景色 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); } void Draw(){ // 可在此添加绘制逻辑,比如简单三角形 } void MainLoop(){ while(!gQuit){ Input(); PreDraw(); Draw(); SDL_GL_SwapWindow(gWindow); // Updates the screen } } void CleanUp(){ SDL_GL_DeleteContext(gContext); // 别忘了删除GL上下文 SDL_DestroyWindow(gWindow); SDL_Quit(); } int main(){ InitializeProgram(); MainLoop(); CleanUp(); return 0; }
关键修改说明
窗口显示标志:
部分桌面环境或双显卡设备下,SDL_CreateWindow默认创建的窗口可能被隐藏,显式添加SDL_WINDOW_SHOWN可强制窗口显示。视口与缓冲清除:
原代码无任何OpenGL绘制操作,也未清除缓冲,导致交换缓冲时无有效内容,窗口会呈现与桌面融合的“透明”状态。添加glClear后会填充固定背景色,窗口立即可见。垂直同步设置:
SDL_GL_SetSwapInterval(1)强制缓冲交换与显示器垂直同步,避免因交换过快导致的渲染异常,同时减少屏幕撕裂。双显卡处理:
初代Surface Book配备Intel集成显卡和NVIDIA独立显卡,Ubuntu下可能存在切换问题。可通过以下命令强制指定显卡:- 强制使用集成显卡:
__GLX_VENDOR_LIBRARY_NAME=mesa ./your_program - 强制使用NVIDIA显卡:
__GLX_VENDOR_LIBRARY_NAME=nvidia ./your_program
- 强制使用集成显卡:
内容的提问来源于stack exchange,提问作者JackAttack31
相关产品推荐
相关产品推荐

