Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >(译)SDL编程入门(16)TrueType字体

(译)SDL编程入门(16)TrueType字体

作者头像
arcticfox
发布于 2020-10-29 02:13:48
发布于 2020-10-29 02:13:48
1K00
代码可运行
举报
运行总次数:0
代码可运行

TrueType字体

使用SDL渲染文本的一种方法是使用扩展库SDL_ttf。SDL_ttf允许你从TrueType字体中创建图像,我们将在这里使用它从字体文本中创建纹理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 使用SDL、SDL_image、SDL_ttf、标准IO、math和string
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include <string>
#include <cmath>

要使用 SDL_ttf,你必须设置 SDL_ttf 扩展库[1],就像你 设置 SDL_image一样。就像之前一样,只是把头文件、库文件和二进制文件放在正确的位置,并把编译器配置成使用它们。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//Texture wrapper class
class LTexture
{
    public:
        //Initializes variables
        LTexture();

        //Deallocates memory
        ~LTexture();

        //Loads image at specified path
        bool loadFromFile( std::string path );
        
        //Creates image from font string
        bool loadFromRenderedText( std::string textureText, SDL_Color textColor );

        //Deallocates texture
        void free();

        //Set color modulation
        void setColor( Uint8 red, Uint8 green, Uint8 blue );

        //Set blending
        void setBlendMode( SDL_BlendMode blending );

        //Set alpha modulation
        void setAlpha( Uint8 alpha );
        
        //Renders texture at given point
        void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );

        //Gets image dimensions
        int getWidth();
        int getHeight();

    private:
        //The actual hardware texture
        SDL_Texture* mTexture;

        //Image dimensions
        int mWidth;
        int mHeight;
};

在这里,我们在texture class中添加了另一个函数,叫做loadFromRenderedText。SDL_ttf的工作方式是从字体和颜色中创建一个新的图像。对于我们的纹理类来说,这意味着我们将从SDL_ttf渲染文本而不是从文件中加载图像。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//我们要渲染的窗口
SDL_Window* gWindow = NULL;

//窗口渲染器
SDL_Renderer* gRenderer = NULL;

//全局通用的字体
TTF_Font *gFont = NULL;

//渲染纹理
LTexture gTextTexture;

在本教程和未来的教程中,我们将使用全局字体进行文本渲染。在SDL_ttf中,字体的数据类型是TTF_Font。

我们还有一个纹理,它将由字体生成。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool LTexture::loadFromRenderedText( std::string textureText, SDL_Color textColor ){
    //释放已有的纹理
    free();

    //渲染文本表面
    SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor );
    if( textSurface == NULL ){
        printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
    }else{
        //从表面像素创建纹理
        mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface );
        if( mTexture == NULL ){
            printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
        }else{
            //Get image dimensions
            mWidth = textSurface->w;
            mHeight = textSurface->h;
        }

        //释放旧表面
        SDL_FreeSurface( textSurface );
    }
    
    //Return success
    return mTexture != NULL;
}

这里是我们实际创建文本纹理的地方,我们将从字体中渲染。这个函数接收我们想要渲染的文本字符串和我们想要用来渲染它的颜色。之后,这个函数的工作原理和从文件中加载文字的工作原理差不多,只是这次我们使用的是SDL_ttf创建的SDL_Surface而不是文件。

在释放任何预存在的纹理后,我们使用 TTF_RenderText_Solid[2] 加载一个表面。这将从给定的字体、文本和颜色中创建一个纯色表面。如果表面创建成功,我们将从中创建一个纹理,就像之前从文件中加载表面时一样。在创建纹理后,我们可以像其他纹理一样用它进行渲染。

还有其他方法可以渲染出更平滑或混合的文本。实验一下SDL_ttf文档[3]中概述的不同类型的渲染。Shaded/Blended 渲染可能对不同大小的文本效果更好。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//初始化PNG加载
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) ){
    printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
    success = false;
}

//初始化 SDL_ttf
if( TTF_Init() == -1 ){
    printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() );
    success = false;
}

就像SDL_image一样,我们必须对它进行初始化,否则字体加载和渲染功能将无法正常工作。我们使用TTF_init[4]来启动SDL_ttf。我们可以使用TTF_GetError()来检查错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool loadMedia(){
    //Loading success flag
    bool success = true;

    //Open the font
    gFont = TTF_OpenFont( "16_true_type_fonts/lazy.ttf", 28 );
    if( gFont == NULL ){
        printf( "Failed to load lazy font! SDL_ttf Error: %s\n", TTF_GetError() );
        success = false;
    }else{
        //Render text
        SDL_Color textColor = { 0, 0, 0 };
        if( !gTextTexture.loadFromRenderedText( "The quick brown fox jumps over the lazy dog", textColor ) ){
            printf( "Failed to render text texture!\n" );
            success = false;
        }
    }

    return success;
}

在我们的加载函数中,使用TTF_OpenFont[5]加载字体。这需要字体文件的路径和我们想要渲染的点大小。

