SDL Surface -> OpenGL Texture Question

Started by
25 comments, last by _nomad_ 19 years, 10 months ago
Hi, I am using SDL_TTF, and when I render the SDL_Surface returned by TTF_RenderText_Solid(), I only get a solid quad. Here's my code:

	static int txt_WriteText(SDL_Color p_Color,
                                 float p_XCoord,
                                 float p_YCoord,
                                 const char *p_Text,
                                 ...)
	{
		SDL_Surface* _Surface;
		int          _TextureID;

		char				 _Buffer[1024];					// 1KB Buffer
		va_list			 _ArgList;							// Pointer To List Of Arguments

		if(p_Text == NULL)									// If There's No Text
			return(ERR_WRITE_TEXT);						// Flag An Error

		if(g_TTF == NULL)										// If Global TTF Is NULL
			return(ERR_WRITE_TEXT);						// Flag An Error

		va_start(_ArgList, p_Text);					// Parses The String For Variables
			vsprintf(_Buffer, p_Text, _ArgList);	// And Converts Symbols To Actual String
		va_end(_ArgList);	

		// Render Text To An SDL_Surface
		if(!(_Surface = TTF_RenderText_Solid(g_TTF,_Buffer,p_Color))) {
			return(ERR_WRITE_TEXT);
		} else {
			glEnable(GL_TEXTURE_2D);					// Enable 2D Texture Support
			glGenTextures(1, &_TextureID);
			glBindTexture(GL_TEXTURE_2D, _TextureID);
			glTexImage2D(GL_TEXTURE_2D, 0, 3, _Surface->w, _Surface->h, 0, GL_BGR, GL_UNSIGNED_BYTE, _Surface->pixels);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

  		txt_BeginOverlay(g_ScreenWidth, g_ScreenHeight);
			  glColor3ub(p_Color.r, p_Color.g, p_Color.b);
				glBegin(GL_QUADS);
					glTexCoord2f(1.0f, 0.0f); glVertex2f(p_XCoord, p_YCoord);
					glTexCoord2f(1.0f, 1.0f); glVertex2f(p_XCoord, p_YCoord+_Surface->h);
					glTexCoord2f(0.0f, 1.0f); glVertex2f(p_XCoord+_Surface->w, p_YCoord+_Surface->h); 
					glTexCoord2f(0.0f, 0.0f); glVertex2f(p_XCoord+_Surface->w, p_YCoord);
				glEnd();
				glColor3ub(255,255,255);
			txt_EndOverlay();
		}
      
		SDL_FreeSurface(_Surface);
		
		return(OK_WRITE_TEXT);
	}
  
txtBeginOverlay() and txtEndOverlay() are just codes that set the screen into ortho mode. Here's the code:

	void txt_BeginOverlay(int p_Width,               // Width Of (Overlay) Window
		                    int p_Height)              // Height Of (Overlay) Window
	{
		glGetIntegerv(GL_BLEND_SRC, &txt_blend_src);
		glGetIntegerv(GL_BLEND_DST, &txt_blend_dst);
		glPushAttrib(GL_ENABLE_BIT|GL_VIEWPORT_BIT|GL_TRANSFORM_BIT);
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);

		glMatrixMode(GL_PROJECTION);
			glPushMatrix();
			glLoadIdentity();
			gluOrtho2D(0.0f, p_Width, 0.0f, p_Height);
		glMatrixMode(GL_MODELVIEW);
			glPushMatrix();
			glLoadIdentity();
	}


	void txt_EndOverlay(void)
	{
		glPopMatrix();
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glPopAttrib();
		glBlendFunc(txt_blend_src, txt_blend_dst);
		glMatrixMode(GL_MODELVIEW);
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
	}
  
any idea what i'm doing wrong? I only get a solid colored quad (color of quad depends on the SDL_Color I pass to txt_WriteText()) this link: http://jcatki.no-ip.org/SDL_ttf/SDL_ttf_27.html#SEC27 says that TTF_RenderText_Solid():
quote:Create an 8-bit palettized surface and render the given text at fast quality with the given font and color. The 0 pixel value is the colorkey, giving a transparent background, and the 1 pixel value is set to the text color. The colormap is set to have the desired foreground color at index 1, this allows you to change the color without having to render the text again. Colormap index 0 is of course not drawn, since it is the colorkey, and thus transparent, though it's actual color is 255 minus each RGB component of the foreground.
Does it have something to do with the way i use glTexImage2D()? it says the surface is 8-bit, will i have to modify my glTexImage2D()? How do i fix it? thanks! [edited by - _nomad_ on April 26, 2004 6:36:45 AM]
Advertisement
oops, sorry for the ugly formatting, i copy and pasted the code directly from msvc++ 6 IDE...:D

btw, i''ve seen posts here that show codes inside a textbox, how do you do it? i used the "code" "/code" tag w/c resulted above...
anyone know how to make sdl_ttf work in an sdl opengl window instead?

thanks.
How about reading the GameDev documents before posting. The documentation consist of many valuable posting information such as tags and such.

