OpenGL, SDL_ttf

I'm having problems displaying text in OpenGL via SDL_ttf. I wrote a LoadFont () function that loads a font and creates an OpenGL texture.

int LoadFont( char *name, GLubyte r, GLubyte g, GLubyte b, char *text, int ptsize) { SDL_Color color = {r, g, b, 0}; TTF_Font *font = TTF_OpenFont(name, ptsize); Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif SDL_Surface *msg = TTF_RenderText_Blended(font, text, color); SDL_SetAlpha(msg, 0, 0); if(!msg) { printf("Unable to Render text\n"); return -1; } SDL_Surface *tmp = SDL_CreateRGBSurface(0, msg->w, msg->h, 32, rmask, gmask, bmask, amask); SDL_BlitSurface(msg, NULL, tmp, NULL); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, msg->pixels); return 1; } 

And I use this function in initGL ():

 int initGL( GLvoid ) { glViewport(0, 0, SCREEN_WIDHT, SCREEN_HEIGHT); LoadFont("THWACK.TTF", 255, 255, 255, "Hello!", 14); glEnable(GL_TEXTURE_2D); glClearColor(0.0f, 0.0f, 1.0f, 0.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat)SCREEN_WIDHT/(GLfloat)SCREEN_HEIGHT, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); return TRUE; } 

Next, I will try to display this text on the polygon:

 int drawGLScene( GLvoid ) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); glBindTexture(GL_TEXTURE_2D, texture[0]); glEnable(GL_TEXTURE_2D); glBegin(GL_POLYGON); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); glDisable(GL_TEXTURE_2D); SDL_GL_SwapBuffers(); return TRUE; } 

But the text is not displayed, only a white polygon.

+4
source share
1 answer

GL_TEXTURE_MIN_FILTER by default GL_NEAREST_MIPMAP_LINEAR .

If you request mipmapping and do not download the full mipmap, you will get white textures.

You have the following:

 // disable mipmapping on default texture glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // create new texture, with default filtering state (==mipmapping on) glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, msg->pixels); 

Try this sequence instead:

 // create new texture, with default filtering state (==mipmapping on) glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); // disable mipmapping on the new texture glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, msg->pixels); 

The texture filtering state belongs to the texture object, not the texture block, so glTexParameterf() after glBindTexture() :

OpenGL 2.1 spec , section 3.8.11 (p. 180) and section 3.8.12 (p. 182):

3.8.11: ... Next, there are two sets of texture properties; each of them consists of selected miniaturization and magnification filters ...

3.8.12: ... The resulting texture object is a new state vector , containing all the state values ​​listed in section 3.8.11 , given the same initial values ​​...


EDIT: You also need to enable blending before rendering if you want to use TTF_Render*_Blended() :

 glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor3ub( 255, 255, 255 ); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, stringTex ); glBegin(GL_QUADS); ... 

Example:

 #include <SDL.h> #include <SDL_ttf.h> #include <SDL_opengl.h> GLuint TextToTexture( TTF_Font* font, GLubyte r, GLubyte g, GLubyte b, const char* text, int ptsize ) { SDL_Color color = { r, g, b }; SDL_Surface* msg = TTF_RenderText_Blended( font, text, color ); // create new texture, with default filtering state (==mipmapping on) GLuint tex; glGenTextures( 1, &tex ); glBindTexture( GL_TEXTURE_2D, tex ); // disable mipmapping on the new texture glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, msg->pixels ); SDL_FreeSurface( msg ); return tex; } GLuint stringTex = 0; void drawGLScene( int winWidth, int winHeight ) { glViewport(0, 0, winWidth, winHeight ); glClearColor(0.0f, 0.0f, 1.0f, 0.0f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, winWidth / (float)winHeight, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -5.0f); // this is where the magic happens glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor3ub( 255, 255, 255 ); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, stringTex ); glBegin(GL_QUADS); glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -1.0f, -1.0f ); glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 1.0f, -1.0f ); glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 1.0f, 1.0f ); glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -1.0f, 1.0f ); glEnd(); glDisable(GL_TEXTURE_2D); } int main( int argc, char *argv[] ) { SDL_Init( SDL_INIT_EVERYTHING ); SDL_Surface* display = SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL ); if( -1 == TTF_Init() ) return -1; // http://unifoundry.com/unifont.html TTF_Font *font = TTF_OpenFont( "unifont.ttf", 14 ); stringTex = TextToTexture( font, 255, 255, 255, "Hello!", 14 ); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); bool running = true; while( running ) { SDL_Event event; while( SDL_PollEvent( &event ) ) { if( event.type == SDL_QUIT ) { running = false; break; } } drawGLScene( display->w, display->h ); SDL_GL_SwapBuffers(); SDL_Delay( 16 ); } TTF_CloseFont(font); TTF_Quit(); SDL_Quit(); return 0; } 
+2
source

Source: https://habr.com/ru/post/1486052/


All Articles