如果字体加载成功,我们要使用加载方法加载一个文本纹理。作为一般规则,你要尽量减少渲染文本的次数。只有在需要的时候才重新渲染,由于我们在整个程序中使用的是同一个文本表面,所以我们只想渲染一次。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void close(){
    //Free loaded images
    gTextTexture.free();

    //Free global font
    TTF_CloseFont( gFont );
    gFont = NULL;

    //Destroy window
    SDL_DestroyRenderer( gRenderer );
    SDL_DestroyWindow( gWindow );
    gWindow = NULL;
    gRenderer = NULL;

    //Quit SDL subsystems
    TTF_Quit();
    IMG_Quit();
    SDL_Quit();
}

在我们的清理函数中,希望使用TTF_CloseFont[6]来释放字体。我们还想使用TTF_Quit[7]来退出SDL_ttf库,以完成清理工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//While application is running
while( !quit ){
    //Handle events on queue
    while( SDL_PollEvent( &e ) != 0 ){
        //User requests quit
        if( e.type == SDL_QUIT ){
            quit = true;
        }
    }

    //Clear screen
    SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
    SDL_RenderClear( gRenderer );

    //Render current frame
    gTextTexture.render( ( SCREEN_WIDTH - gTextTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gTextTexture.getHeight() ) / 2 );

    //Update screen
    SDL_RenderPresent( gRenderer );
}

正如你所看到的,在我们渲染了文本纹理之后,我们可以像其他纹理一样渲染它。

这里[8]下载本教程的媒体和源代码。

原文链接[9]

参考资料

[1]

SDL_ttf 扩展库: http://www.libsdl.org/projects/SDL_ttf/

[2]

TTF_RenderText_Solid: http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_43.html

[3]

SDL_ttf文档: http://www.libsdl.org/projects/docs/SDL_ttf/SDL_ttf_35.html

[4]

TTF_init: http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_8.html

[5]

TTF_OpenFont: http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_14.html

[6]

TTF_CloseFont: http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_18.html

[7]

TTF_Quit: http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_10.html

[8]

这里: http://www.lazyfoo.net/tutorials/SDL/16_true_type_fonts/16_true_type_fonts.zip

[9]