''
'' is how you do it. I assume you know how to end/close it?...........
Jehovah is viewed by Gnostics as fundamentally evil, jealous, rigid, lacking in compassion and prone to genocide.
You were on the right track.

TTF_*Solid creates a paletted bitmap, and you''re telling openGL that it is BGR.

The solution is either to use the TTF_*Blended, and tell openGL its an ARGB/whatever (I recommend this), or use SDL_ConvertSurface on the surface you jsut got and convert it into an RGB surface.
quote:Original post by C-Junkie
You were on the right track.

TTF_*Solid creates a paletted bitmap, and you''re telling openGL that it is BGR.

The solution is either to use the TTF_*Blended, and tell openGL its an ARGB/whatever (I recommend this), or use SDL_ConvertSurface on the surface you jsut got and convert it into an RGB surface.



I tried the TTF_*Blended way and then tell opengl it''s an argb, and it doesn''t work since glTexImage2D() only has the GL_RGBA flag, and not GL_ARGB (or am i mistaken? is there a flag that allows ARGB definition?)

will look into sdl_convertsurface...
thanks.

@Demiurge666 - did you get yours to work?
Hi. I don't think this is your problem and you might have intended this, but I'll point it out just to make sure you know.

It seems from your glVertex2f statements that you are trying to draw as follows: lowerleft->upperleft->upperright->lowerright. But, your texture statements indicate lowerright->upperright->upperleft->lowerleft.

Also, you include nice code with [ source ][/ source ]. Without the spaces inside the brackets, of course. You can check other stuff in the faq.)

~Urayami

[edited by - urayami on April 27, 2004 3:10:09 AM]
~Urayami
@urayami - hey, thanks for pointing that out, didn''t notice that...:D
Ok, here''s the updated code, with SDL_ConvertSurface() to convert the surface into an RGBA:

static int txt_WriteText(SDL_Color p_Color,                         float p_XCoord,                         float p_YCoord,                         const char *p_Text,                         ...){  SDL_Surface* _Surface;  SDL_Surface* _NewSurface;  int          _TextureID;  char         _Buffer[1024];	// 1KB Buffer  va_list      _ArgList;	// Pointer To List Of Arguments  SDL_Surface *surface;  Uint32 rmask, gmask, bmask, amask;/* SDL interprets each pixel as a 32-bit number,    so our masks must depend on the endianness    (byte order) of the machine */#if SDL_BYTEORDER == SDL_BIG_ENDIAN			rmask = 0xff000000;			gmask = 0x00ff0000;			bmask = 0x0000ff00;			amask = 0x000000ff;#else			rmask = 0x000000ff;			gmask = 0x0000ff00;			bmask = 0x00ff0000;			amask = 0xff000000;#endif  if(p_Text == NULL)	// If There''s No Text  return(ERR_WRITE_TEXT);	// Flag An Error  if(g_TTF == NULL)	// If Global TTF Is NULL  return(ERR_WRITE_TEXT);	// Flag An Error  va_start(_ArgList, p_Text);  vsprintf(_Buffer, p_Text, _ArgList);	  va_end(_ArgList);	// Render Text To An SDL_Surface  if(!(_Surface = TTF_RenderText_Blended(g_TTF,_Buffer,p_Color))) {  return(ERR_WRITE_TEXT);  } else {    glEnable(GL_TEXTURE_2D);    glGenTextures(1, &_TextureID);    glBindTexture(GL_TEXTURE_2D, _TextureID);    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, _Surface->w,                                  _Surface->h, 32,                                 rmask, gmask, bmask, amask);    if(surface == NULL) {      exit(1);    }    _NewSurface = SDL_ConvertSurface(_Surface, surface->format,                                    SDL_SWSURFACE | SDL_SRCALPHA);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _NewSurface->w,               _NewSurface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE,                (void*)_NewSurface->pixels);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP);    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    txt_BeginOverlay(g_ScreenWidth, g_ScreenHeight);    glColor3ub(p_Color.r, p_Color.g, p_Color.b);    glBegin(GL_QUADS);      glTexCoord2f(0.0f, 0.0f); glVertex2f(p_XCoord, p_YCoord);      glTexCoord2f(0.0f, 1.0f); glVertex2f(p_XCoord, p_YCoord+_Surface->h);      glTexCoord2f(1.0f, 1.0f); glVertex2f(p_XCoord+_Surface->w, p_YCoord+_Surface->h);       glTexCoord2f(1.0f, 0.0f); glVertex2f(p_XCoord+_Surface->w, p_YCoord);    glEnd();    glColor3ub(255,255,255);    txt_EndOverlay();  }        SDL_FreeSurface(_Surface);  return(OK_WRITE_TEXT);}



but it''s still not working...am i using sdl_convertsuface() wrongly? are the flags in sdl_convertsurface() wrong? i''m using TTF_RenderText_Blended() already, btw.
Try using your ''surface'' pointer directly in glTexImage2D. Having three temporary SDL_Surfaces seems like a waste of resources and computation time. Either way, remember to call SDL_FreeSurface on ALL of your surfaces.

You should study the documentation for both SDL and SDL_ttf.
2 + 2 = 5 for extremely large values of 2

This topic is closed to new replies.

Advertisement