You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu系统下SDL2窗口运行后无法显示的问题求助

SDL2创建空白窗口无显示问题解决

我用C语言结合SDL2编写了一个简单的空白窗口程序,编译无错误,但运行后窗口不显示,while循环持续运行。

原始代码

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

#include <SDL2/SDL.h>

void manageEvents(bool* launched) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
            case SDL_QUIT:
                *launched = false;
                break;

            default:
                break;
        }
    }
}

int main() {
    if(SDL_Init(SDL_INIT_VIDEO) < 0){
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
        return 1;
    }

    SDL_Window* window = SDL_CreateWindow("Mandelbrot :)", 0, 0, 800, 600, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);


    if (window == NULL) {
        printf("No window pointer\n");
        return 1;
    }
    
    bool launched = true;

    while (launched) {
        manageEvents(&launched);
    }

    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);

    SDL_Quit();

    return 0;
}

环境与编译信息

  • 系统:Ubuntu 22.04.2 LTS
  • SDL版本:2.28.0
  • 安装命令:
sudo apt-get install libsdl2-2.0-0
sudo apt-get install libsdl2-dev
  • 编译命令:
gcc ./main.c -o out -Wextra -Wall -Werror -lSDL2

已尝试的无效操作

  • 确认window指针不为空
  • 在while循环前添加SDL_ShowWindow(window);
  • 在循环内添加SDL_RenderClear(renderer);和SDL_RenderPresent(renderer);
  • 编译SDL官方源码重新安装

问题原因与解决方案

核心问题在于事件循环没有给窗口管理器留出更新界面的时间,同时原始代码存在渲染流程不完整、资源检查缺失的问题。以下是修复后的完整代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

#include <SDL2/SDL.h>

void manageEvents(bool* launched) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
            case SDL_QUIT:
                *launched = false;
                break;

            default:
                break;
        }
    }
}

int main() {
    if(SDL_Init(SDL_INIT_VIDEO) < 0){
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
        return 1;
    }

    // 使用居中位置创建窗口,避免0,0导致窗口出现在屏幕可视区域外
    SDL_Window* window = SDL_CreateWindow("Mandelbrot :)", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
    if (window == NULL) {
        printf("No window pointer\n");
        SDL_Quit();
        return 1;
    }

    // 使用硬件加速渲染器并开启垂直同步,提升渲染效率
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == NULL) {
        printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    
    bool launched = true;

    while (launched) {
        manageEvents(&launched);

        // 完整渲染流程:设置背景色→清空缓冲区→提交渲染到窗口
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);

        // 添加延迟降低CPU占用,同时给窗口系统留出界面更新时间
        SDL_Delay(16);
    }

    // 规范资源销毁顺序:先销毁渲染器,再销毁窗口
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;
}

关键修改点

  1. 窗口位置修正:用SDL_WINDOWPOS_CENTERED替代0,0,避免窗口被放置在屏幕可视区域外
  2. 渲染器检查:添加渲染器空指针检查,避免后续无效操作导致的隐性问题
  3. 完整渲染流程:必须先设置绘制颜色,再执行清空和提交操作,触发窗口界面更新
  4. CPU占用优化:添加SDL_Delay(16)(约60帧间隔),给窗口管理器留出界面更新的时间
  5. 资源销毁顺序:先销毁渲染器再销毁窗口,符合SDL资源管理规范

内容的提问来源于stack exchange,提问作者Yolwoocle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:15:14