原文链接: http://www.lazyfoo.net/tutorials/SDL/16_true_type_fonts/index.php

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程之路从0到1 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
(译)SDL编程入门(21)音效和音乐
到目前为止,我们只是在处理视频和输入。大多数游戏制作都需要某种声音,这里我们将使用SDL_mixer为我们播放音频。
arcticfox
2021/01/06
1.2K0
(译)SDL编程入门(21)音效和音乐
(译)SDL编程入门(17)鼠标事件
和按键一样,SDL也有事件结构来处理鼠标事件,如鼠标运动、鼠标按钮按下和鼠标按钮释放。在本教程中,我们将制作一堆可以与之交互的按钮。
arcticfox
2020/10/29
1.7K0
(译)SDL编程入门(4)按键操作
点X关闭出窗口只是SDL能够处理的事件之一。另一种在游戏中大量使用的输入方式是键盘。在本教程中,我们将根据您所按的键来使不同的图像出现。
arcticfox
2020/09/24
1.1K0
(译)SDL编程入门(13)透明度混合
得益于新的硬件加速渲染,SDL2.0中的透明度变得更快。这里我们将使用alpha调制(它的工作原理很像颜色调制)来控制纹理的透明度。
arcticfox
2020/10/19
1.3K0
(译)SDL编程入门(13)透明度混合
(译)SDL编程入门(12)色彩调制
我们要在纹理包装器类中添加一个函数,允许设置纹理调制。它所要做的就是接收一个红、绿、蓝三色组件。
arcticfox
2020/10/09
6190
SDL的几个宽高概念讲解(文中有福利)
SDL系列讲解(一) 简介 SDL系列讲解(二) 环境搭建 SDL系列讲解(三) 工具安装 SDL是什么,能干什么,为什么我们要学习它? SDL系列讲解(四) demo讲解 SDL系列讲解(五) 调试c代码 SDL系列讲解(六) SDL_Activity流程 SDL系列讲解(七) SDL_image教程 SDL系列讲解(八) SDL_ttf教程 SDL系列讲解(九) 异常退出分析 SDL系列讲解(十) 按键处理流程 SDL系列讲解(十一) SDL_QUIT流程 SDL系列讲解(十二)创建窗口流程 a
用户1263308
2018/02/02
2K0
SDL的几个宽高概念讲解(文中有福利)
(译)SDL编程入门(10)Color Key
当在屏幕上渲染多个图像时,通常需要让图像具有透明背景。幸运的是,SDL提供了一种使用颜色键控的简单方法来实现这一点。
arcticfox
2020/10/09
1.2K0
(译)SDL编程入门(19)游戏手柄和操纵杆
就像[鼠标输入]和[键盘输入]一样,SDL也有能力读取来自操纵杆/游戏手柄/游戏控制器的输入。在本教程中,我们将根据操纵杆的输入使箭头旋转。
arcticfox
2021/01/06
1.9K0
(译)SDL编程入门(6)扩展库SDL_image
SDL扩展库允许你做一些事情,比如加载BMP以外的图像文件,渲染TTF字体,以及播放音乐。您可以设置SDL_image来加载PNG文件,这可以为您节省大量的磁盘空间。在本教程中,我们将介绍如何安装SDL_image。
arcticfox
2020/09/24
1.4K0
SDL系列讲解(八) SDL_ttf教程
关于游戏开发,当前还在调试,一款移植的随后先推出,自己开发的需要稍等几周,近期比较忙,时间不充裕,大家谅解。同时,对于android开发中的任意问题,可以留言,想了解哪方向的知识,可以回复,如果有能力,可以进行讲解的,后续我便会进行展开,以便更准确的帮助到大家。 感谢一路大家的支持与厚爱。 SDL系列讲解(一) 简介 SDL系列讲解(二) 环境搭建 SDL系列讲解(三) 工具安装 SDL是什么,能干什么,为什么我们要学习它? SDL系列讲解(四) demo讲解 SDL系列讲解(五) 调试c代码 SDL
用户1263308
2018/02/02
3.3K0
SDL系列讲解(八) SDL_ttf教程
(译)SDL编程入门(14)动画精灵和VSync
动画简而言之就是展示一个又一个的图像来制造运动的假象。在这里我们将展示不同的精灵来制作一个简笔画的动画。
arcticfox
2020/10/19
1K0
(译)SDL编程入门(14)动画精灵和VSync
【程序源代码】《金庸群侠传》C++复刻版
这是一个以SDL2为基础实现的2D游戏框架,同时相当于提供了一个使用该框架制作DOS游戏《金庸群侠传》移植版的范例。Windows下可以使用Visual Studio编译,其他系统下可以在src目录使用CMake生成Makefile,使用GCC或Clang编译,需至少支持C++14。VS工程为x64版本,如需要x86版请自行修改。
程序源代码
2020/01/16
2.9K0
【程序源代码】《金庸群侠传》C++复刻版
(译)SDL编程入门(11)裁剪渲染和精灵表
有时你只想渲染纹理的一部分。很多时候,游戏喜欢将多个图像保留在同一张精灵表上,而不是拥有一堆纹理。使用剪辑渲染,我们可以定义要渲染的纹理的一部分,而不是渲染整个对象。
arcticfox
2020/10/09
8090
(译)SDL编程入门(15)旋转和翻转
SDL2的硬件加速纹理渲染还能给我们提供图像快速翻转和旋转的能力。在本教程中,我们将利用这一点使一个箭头纹理旋转和翻转。
arcticfox
2020/10/19
1.3K0
(译)SDL编程入门(15)旋转和翻转
(译)SDL编程入门(5)Surface 优化和软拉伸
到现在为止,我们一直都是将我们的图像原始地融合在一起。因为我们只显示一张图片,所以这并不重要。当你在做游戏的时候,原始图像会导致不必要的减速。我们将把它们转换为优化的格式来加快它们的速度。
arcticfox
2020/09/24
1.4K0
SDL简介
SDL在结构上是将不同操作系统的库再封装成相同的函数,例如SDL在Windows平台上是DirectX的封装,而在使用X11的平台上(包括Linux),SDL则是与Xlib库沟通来输出图像。虽然SDL本身是使用C语言写成,但是它几乎可以被所有的编程语言所使用,例如:C++、Perl、Python(借由pygame库)、Pascal、Java等等。
arcticfox
2020/09/24
2.5K0
android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程
SDL系列讲解(一) 简介 SDL系列讲解(二) 环境搭建 SDL系列讲解(三) 工具安装 SDL是什么,能干什么,为什么我们要学习它? SDL系列讲解(四) demo讲解 SDL系列讲解(五) 调试c代码 SDL系列讲解(六) SDL_Activity流程 SDL系列讲解(七) SDL_image教程 SDL系列讲解(八) SDL_ttf教程 SDL系列讲解(九) 异常退出分析 SDL系列讲解(十) 按键处理流程 SDL系列讲解(十一) SDL_QUIT流程 SDL系列讲解(十二)创建窗口流程
用户1263308
2018/02/02
2.4K0
android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程
OpenGL ES 文字渲染
在音视频或 OpenGL 开发中,文字渲染是一个高频使用的功能,比如制作一些酷炫的字幕、为视频添加水印、设置特殊字体等等。
字节流动
2021/06/24
1.9K0
OpenGL ES 文字渲染
(译)SDL编程入门(9)视口
有些时候,你只想渲染屏幕的一部分,比如最小地图。使用视口你可以控制你在屏幕上的渲染位置。
arcticfox
2020/09/27
8210
(译)SDL编程入门(9)视口
(译)SDL编程入门(8)几何图形渲染
除了新的纹理API,SDL还有新的基元渲染调用作为其渲染API[1]的一部分。因此,如果你需要渲染一些基本的形状,而你又不想为它们创建额外的图形,SDL可以为你省力。
arcticfox
2020/09/27
1.5K0
(译)SDL编程入门(8)几何图形渲染
相关推荐
(译)SDL编程入门(21)音效和音乐
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档