Problem rendering fonts to texture

Im trying to render text with sdl-ttf to a surface that is converted to
opengl texture later to show in a quad.
Here is my code:

fgcol.r=0;
fgcol.g=1;
fgcol.b=0;

tmp = TTF_RenderText_Blended(theme::getTheme()->font,text.c_str
(),fgcol);
if (tmp==NULL) printf(“Error rendering text\n”);
else {
tmp=SDL_DisplayFormat(tmp);
if (tmp==NULL) printf(“Error converting rendered text\n”);
}

glBindTexture(GL_TEXTURE_2D, caption_tex); // 2d texture (x and y
size)

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, 4, tmp->w, tmp->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, tmp->pixels);

And here is the rendering code:
glBindTexture(GL_TEXTURE_2D, caption_tex);

glTexCoord2f(0.0,0.0);
glVertex2i(x+10,y+5);
glTexCoord2f(1.0,0.0);
glVertex2i(x+w-10,y+5);
glTexCoord2f(1.0,1.0);
glVertex2i(x+w-10,y+h-5);
glTexCoord2f(0.0,1.0);
glVertex2i(x+10,y+h-5);

But instead of text what I get is the previously used texture. Can
somebody see what Im doing wrong here?–
Roger D. Vargas
Formatur Santiago

glTexImage2D(GL_TEXTURE_2D, 0, 4, tmp->w, tmp->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, tmp->pixels);

Try using GL_RGBA for the third parameter (instead of 4).

Ilya

Im trying to render text with sdl-ttf to a surface that is converted
to opengl texture later to show in a quad.
Here is my code:

fgcol.r=0;
fgcol.g=1;
fgcol.b=0;

tmp = TTF_RenderText_Blended(theme::getTheme()->font,text.c_str
(),fgcol);
if (tmp==NULL) printf(“Error rendering text\n”);
else {
tmp=SDL_DisplayFormat(tmp);
if (tmp==NULL) printf(“Error converting rendered text\n”);
}

glBindTexture(GL_TEXTURE_2D, caption_tex); // 2d texture (x and y
size)

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, 4, tmp->w, tmp->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, tmp->pixels);

Are the width and height power of two?
The upload will fail if they are not.
Have you checked that there is no error in the upload?On Friday 27 October 2006 00:00, Roger D. Vargas wrote:

And here is the rendering code:
glBindTexture(GL_TEXTURE_2D, caption_tex);

glTexCoord2f(0.0,0.0);
glVertex2i(x+10,y+5);
glTexCoord2f(1.0,0.0);
glVertex2i(x+w-10,y+5);
glTexCoord2f(1.0,1.0);
glVertex2i(x+w-10,y+h-5);
glTexCoord2f(0.0,1.0);
glVertex2i(x+10,y+h-5);

But instead of text what I get is the previously used texture. Can
somebody see what Im doing wrong here?

El jue, 26-10-2006 a las 23:36 -0400, Ilya Olevsky escribi?:

glTexImage2D(GL_TEXTURE_2D, 0, 4, tmp->w, tmp->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, tmp->pixels);

Try using GL_RGBA for the third parameter (instead of 4).
Same problem.–
Roger D. Vargas
Formatur Santiago

El vie, 27-10-2006 a las 17:05 +0300, Sami N??t?nen escribi?:

Im trying to render text with sdl-ttf to a surface that is converted
to opengl texture later to show in a quad.
Here is my code:

Are the width and height power of two?
I havent checked that. Is there any way to force the surface to have an
specific size?
The upload will fail if they are not.
Have you checked that there is no error in the upload?
No, Im not making checks, except if the text is rendered to surface.> On Friday 27 October 2006 00:00, Roger D. Vargas wrote:


Roger D. Vargas
Formatur Santiago

Are the width and height power of two?
I havent checked that. Is there any way to force the surface to have an
specific size?
The upload will fail if they are not.
Have you checked that there is no error in the upload?
No, Im not making checks, except if the text is rendered to surface.

You can make a new surface with the width and height being values that
are powers of two, and blit the SDL_ttf generated surface to it. A
simple way to get power of two dimensions closest to the original values
is to use a while loop starting at 1, squaring each number until you
find the first smallest power of two >= original number.

Ilya

El vie, 27-10-2006 a las 17:05 +0300, Sami N??t?nen escribi?:

Im trying to render text with sdl-ttf to a surface that is
converted to opengl texture later to show in a quad.
Here is my code:

Are the width and height power of two?

I havent checked that. Is there any way to force the surface to have
an specific size?

I think no. You have to do like Ilya said.
Or you could use texturerects instead of plain textures.
Those have only upper width and height limits.
Down side is texturerects are not supported on old HW.

One other point is that OpenGL expects the pixel array to be
flat. So if the surface is say 65 pixels wide then the SDL surface
can have some padding bytes for each row. This will lead to incorrect
texture upload.

