Jump to content
  • Advertisement
Sign in to follow this  
codemastermm

SDL_ttf rendering size problem

This topic is 4865 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In my code, I have it so that whenever you type text, it will add it to a size 32 array of char's and my RenderText function will render the text out. (basically, it's a char text[32]) Anyway, my problem resides in this: I type a few letters, but instead of the text becoming wider, it simply condenses the text, for a few letters. As I type more, sometimes it resizes itself to its proper width, but then as I still type more, it returns to becoming crammed again (it basically alternates; it's quite odd). Here's the function I use to render my text:
void	RenderText(TTF_Font *font, const char *message, SDL_Color color, SDL_Rect pos)
{
	SDL_Surface *text, *image;
	GLuint texture;
	int w, h;
	SDL_Rect area;
	Uint32 saved_flags;
	Uint8  saved_alpha;
	GLfloat texcoord[4];
	GLenum gl_error;

	pos.y -= TTF_FontHeight(font);

	if(!(text = TTF_RenderText_Blended(font, message, color)))
	{
		printf("TTF_RenderText_Blended: %s\n", SDL_GetError());
		TTF_CloseFont(font);
		return;
	}

	glGetError();

	/* Use the text width and height expanded to powers of 2 */
	w = power_of_two(text->w);
	h = power_of_two(text->h);
	texcoord[0] = 0.0f;			/* Min X */
	texcoord[1] = 0.0f;			/* Min Y */
	texcoord[2] = (GLfloat)text->w / w;	/* Max X */
	texcoord[3] = (GLfloat)text->h / h;	/* Max Y */

	image = SDL_CreateRGBSurface(
		SDL_HWSURFACE,
		w, h,
		32,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
		0x000000FF, 
		0x0000FF00, 
		0x00FF0000, 
		0xFF000000
#else
		0xFF000000,
		0x00FF0000, 
		0x0000FF00, 
		0x000000FF
#endif
	);
	if(!image)
	{
		printf("SDL_CreateRGBtext: %s\n", SDL_GetError());
		return;
	}

	/* Save the alpha blending attributes */
	saved_flags = text->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
	saved_alpha = text->format->alpha;
	if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
		SDL_SetAlpha(text, 0, 0);

	/* Copy the text into the GL texture image */
	area.x = area.y = 0;
	area.w = text->w;
	area.h = text->h;
	SDL_BlitSurface(text, &area, image, &area);

	/* Restore the alpha blending attributes */
	if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
		SDL_SetAlpha(text, saved_flags, saved_alpha);

	/* Create an OpenGL texture for the image */
	glGenTextures(1, &texture);
	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,
		     GL_RGBA,
		     w, h,
		     0,
		     GL_RGBA,
		     GL_UNSIGNED_BYTE,
		     image->pixels);
	SDL_FreeSurface(image); // No longer needed

	if((gl_error = glGetError()) != GL_NO_ERROR)
	{
		/* If this failed, the text may exceed texture size limits */
		printf("Warning: Couldn't create texture: 0x%x\n", gl_error);
		return;
	}

	SDL_FreeSurface(text);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture);
	glBegin(GL_TRIANGLE_STRIP);
		glTexCoord2f(texcoord[0], texcoord[3]); glVertex2i(pos.x,   pos.y  );
		glTexCoord2f(texcoord[2], texcoord[3]); glVertex2i(pos.x+w, pos.y  );
		glTexCoord2f(texcoord[0], texcoord[1]); glVertex2i(pos.x,   pos.y+h);
		glTexCoord2f(texcoord[2], texcoord[1]); glVertex2i(pos.x+w, pos.y+h);
	glEnd();

	glDeleteTextures(1, &texture);

	return;
}

Share this post


Link to post
Share on other sites
Advertisement
Uhhm, if I understood you correctly, probably problem lies within theese lines of code:


glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(texcoord[0], texcoord[3]); glVertex2i(pos.x, pos.y );
glTexCoord2f(texcoord[2], texcoord[3]); glVertex2i(pos.x+w, pos.y );
glTexCoord2f(texcoord[0], texcoord[1]); glVertex2i(pos.x, pos.y+h);
glTexCoord2f(texcoord[2], texcoord[1]); glVertex2i(pos.x+w, pos.y+h);
glEnd();



