Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fonts 如何使用SDL2高效地呈现字体和文本?_Fonts_Sdl_Sdl 2_Truetype_Sdl Ttf - Fatal编程技术网

Fonts 如何使用SDL2高效地呈现字体和文本?

Fonts 如何使用SDL2高效地呈现字体和文本?,fonts,sdl,sdl-2,truetype,sdl-ttf,Fonts,Sdl,Sdl 2,Truetype,Sdl Ttf,看到了这篇关于在游戏中使用SDL_ttf渲染文本的文章。但是,这种方法需要在每一帧调用SDL_CreateTextureFromSurface()以及SDL_FreeSurface()和SDL_DestroyTexture() 每帧创建纹理(可能随后必须发送到GPU)是否会对我的性能产生重大影响 使用SDL_ttf只使用我的整个渲染字符集创建一个纹理,然后从那里逐个字符地进行blit,这是否更明智 编辑:我只希望用美式英语(基本ASCII)呈现简单的单空间字体。是的,每帧创建纹理都会影响性能。此

看到了这篇关于在游戏中使用SDL_ttf渲染文本的文章。但是,这种方法需要在每一帧调用SDL_CreateTextureFromSurface()以及SDL_FreeSurface()和SDL_DestroyTexture()

每帧创建纹理(可能随后必须发送到GPU)是否会对我的性能产生重大影响

使用SDL_ttf只使用我的整个渲染字符集创建一个纹理,然后从那里逐个字符地进行blit,这是否更明智


编辑:我只希望用美式英语(基本ASCII)呈现简单的单空间字体。

是的,每帧创建纹理都会影响性能。此外,将TrueType字体栅格化到SDL_曲面(就像SDL_ttf一样)每帧都会影响性能

我推荐SDL_FontCache(完全公开:我是作者)。它使用SDL_ttf并在纹理中缓存生成的图示符,因此您不必自己完成所有操作:

OpenGL文本方法

使用OpenGL更有可能找到一个高效的实现,因为它比SDL使用得更广泛,请参见:

目前,我选择的是freetype gl:它支持即时可用的纹理图集

SDL很好地支持OpenGL,如果您已经在程序中使用SDL纹理,您甚至可以在单个程序中同时使用GL和SDL纹理,例如:

#include <SDL2/SDL.h>
#define GLEW_STATIC
#include <GL/glew.h>

int main(void) {
    SDL_GLContext gl_context;
    SDL_Event event;
    SDL_Renderer *renderer = NULL;
    SDL_Texture *texture = NULL;
    SDL_Window *window = NULL;
    Uint8 *base;
    const unsigned int
        WINDOW_WIDTH = 500,
        WINDOW_HEIGHT = WINDOW_WIDTH
    ;
    int pitch;
    unsigned int x, y;
    void *pixels = NULL;

    /* Window setup. */
    SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
    window = SDL_CreateWindow(
        __FILE__, 0, 0,
        WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL
    );
    renderer = SDL_CreateRenderer(window, 0, 0);
    gl_context = SDL_GL_CreateContext(window);

    /* GL drawing. */
    glClearColor(1.0, 0.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    /* Wrapped texture drawing. */
    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
        SDL_TEXTUREACCESS_STREAMING, WINDOW_WIDTH, WINDOW_HEIGHT);
    SDL_LockTexture(texture, NULL, &pixels, &pitch);
    for (x = 0; x < WINDOW_WIDTH; x++) {
        for (y = 0; y < WINDOW_HEIGHT; y++) {
            base = ((Uint8 *)pixels) + (4 * (x * WINDOW_WIDTH + y));
            base[0] = 0;
            base[1] = 0;
            base[2] = 255;
            base[3] = 255;
        }
    }
    SDL_UnlockTexture(texture);
    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = WINDOW_WIDTH / 2;
    rect.h = WINDOW_HEIGHT / 2;
    SDL_RenderCopy(renderer, texture, NULL, &rect);
    SDL_GL_SwapWindow(window);

    /* Main loop. */
    while (1) {
        if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
            break;
    }

    /* Cleanup. */
    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return EXIT_SUCCESS;
}
在Ubuntu 17.10中测试


GitHub upstream:

也许吧,但请记住,使用现代字体“绘制文本”与“获取字母,然后将它们放在彼此旁边”完全不同(1984年字体就是这样工作的。从那时起,我们一直在进步)。现代字体将字母组合在一起,调整它们之间的间距,在必要时进行细微的替换,根据所选的点大小平滑轮廓,以及将字体基本上视为位图而丢失的许多其他内容。同意,但是为了便于讨论,我们假设我们只使用简单的单空格字体和ASCII字符。我试图大致了解所有这些纹理的创建和删除在CPU/GPU使用方面需要什么Fair point(值得添加到文章中)只需渲染一次文本,保留此纹理直到文本值发生更改,并在文本不相同时重新绘制纹理。使用这种方法,您将不会在每一帧重新绘制文本,并将节省一点渲染时间。我在寻找此问题的解决方案时遇到了这个问题。我想解决这个问题的方法是使用一个缓冲曲面,在这个曲面上,我将使用BlitSurface移动给定帧上的所有文本,然后,在所有文本添加到它之后,创建它的纹理并绘制它。这是一个很好的解决方案,还是每一帧都是性能命中循环?我对SDL2如何在较低级别上工作的了解不是很好,因此如果您能向我解释为什么或者为什么这不是一个好的解决方案,我将非常高兴。谢谢。所以确实有人已经想到了这一点,甚至实施了它。非常感谢的链接,看起来像一个非常好的项目!不客气。代码在C++ nFoT项目中已经存在了多年,但直到最近我才将它拉到自己的库中以更好地重用(和C支持)。这只适用于SDL吗?不是SDL2?另外,我听说SDL_ttf source有一个
SetFontSize()
,可以更改
ttf_字体的大小*
。这是否会影响FontCache中保留的结构?它实际上假定为SDL2,如果不进行一些修改,就无法使用SDL1。如果SetFontSize()是公开的,我认为它不会影响SDL_FontCache中的结构。只要别把地毯从图书馆下面拉出来就好了。
gcc -std=c99 main.c -lSDL2 -lGL
./a.out