将 SDL 表面转换为 GL 纹理时出现问题

Posted

技术标签:

【中文标题】将 SDL 表面转换为 GL 纹理时出现问题【英文标题】:Something wrong with converting SDL surface to GL texture 【发布时间】:2014-12-18 11:58:51 【问题描述】:

我找不到我的错误,为什么没有创建文本?当使用纹理而不是文本时,我什么也没有得到或带有彩色点的黑色背景,请帮助

GLuint texture;
SDL_Surface *text = NULL;
TTF_Font *font = NULL;
SDL_Color color = 0, 0, 0;


font = TTF_OpenFont("../test.ttf", 20);
text = TTF_RenderText_Solid(font, "Hello, SDL !!!", color);

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, text->w, text->h, 0, GL_RGB, GL_UNSIGNED_BYTE, text->pixels);

SDL_FreeSurface(text);

【问题讨论】:

你为什么声称来自TTF_RenderText_Solid()text->pixels 在你的glTexImage2D() 调用中包含RGB 数据? 【参考方案1】:

您可以添加的一件事是指定纹理过滤器,例如

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

【讨论】:

【参考方案2】:

你必须先检查几件事

    字体加载正确吗?检查“font == NULL”是否,也许你的 字体路径错误 着色器(如果您使用着色器)设置是否正确?

我的猜测是您在 glTexImage2D 中设置了错误的像素格式类型导致纹理上出现随机颜色点

下面是我通过 SDL_image 加载图像以供 OpenGL 使用的代码,我认为这将是找出您错过或忘记了哪一步的好开始。

顺便说一句,这段代码并不完美。像素格式的类型不止四种(比如索引颜色),我只处理其中的一部分。

/*
 * object_, originalWidth_ and originalHeight_ are private variables in
 * this class, don't panic.
 */
void
Texture::Load(string filePath, GLint minMagFilter,  GLint wrapMode)              

    SDL_Surface* image;                                                      
    GLenum textureFormat;                                                    
    GLint bpp;              //Byte Per Pixel                                 

    /* Load image file */                                                    
    image = IMG_Load(filePath.c_str());                                      
    if (image == nullptr)                                                   
            string msg("IMG error: ");                                       
            msg += IMG_GetError();                                           
            throw runtime_error(msg.c_str());                                
                                                                            

    /* Find out pixel format type */                                         
    bpp = image->format->BytesPerPixel;                                      
    if (bpp == 4)                                                           
            if (image->format->Rmask == 0x000000ff)                          
                    textureFormat = GL_RGBA;                                 
            else                                                             
                    textureFormat = GL_BGRA;                                 
     else if (bpp == 3)                                                    
            if (image->format->Rmask == 0x000000ff)                          
                    textureFormat = GL_RGB;                                  
            else                                                             
                    textureFormat = GL_BGR;                                  
     else                                                                  
            string msg("IMG error: Unknow pixel format, bpp = ");            
            msg += bpp;                                                      
            throw runtime_error(msg.c_str());                                
                                                                            

    /* Store widht and height */                                             
    originalWidth_ = image->w;                                               
    originalHeight_ = image->h;

    /* Make OpenGL texture */                                                
    glEnable(GL_TEXTURE_2D);                                                 
    glGenTextures(1, &object_);                                              
    glBindTexture(GL_TEXTURE_2D, object_);                                   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minMagFilter);     
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minMagFilter);     
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);             
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);             
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);             
    glTexImage2D(                                                            
            GL_TEXTURE_2D,                  // texture type                  
            0,                              // level                         
            bpp,                            // internal format               
            image->w,                       // width                         
            image->h,                       // height                        
            0,                              // border                        
            textureFormat,                  // format(in this texture?)      
            GL_UNSIGNED_BYTE,               // data type                     
            image->pixels                   // pointer to data               
            );                                                               

    /* Clean these mess up */                                                
    glBindTexture(GL_TEXTURE_2D, 0);                                         
    glDisable(GL_TEXTURE_2D);                                                
    SDL_FreeSurface(image);

如需了解更多信息,请查看SDL wiki 或深入其源代码以全面了解 SDL_Surface 的架构。

【讨论】:

我试了你说的,发现我的字体表面的BPP是1。我不知道该怎么办:-(

以上是关于将 SDL 表面转换为 GL 纹理时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

纹理的 SDL 渲染器参数,但表面不需要

尝试对立方体贴图纹理进行采样时出现 GL_INVALID_OPERATION

编译c ++项目/ Open GL时出现纹理错误

SDL2/表面/纹理/渲染

表面和纹理之间的区别(SDL/一般)

在 OpenGL 中将纹理映射到球体时出现接缝问题