C++ SDL_ttf和OpenGL正在输出看似随机的垃圾和崩溃

C++ SDL_ttf和OpenGL正在输出看似随机的垃圾和崩溃,c++,string,opengl,sdl,sdl-ttf,C++,String,Opengl,Sdl,Sdl Ttf,我正在尝试编写一个基本程序,使用SDL_ttf在OpenGL中渲染文本。我已经看到了十几个关于如何让两者协同工作的问题得到了回答,几乎所有这些问题都提供了与我正在使用的代码相似的代码。然而,我没有看到任何与我所经历的波动性相关的问题 这很奇怪。如果我使用某个字体、某个点大小和某个输出字符串,那么程序工作和输出都很完美。在其他情况下,程序将运行,但文本表面显示为垃圾。在其他情况下,程序会立即崩溃 例如,如果我调用TTF_OpenFont font1.TTF,28,然后将TTF_RenderUTF8

我正在尝试编写一个基本程序,使用SDL_ttf在OpenGL中渲染文本。我已经看到了十几个关于如何让两者协同工作的问题得到了回答,几乎所有这些问题都提供了与我正在使用的代码相似的代码。然而,我没有看到任何与我所经历的波动性相关的问题

这很奇怪。如果我使用某个字体、某个点大小和某个输出字符串,那么程序工作和输出都很完美。在其他情况下,程序将运行,但文本表面显示为垃圾。在其他情况下,程序会立即崩溃

例如,如果我调用TTF_OpenFont font1.TTF,28,然后将TTF_RenderUTF8_Blended with Testing作为输出字符串,它就会崩溃。但我做了很多尝试,结果非常令人不安

-如果我删除g并尝试输出Testin,那么程序就会按照预期工作并输出。欧欧欧

-如果我尝试输出测试,我会得到垃圾

-如果我尝试输出Tst,程序就会工作。欧欧欧

-如果我试图输出tst,程序就会崩溃

此外,当我尝试使用不同的字体和点大小时,我会收到垃圾或使用不同的字符串崩溃

SDL_ttf函数的所有错误检查都恢复正常

换句话说,就我所知,唯一能区别程序是否工作的是我传递给SDL_ttf函数的字符串。我完全不知道为什么字体目录绝对准确。我只能假设我忽略了某种明显的内存泄漏之类的事情

话虽如此,以下是我的初始化代码:

bool Init() {

if( SDL_Init(SDL_INIT_EVERYTHING) < 0 )
    return false;

//SDL_Surface* display_surface is declared outside of this function
if( (display_surface = SDL_SetVideoMode(640 , 480 , 32 , SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL)) == NULL )
    return false;

SDL_GL_SetAttribute(SDL_GL_RED_SIZE,            8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,          8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,           8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,          8);

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,          16);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,         32);

SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,      8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,    8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,     8);
SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,    8);

SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,  1);

SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,  2);

glClearColor(0, 0, 0, 0);
glClearDepth(1.0f);

glViewport(0, 0, 640, 480);

glMatrixMode( GL_PROJECTION );
glLoadIdentity();

glOrtho(0 ,640 ,480 ,0 ,1 ,-1);

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

//TTF_Font* test_font is declared outside of this function
test_font = TTF_OpenFont( "font1.ttf" , 28 ); 

SDL_Color text_color = { 255 , 255 , 255 };

//SDL_Surface* text_surface is declared outside of this function
text_surface = TTF_RenderUTF8_Blended( test_font, "Testing" , text_color );

//force powers of 2
int w_pow2 = 1;
int h_pow2 = 1;
while( w_pow2 < text_surface->w )
    w_pow2 *= 2;
while( h_pow2 < text_surface->h )
    h_pow2 *= 2;
text_surface->w = w_pow2;
text_surface->h = h_pow2;

GLuint color_format;

if ( text_surface->format->BytesPerPixel == 4 ) {
    if (text_surface->format->Rmask == 0x000000ff) 
        color_format = GL_RGBA;
    else 
        color_format = GL_BGRA;
    } 
else if ( text_surface->format->BytesPerPixel == 3 ) {
    if ( text_surface->format->Rmask == 0x000000ff) 
        color_format = GL_RGB;
    else 
        color_format = GL_BGR;
    } 

glGenTextures( 1 , &texture ); //GLuint texture is declared outside of this function
glBindTexture( GL_TEXTURE_2D , texture );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D , 0 , text_surface->format->BytesPerPixel , text_surface->w , text_surface->h , 0 , color_format , GL_UNSIGNED_BYTE , text_surface->pixels ); 

return true;

}
我的清理工作:

void Cleanup() {

glDeleteTextures( 1 , &texture );

SDL_FreeSurface( text_surface ); 

TTF_CloseFont( test_font ); 

TTF_Quit();

SDL_Quit();

}

我将尽力提供所需的更多详细信息。

TTF_RenderRutF8_Blended根据TrueType渲染器决定打印文本的方式生成任意大小的SDL_曲面文本。稍后,代码会单方面重新调整文本曲面的宽度和高度变量的大小,而不会实际更改存储在像素中的图像数据以反映更改的尺寸。这将导致glTexImage2D读取不相关的程序变量数据,充其量为图像数据,和/或充其量为非法内存访问


查看SDLGL_LoadTextureFromFileBestFit,了解如何调整SDL_曲面的大小,使其具有二维的能力,以及如何将其映射到正确的OpenGL纹理坐标。

您可以使用调试器并找出它崩溃的位置吗?当我通过调试器运行它时,它不会崩溃,它只输出字符串的垃圾像素,如果我正常运行程序,这些字符串将崩溃。我使用DeV C++,如果它很重要。当你调用TtfpOpenFoeFun1.TTF,28,运行目录中是否存在fut1.tf?@我认为opengl试图读取sdl曲面数据的方式会导致访问冲突。但是如果是这样的话,我不知道调试器为什么不抱怨它。我如何格式化opengl纹理有什么不确定的地方吗?啊,当然。我应该早点意识到这一点。现在开始工作了。非常感谢!
void Cleanup() {

glDeleteTextures( 1 , &texture );

SDL_FreeSurface( text_surface ); 

TTF_CloseFont( test_font ); 

TTF_Quit();

SDL_Quit();

}