Quote:

Anyway, my problem resides in this: I type a few letters, but instead of the text becoming wider, it simply condenses the text, for a few letters. As I type more, sometimes it resizes itself to its proper width, but then as I still type more, it returns to becoming crammed again (it basically alternates; it's quite odd).


IMHO it's sth related to "power of two" stuff - sometimes w and h variables contain ie. 128 when text->w and text->h was from range [65, 128], but when it increases once more, by one pixel - power_of_two(text(129) will return 256, which may explain why "sometimes it appears ok, but when you type more", why it alternates etc.


So, how to solve this problem (assuming that's what causes errors) - hmmm, maybe try changing pos.x+w to pos.x+text->w?


If I wasn't right, then maybe looking at my text rendering function will help you?



void SC :: Renderer :: RenderText(const char * _text, const char * _fontName, usint _size, const TScrPoint & _position,
const TColor4 & _color, ulint _style, eTextPosition _horizontal,
eTextPosition _vertical, eTextRenderMode _renderMode, eTextAlignment _align,
bool _addDescent, usint _zPosition )
{
SC_ASSERT(_text)
SC_ASSERT(_fontName)
SC_ASSERT(_size > 0)

TGlyphsContainer * glyphs = getFontMgr.GetGlyphsContainer(_fontName, _size);

if (!glyphs)
{
logError2("Renderer", "Couldn't find font to output text.")
return;
}

// -------------------------------------------------

glColor4ub(_color.r, _color.g, _color.b, _color.a);

ssint xPos = _position.x;
ssint yPos = _position.y;

const char * txtPtr = _text;

// this precaching of glyphs is needed to determine full size of rendered text, it's needed to
// render them properly with given eTextPosition stuff
std :: vector <GlyphTexture*> cachedGlyphs;
TScrPoint renderedText;
TScrPntSet(renderedText, 0, 0);

while (*txtPtr)
{
GlyphTexture * glyph = glyphs->GetGlyphTexture(*txtPtr, _style, _renderMode);

SC_ASSERT(glyph)
TScrPntAddX(renderedText, renderedText, glyph->advance );
renderedText.y = Max(glyph->charHeight, (int) renderedText.y);

cachedGlyphs.push_back(glyph);
++txtPtr;
}

// ------------------------------------------------- HORIZONTAL JUSTIFICTION

if (_horizontal == tp_Centered) // center text
xPos -= (renderedText.x)/2;
else if (_horizontal == tp_Right) // justify to right
xPos -= renderedText.x;

// ------------------------------------------------- VERTICAL JUSTIFICTION

// we're adding, not subtracting - because it retuns negative value

if (_addDescent)
yPos += glyphs->GetFontDescent();

if (_vertical == tp_Centered) // center text
yPos -= (renderedText.y)/4;
else if (_vertical == tp_Right) // justify to right
yPos -= renderedText.y/2;

// ------------------------------------------------- TEXT ALIGNMENT

if ( _align == ta_Up)
{
yPos -= glyphs->GetFontHeight();
}

// -------------------------------------------------

std :: vector <GlyphTexture*> :: iterator itor = cachedGlyphs.begin();

while (itor != cachedGlyphs.end())
{
GlyphTexture * glyph = (*itor);
SC_ASSERT(glyph)

glBindTexture(GL_TEXTURE_2D, glyph->textureID);

float rightMargin = (float) glyph->charWidth /(float)glyph->width;
float upMargin = (float) glyph->charHeight / (float)glyph->height;

// -------------------------------------------------

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3i( xPos, yPos + glyph->charHeight, _zPosition);

glTexCoord2f(0.0f, upMargin);
glVertex3i( xPos, yPos, _zPosition);

glTexCoord2f(rightMargin, upMargin);
glVertex3i( xPos + glyph->charWidth, yPos, _zPosition);

glTexCoord2f(rightMargin, 0.0f);
glVertex3i( xPos + glyph->charWidth, yPos + glyph->charHeight, _zPosition);

glEnd();

// -------------------------------------------------

xPos += glyph->advance;

++itor;
}

glBindTexture(GL_TEXTURE_2D, 0);
boundTexture.id = 0;
glColor4ub(255, 255, 255, 255);
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!