The upload will fail if they are not.
Have you checked that there is no error in the upload?

No, Im not making checks, except if the text is rendered to surface.

So start doing them.
All error checks should be done in all code variances anyway.
If something fails what you want to do after that is another story
though.On Saturday 28 October 2006 00:59, Roger D. Vargas wrote:

On Friday 27 October 2006 00:00, Roger D. Vargas wrote:

Are the width and height power of two?
I havent checked that. Is there any way to force the surface to
have an
specific size?
The upload will fail if they are not.
Have you checked that there is no error in the upload?
No, Im not making checks, except if the text is rendered to surface.

You can make a new surface with the width and height being values that
are powers of two, and blit the SDL_ttf generated surface to it.

better make an empty texture (pixels parameter to glTexImage2D ==
NULL) with power of two sizes and update / use only a part of it (use
glTexSubImage2D).

and use the following to find the size of the texture:On 28 Oct 2006, at 05:02, Ilya Olevsky wrote:

A simple way to get power of two dimensions closest to the original
values
is to use a while loop starting at 1, squaring each number until you
find the first smallest power of two >= original number.

This is faster and easier, but this still has the flat array problem
(look my other mail). Although in this case it can be get around using
the pitch/bpp instead of width (if the texture is wide enough of
course).

This can produce some artifact problems though.On Saturday 28 October 2006 21:00, Artem Baguinski wrote:

On 28 Oct 2006, at 05:02, Ilya Olevsky wrote:

Are the width and height power of two?

I havent checked that. Is there any way to force the surface to
have an
specific size?

The upload will fail if they are not.
Have you checked that there is no error in the upload?

No, Im not making checks, except if the text is rendered to
surface.

You can make a new surface with the width and height being values
that are powers of two, and blit the SDL_ttf generated surface to
it.

better make an empty texture (pixels parameter to glTexImage2D ==
NULL) with power of two sizes and update / use only a part of it (use
glTexSubImage2D).

You can make a new surface with the width and height being values
that are powers of two, and blit the SDL_ttf generated surface to
it.

better make an empty texture (pixels parameter to glTexImage2D ==
NULL) with power of two sizes and update / use only a part of it (use
glTexSubImage2D).

This is faster and easier, but this still has the flat array problem
(look my other mail). Although in this case it can be get around using
the pitch/bpp instead of width (if the texture is wide enough of
course).
This can produce some artifact problems though.

it doesn’t have flat array problem. (what’s flat array???)

say your image is 65x65

you will have to use texture that is 128x128, you create it with e.g.
glTexImage2D( GL_TEXTURE_2D, //GLenum target,
0, //GLint level,
GL_RGBA, //GLint internalformat,
128, //GLsizei width,
128, //GLsizei height,
0, //GLint border,
GL_RGBA, //GLenum format,
GL_UNSIGNED_BYTE, //GLenum type,
NULL); //const GLvoid *pixels )

then you will call
glTexSubImage2D( GL_TEXTURE_2D, //GLenum target,
0, //GLint level,
0, //GLint xoffset,
0, //GLint yoffset,
65, //GLsizei width,
65, //GLsizei height,
GL_RGBA, //GLenum format,
GL_UNSIGNED_BYTE, //GLenum type,
surface->pixels); //const GLvoid
*pixels )

this will redefine a 65x65 portion of the texture in the lower left
corner.

when you display the texture you’ll make the texture coordinates go
from 0 to (65.0/128.0) in both dimensions (because you’re only
interested in part of the texture).On 28 Oct 2006, at 20:57, Sami N??t?nen wrote:

You can make a new surface with the width and height being values
that are powers of two, and blit the SDL_ttf generated surface to
it.

better make an empty texture (pixels parameter to glTexImage2D ==
NULL) with power of two sizes and update / use only a part of it
(use glTexSubImage2D).

This is faster and easier, but this still has the flat array
problem (look my other mail). Although in this case it can be get
around using the pitch/bpp instead of width (if the texture is wide
enough of course).
This can produce some artifact problems though.

it doesn’t have flat array problem. (what’s flat array???)

one dimensional array, which is handled like multi dimensional array.
To get correct result with such an array, one have to know the row
length. Normally this has no problem at all. It just works.

When the array represents gfx like SDL surface there starts to be
problems. Every row might have some extra values to keep the start of
row in favorable memory alignment.

SDL_surface.pitch is this real row length in bytes. OpenGL texture
upload can’t compensate these extra bytes. One has to use the
pitch/bytesperpixel as the upload width to get the start of the rows to
match.

say your image is 65x65

