SDL - 窗口不显示任何内容

时间:2014-02-22 10:46:28

标签: c++ linux sdl-2

我在SDL(C ++)中迈出了第一步,从www获得了一些教程。

但有一个问题。我在我的Linux Mint系统上安装了SDL2,编译了教程代码:

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (win == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Renderer *ren = SDL_CreateRenderer(win, -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == NULL){
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
    if (bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
    SDL_FreeSurface(bmp);
    if (tex == NULL){
        std::cout << "SDL_CreateTextureFromSurface Error: "
            << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Delay(4000);

    SDL_DestroyTexture(tex);
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}

使用此编译命令:

g++ main.cpp -lSDL2 -o prog

我得到了这个:

A window frame without any inside

没有任何内部的窗框。我必须在哪里查找错误



最终守则

首先:感谢starrify!

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{

    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *window = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (window == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }
/*
    SDL_Renderer *ren = SDL_CreateRenderer(window, -1,
    SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (ren == NULL){
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }
*/
    SDL_Surface *surface_bmp = SDL_LoadBMP("cb.bmp");
    if (surface_bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }
/*
    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, surface_bmp);
    SDL_FreeSurface(surface_bmp);
    if (tex == NULL){
        std::cout << "SDL_CreateTextureFromSurface Error: "
            << SDL_GetError() << std::endl;
        return 1;
    }
*/

    SDL_Surface *surface_window = SDL_GetWindowSurface(window);

    /*
     * Copies the bmp surface to the window surface
     */
    SDL_BlitSurface(surface_bmp,
                    NULL,
                    surface_window,
                    NULL);

    /*
     * Now updating the window
     */
    SDL_UpdateWindowSurface(window);

    /*
     * This function used to update a window with OpenGL rendering.
     * This is used with double-buffered OpenGL contexts, which are the default.
     */
/*    SDL_GL_SwapWindow(window); */

    SDL_Delay(5000);

/*    SDL_DestroyTexture(tex);*/
/*    SDL_DestroyRenderer(ren);*/
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

告诉我这个结果:) enter image description here

我看到它真的很容易。这样我就不需要用于绘图的openGL了。这将是下一步。 如果你帮我改进这个例子来使用openGL来实现它,那就太好了。

2 个答案:

答案 0 :(得分:4)

  

SDL - 窗口没有显示任何内容

原因是你没有画任何东西。您创建了一个窗口,一个渲染器,一个曲面和一个纹理。但是你不是绘图任何东西。视觉效果完全反映了你的所作所为。

要简单地显示BMP图像,请将图像加载到曲面中,然后使用SDL_BlitSurface将其复制到屏幕上。或者要使用纹理,您应该像使用OpenGL一样绘制三角形或四边形等基元。

另一个问题是:为什么你的窗口看起来充满了除空白屏幕之外的其他内容? 那是因为这些年默认视频模式设置为double buffering,这意味着要显示前缓冲区和渲染后缓冲区。完成渲染单帧后,您应调用类似SDL_Flip的内容(似乎已在SDL2中废弃)或SDL_UpdateWindowSurface

已编辑:我已编辑了您的代码,这里的内容有效:(已移除渲染器/纹理,添加了SDL_BlitSurface和SDL_UpdateWindowSurface)

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <stdio.h>
#include <SDL2/SDL.h>

#include <iostream>

int main ( int argc, char** argv )
{
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
    SDL_WINDOW_SHOWN);
    if (win == NULL){
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
    if (bmp == NULL){
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    SDL_BlitSurface(bmp, 0, SDL_GetWindowSurface(win), 0);
    SDL_UpdateWindowSurface(win);

    SDL_Delay(4000);

    SDL_DestroyWindow(win);
    SDL_Quit();

    return 0;
}

答案 1 :(得分:2)

由于您使用的是SDL2,因此不应使用SDL_Surface来更新屏幕。这是SDL 1.2必须使用的旧方法。新的渲染器子系统是您想要的一般用途,因为它是硬件加速的(使用GPU),而SDL_BlitSurface()和SDL_UpdateWindowSurface()则不是(所有像素复制都在CPU上完成)。

所以这是做什么的。不要使用SDL_GetWindowSurface()。使用以前的代码创建渲染器和纹理。用调用SDL_RenderCopy()替换SDL_BlitSurface()。用调用SDL_RenderPresent()替换SDL_UpdateWindowSurface()。

或者,您可以使用SDL_gpu(注意:我是作者),感觉就像旧的SDL 1.2 blitting API,但具有比SDL_Renderer更多的功能和优化。