LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 07-28-2006, 01:06 AM   #1
pda_h4x0r
Member
 
Registered: Feb 2006
Location: somewhere in cyberspace
Distribution: Debian, Familiar
Posts: 380

Rep: Reputation: 30
SDL's TTF API doesn't work with OpenGL


Hello everyone,

I'm writing a simple game using both OpenGL (for the graphics) and SDL (for event handling and keyboard input). I can initilize the TTF API, I can load a TTF, I can use TTF_RenderText_* functions, but no matter what I do, no text appears whenever I attempt to blit a surface created by a TTF_RenderText_* function to the main SDL_Surface. Here's the (relevant) code:

int DrawStr(TTF_Font* fnt, char* str, int x, int y, SDL_Surface* dest, SDL_Color color) {

if(fnt == NULL) return 0;
SDL_Surface* tmp = TTF_RenderText_Solid(fnt, str, color);
if(!tmp) return 0;
if(SDL_BlitSurface(tmp, NULL, dest, &(SDL_Rect){x,y,0,0})) return 0;
SDL_FreeSurface(tmp);
return 1;

}

The above function always returns 1, but no text appears.

It is called as follows:

SDL_Surface* GLSCREEN;
TTF_Font fnt_sans12;

#define random(x) (rand() % (x))

//...

if(!DrawStr(fnt_sans12, "Linux", 20, 20, GLSCREEN, &(SDL_Color){random(255), random(255), random(255), random(255)}) printf("Unable to render text!\n");

GLSCREEN has the SDL_OPENGL, SDL_GL_DOUBLEBUFFER, SDL_HWPALETTE, SDL_RESIZABLE, and SDL_HWACCEL options enabled. I am using SDL 2.0 (i.e. the latest libs in Debian Etch).

Thank you in advance for your response(s).

Last edited by pda_h4x0r; 07-28-2006 at 01:08 AM.
 
Old 07-29-2006, 02:26 AM   #2
pda_h4x0r
Member
 
Registered: Feb 2006
Location: somewhere in cyberspace
Distribution: Debian, Familiar
Posts: 380

Original Poster
Rep: Reputation: 30
It seems I found a solution from an SDL tutorial at http://osdl.sourceforge.net/OSDL/OSD...libraries.html.

TTF_RenderText_Solid() doesn't work in GNU/Linux. TTF_RenderText_Shaded(), however, does.

How about that. Please see the signature...
 
Old 08-02-2006, 01:55 AM   #3
pda_h4x0r
Member
 
Registered: Feb 2006
Location: somewhere in cyberspace
Distribution: Debian, Familiar
Posts: 380

Original Poster
Rep: Reputation: 30
Hmmm...TTF_RenderText_* isn't failing--SDL_BlitSurface is. I think this may be because 32-bit SDL surfaces have an ARGB pixel format, whereas OpenGL's 32-bit pixel format is RGBA. Because I explicitly initilized SDL to use OpenGL for graphics (i.e. by enabling the SDL_OPENGL option), SDL_BlitSurface is simply unable to perform blits. Crap.
 
Old 08-02-2006, 01:59 AM   #4
vharishankar
Senior Member
 
Registered: Dec 2003
Posts: 3,142
Blog Entries: 4

Rep: Reputation: 121Reputation: 121
You can initialize with the SDL_OPENGLBLIT flag instead of SDL_OPENGL in SDL_SetVideoMode. That will allow SDL blits in an OpenGL surface.

Last edited by vharishankar; 08-02-2006 at 02:01 AM.
 
Old 08-02-2006, 04:13 AM   #5
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Use this option at your own peril.
http://twomix.devolution.com/piperma...er/039852.html
 
Old 08-03-2006, 11:53 PM   #6
pda_h4x0r
Member
 
Registered: Feb 2006
Location: somewhere in cyberspace
Distribution: Debian, Familiar
Posts: 380

Original Poster
Rep: Reputation: 30
Thank you for the suggestions. What I currently have working is a way to generate an OpenGL texture from an SDL surface with the same pixel format. The code is currently unsuitable for many calls (i.e. I'm using it to generate HUDs), but here's what I have:


int GLTexFromSurface(SDL_Surface* src, GLuint tex, int type) {
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, type, src->w, src->h, 0, type,
GL_UNSIGNED_BYTE, src->pixels );

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

return 1;
}

inline int GLFreeTex(GLuint* tex) {
glDeleteTextures(1,tex);
return 1;
}

//POT == Power Of Two
inline int GLMakePOT(int dim) {
double log2 = log(dim) / log(2);
int log2i = (int)ceil(log2);
return (int)(pow(2,log2i));
}

int DrawStr(TTF_Font* fnt, char* str, float x, float y, GLuint texi, SDL_Color color) {
SDL_Surface* text = TTF_RenderText_Blended(fnt, str, color);
if(text == NULL) {
printf("DrawStr(): unable to allocate text buffer\n");
return 0;
}

int width = GLMakePOT(text->w);
int height = GLMakePOT(text->h);

//FIXME: currently, the texture has to be square to prevent ugly distortions
if(width > height) height = width;
else if(height > width) width = height;

SDL_Surface* tmp = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
if(tmp == NULL) {
printf("DrawStr(): unable to allocate temporary surface\n");
SDL_FreeSurface(text);
return 0;
}

//FIXME: not sure this is needed...
SDL_FillRect(tmp, &(SDL_Rect){0,0,width,height}, 0);

if(SDL_BlitSurface(text, NULL, tmp, NULL)) {
printf("DrawStr(): unable to create OpenGL-compatible surface\n");
SDL_FreeSurface(text);
SDL_FreeSurface(tmp);
return 0;
}

//my OpenGL surface has RGBA format
GLTexFromSurface(tmp, texi, GL_RGBA);

glBindTexture(GL_TEXTURE_2D, texi);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(x,y,-1.0f);

glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f(width,0.0f,0.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f(width,height,0.0f);
glTexCoord2f(0.0f,1.0f); glVertex3f(0.0f,height,0.0f);
glEnd();

glFinish();

SDL_FreeSurface(text);
SDL_FreeSurface(tmp);
GLFreeTex(&texi);

return 1;
}

What I'll probably end up doing is creating one small 32-bit SDL surface for each HUD element one big 32-bit SDL surface offscreen, and one big OpenGL texture when the game initilizes. Then, during run-time, I'll just clear the big SDL surface, blit the HUD elements to it, bind it to the OpenGL texture, and render it as a single quad.

Thanks again!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Hardware accelerated drawing api for linux (besides OpenGL) ForYouAndI.com Programming 0 01-19-2006 08:04 AM
Can't get TTF fonts to work in GIMP RickyM Linux - Software 11 03-17-2004 04:50 PM
Can't get OpenGL to work scorpion777 Linux - Newbie 1 08-19-2003 10:13 PM
Imported Windows TTF fonts work in GTK+ 1.2 but not 2.0 Locura Slackware 1 07-03-2003 08:53 PM
How do I get OpenGL to Work oostevo Linux - Newbie 2 10-28-2001 05:15 PM


All times are GMT -5. The time now is 11:31 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration