用SDL TTF显示带有SDL2和OpenGL的文本

Displaying text with SDL TTF with SDL2 and OpenGL

本文关键字:OpenGL 文本 SDL2 SDL TTF 显示      更新时间:2023-10-16

我正在尝试使用SDL2 TTF和OpenGL显示文本。窗口中会出现一个奇怪的纹理,它的大小和正确的位置正确,但您看不到任何字母。

我已经尝试使用SDL_CREaterGbsurface((认为这可能是一种更干净的像素,但它也不起作用。我的表面永远不会为空,并且总是通过验证测试。

i在使用glclear(gl_color_buffer_bit(之后,在whial((loop之前使用get_front((函数。

SDL,TTF和OpenGL适当初始化,我创建了一个OpenGL上下文。这是有问题的代码:

SDL_Surface* get_font()
{
    TTF_Font *font;
    font = TTF_OpenFont("lib/ariali.ttf", 35);
    if (!font) cout << "problem loading font" << endl;
    SDL_Color white = {150,200,200};
    SDL_Color black = {0,100,0};
    SDL_Surface* text = TTF_RenderText_Shaded(font, "MO", white, black);
    if (!text) cout << "text not loaded" << endl;
    return text;
}
void displayMoney(SDL_Surface* surface)
{
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable(GL_TEXTURE_2D);
    GLuint TextureID = 0;
    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);
        int Mode = GL_RGB;
        if(surface->format->BytesPerPixel == 4) {
            Mode = GL_RGBA;
        }
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, Mode, 128, 64, 0, Mode, GL_UNSIGNED_BYTE, surface->pixels);
        glPushMatrix();
            glTranslated(100,100,0);
            glScalef(100,100,0);
            glBegin(GL_QUADS);
                glTexCoord2f(0, 1); glVertex2f(-0.5f, -0.5f);  
                glTexCoord2f(1, 1); glVertex2f(0.5f, -0.5f); 
                glTexCoord2f(1, 0); glVertex2f(0.5f, 0.5f); 
                glTexCoord2f(0, 0); glVertex2f(-0.5f, 0.5f);  
            glEnd();
        glPopMatrix();
    glBindTexture(GL_TEXTURE_2D, 0); 
}

#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#include <GL/gl.h>
#include <GL/glu.h>
#include <stb_image/stb_image.h>
#include <SDL2_ttf/SDL_ttf.h>
#include "init.h"

int main(int argc, char **argv) {
    SDL_Window* window = init();
    if (window == nullptr) {
        cout << "Error window init" << endl;
    }
    if (TTF_Init() < 0) {
        cout << "Error TTF init" << endl;
    }
    SDL_Surface* text = get_font(); 
    while (loop) {
        glClear(GL_COLOR_BUFFER_BIT);
        displayMoney(text);
...
       SDL_GL_SwapWindow(window);

没有任何错误消息。另外,我没有使用STBI_LOAD功能,而不是使用表面,而是用图像测试了代码,并且效果很好。因此,问题似乎与SDL部分有关。

edit :我最近发现了我从文本中获得的表面具有以下属性:rmask = gmask = bmask = amask = amask = 0了解如何修复它...

如https://www.libsdl.org/projects/sdl_ttf/docs/sdl_ttf.httf.html#sec42,

阴影: 创建一个8位调整的表面,并以给定的字体和颜色以高质量呈现给定文本。0像素值是背景,而其他像素的前景颜色与背景颜色不同。

因此,您所产生的表面是用8位调色板索引的,而不是RGBA(如您所指出的那样,也以表面格式缺失的颜色掩模表示(。带有α通道的RGBA表面由例如TTF_RenderText_Blended,或使用不同的纹理格式,或执行格式转换。您需要将表面宽度/高度传递到glTexImage2D而不是128/64常数,因为表面尺寸可能会有所不同。

您还有几个资源泄漏的问题代码:在每次绘制上创建新纹理,而从不删除它(如果文本不更改,这也不需要使用TTF_CloseFont