you will have to use texture that is 128x128, you create it with e.g.
glTexImage2D( GL_TEXTURE_2D, //GLenum target,
0, //GLint level,
GL_RGBA, //GLint internalformat,
128, //GLsizei width,
128, //GLsizei height,
0, //GLint border,
GL_RGBA, //GLenum format,
GL_UNSIGNED_BYTE, //GLenum type,
NULL); //const GLvoid *pixels )

then you will call
glTexSubImage2D( GL_TEXTURE_2D, //GLenum target,
0, //GLint level,
0, //GLint xoffset,
0, //GLint yoffset,
65, //GLsizei width,
65, //GLsizei height,
GL_RGBA, //GLenum format,
GL_UNSIGNED_BYTE, //GLenum type,
surface->pixels); //const GLvoid
*pixels )

this will redefine a 65x65 portion of the texture in the lower left
corner.

when you display the texture you’ll make the texture coordinates go
from 0 to (65.0/128.0) in both dimensions (because you’re only
interested in part of the texture).

Yes but you have to use the pitch/bytesperpixel instead of the width to
be sure that the uploaded image is correct.On Saturday 28 October 2006 22:42, Artem Baguinski wrote:

On 28 Oct 2006, at 20:57, Sami N??t?nen wrote:


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

one dimensional array, which is handled like multi dimensional array.
To get correct result with such an array, one have to know the row
length. Normally this has no problem at all. It just works.

When the array represents gfx like SDL surface there starts to be
problems. Every row might have some extra values to keep the start of
row in favorable memory alignment.

SDL_surface.pitch is this real row length in bytes. OpenGL texture
upload can’t compensate these extra bytes.

i see what you mean.

OpenGL CAN compensate all this, see glPixelStore. you can specify
alignment and row length and some other properties of pixel memory.

But will you ever get aligned array when using sdl_ttf? I’m using it
with OpenGL and i just use surface->w and surface->h and everything
looks fine with different fonts and font sizes etc.On 29 Oct 2006, at 12:48, Sami N??t?nen wrote:

one dimensional array, which is handled like multi dimensional
array. To get correct result with such an array, one have to know
the row length. Normally this has no problem at all. It just works.

When the array represents gfx like SDL surface there starts to be
problems. Every row might have some extra values to keep the start
of row in favorable memory alignment.

SDL_surface.pitch is this real row length in bytes. OpenGL texture
upload can’t compensate these extra bytes.

i see what you mean.

OpenGL CAN compensate all this, see glPixelStore. you can specify
alignment and row length and some other properties of pixel memory.

So I did remeber correctly, but I forget what the way was. :slight_smile:

But will you ever get aligned array when using sdl_ttf? I’m using it
with OpenGL and i just use surface->w and surface->h and everything
looks fine with different fonts and font sizes etc.

I know that 16bit surfaces will suffer when uploaded from even width
surfaces in P4.

This restriction is mostly concerned in 64bit archs, which might want to
memory align rows to 8 byte boundaries in 32bit surfaces.

At least one should do the following to be absolutely sure:

if( surf->pitch / surf->format->BytesPerPixel != surf->width )
glPixelStorei( GL_UNPACK_ROW_LENGTH,
surf->pitch / surf->format->BytesPerPixel );
glTexSubImage2D(…);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );On Sunday 29 October 2006 17:57, Artem Baguinski wrote:

On 29 Oct 2006, at 12:48, Sami N??t?nen wrote:

one dimensional array, which is handled like multi dimensional
array. To get correct result with such an array, one have to know
the row length. Normally this has no problem at all. It just
works.

When the array represents gfx like SDL surface there starts to be
problems. Every row might have some extra values to keep the
start of row in favorable memory alignment.

SDL_surface.pitch is this real row length in bytes. OpenGL
texture upload can’t compensate these extra bytes.

i see what you mean.

OpenGL CAN compensate all this, see glPixelStore. you can specify
alignment and row length and some other properties of pixel memory.

So I did remeber correctly, but I forget what the way was. :slight_smile:

But will you ever get aligned array when using sdl_ttf? I’m using
it with OpenGL and i just use surface->w and surface->h and
everything looks fine with different fonts and font sizes etc.

I know that 16bit surfaces will suffer when uploaded from even width
surfaces in P4.

And I should have writen odd. :)On Monday 30 October 2006 14:33, Sami N??t?nen wrote:

On Sunday 29 October 2006 17:57, Artem Baguinski wrote:

On 29 Oct 2006, at 12:48, Sami N??t?nen wrote:

This restriction is mostly concerned in 64bit archs, which might want
to memory align rows to 8 byte boundaries in 32bit surfaces.

At least one should do the following to be absolutely sure:

if( surf->pitch / surf->format->BytesPerPixel != surf->width )
glPixelStorei( GL_UNPACK_ROW_LENGTH,
surf->pitch / surf->format->BytesPerPixel );
glTexSubImage2D(…);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl