Sign in to follow this  
crim

convert sdl_surface ogl tex

Recommended Posts

int sdl_interface::load_text ( string output_text ) {

	TTF_Font* font;

if(TTF_Init())
		cout << "error load font: " << TTF_GetError() << endl;

  atexit(TTF_Quit);

	if(!(font = TTF_OpenFont("data\\fonts\\comic.ttf", 20)))
		cout << "Error loading font: " << TTF_GetError() << endl;

	SDL_Surface *initial;
	SDL_Surface *intermediary;
	SDL_Rect rect;
	int w;
  int h;
	GLuint texture;

SDL_Color color;
		color.r = 255;
		color.g = 255;
		color.b = 255;

	initial = TTF_RenderText_Blended(font, "TESTING THE TEXT", color);
if(initial == NULL)
  cout << "Error crating text" << TTF_GetError() << endl;

intermediary = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 32, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);

if(intermediary == NULL)
  cout << "Error: Creating surface" << endl;

	if(SDL_BlitSurface(initial, 0, intermediary, 0) == -1)
    cout << "Error: Bliting surface" << endl;

SDL_UpdateRect( intermediary, 0, 0, 0, 0 );

intermediary = SDL_DisplayFormat(intermediary);

  SDL_SaveBMP(initial, "blah0.bmp");
  SDL_SaveBMP(intermediary, "blah1.bmp");

  SDL_FreeSurface( initial );

glEnable(GL_TEXTURE_2D);

	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels );

  texture_data tex_temp;

  tex_temp.filepath = "text";
  tex_temp.texture = texture;
  tex_temp.texture_id = next_texture_store;

  texture_store.push_back(tex_temp);

  next_texture_store++;
cout << "Added text texture (#" << (next_texture_store - 1) << ")" << endl;

	/* Clean up */
	SDL_FreeSurface(initial);
	SDL_FreeSurface(intermediary);
	glDeleteTextures(1, &texture);

}


sorry about the lack of comments, just messed around with the code to much, anyway, blah0.bmp and blah1.bmp are both perfect images, the texture should print out to the screen on a ortho plane in another class, but doesn't. I tested the plane with other textures stored in memory and they worked but only this algorithum refuses to show anything. What does appear on the plane is the values set for glColor(); If anyone could help with this, i would be grateful. i have looked at other sources on the net but none of them can explain the problem with the code.

Share this post


Link to post
Share on other sites
Take a look at this article from GPWiki. Scroll down to the section titled "Drawing with OpenGL" - there is an example of loading a surface and using it to create an OpenGL texture.

[Edited by - Peregrin on September 8, 2005 4:12:55 AM]

Share this post


Link to post
Share on other sites
First comment out everything after the SDL_SaveBMP and check if it is in good health. [smile] Then, you could use this handy function of mine to see if you can texture anything with glBindTexture(GL_TEXTURE_2D, texture[0]). It should work for any BMP. Is texture_data a class of your own? Well make sure it's working ...


bool loadGLtextures(char *filename)
{
bool loaded = 0;
SDL_Surface *tex[1];

if (!filename)
{
printf("I couldn't find %s. Make sure it is there!\n", filename);
return false;
}

tex[0] = SDL_LoadBMP(filename);

if (tex[0])
{
glGenTextures(1, &texture[0]);

for (int loop=0; loop<1; loop++)
{
// linear filtered
glBindTexture (GL_TEXTURE_2D, texture[loop]);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex[loop]->w, tex[loop]->h, 0,
GL_BGR_EXT, GL_UNSIGNED_BYTE, tex[loop]->pixels);
}
loaded = 1;
}
if (tex[0])
SDL_FreeSurface(tex[0]);

return loaded;
}

Share this post


Link to post
Share on other sites
I think your problem may be the glDeleteTextures(1, &texture); at the end of your function. Comment that out and see if it works now. Otherwise...

Then the problem could be with the function TTF_RenderText_Blended. In all the SDL_ttf problem threads I've come across, that function always faield to work correctly. Try using TTF_RenderText_Solid just to see if it works. And if not...

I have a function written that does that, take a look at this thread for more information on what was going on.

Here is the funtion modified to convert a SDL_Surface to an OpenGL texture automatically:

// Function that will load an image file and create an OpenGL texture from it
bool SurfacetoTexture( SDL_Surface* imgFile1, GLuint *texture )
{
// If there is no image
if( !imgFile1 )
return false;

// This is the final image
SDL_Surface* imgFile = SDL_CreateRGBSurface( SDL_HWSURFACE, imgFile1->w, imgFile1->h, imgFile1->format->BitsPerPixel, imgFile1->format->Rmask, imgFile1->format->Gmask, imgFile1->format->Bmask, imgFile1->format->Amask);

// If the final image's space could not be allcoated
if( !imgFile )
return false;

// Loop though and fix the pixels
for( int y = 0; y < imgFile1->h; y++ )
{
for( int x = 0; x < imgFile1->w; x++ )
{
// Don't worry too much about trying to understand all of what follows, just know it works ;)

// This is the code that gets a pixel on a surface
Uint32 curPixel = 0;

int FinalX = x;
int FinalY = imgFile1->h - y - 1;

// Store the surface BPP
int bpp = imgFile1->format->BytesPerPixel;

// Here p is the address to the curPixel we want to retrieve
Uint8 *p = (Uint8 *)imgFile1->pixels + FinalY * imgFile1->pitch + FinalX * bpp;

switch(bpp)
{
case 1:
curPixel = (*p);

case 2:
curPixel = (*(Uint16 *)p);

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
curPixel = (p[0] << 16 | p[1] << 8 | p[2]);
else
curPixel = (p[0] | p[1] << 8 | p[2] << 16);

case 4:
curPixel = (*(Uint32 *)p);
}

// This is the code that will draw pixels
Uint8 *ubuff8;
Uint16 *ubuff16;
Uint32 *ubuff32;
Uint32 color = curPixel;
char c1, c2, c3;

// Lock the imgFile, if needed
if(SDL_MUSTLOCK(imgFile))
{
if(SDL_LockSurface(imgFile) < 0)
return false;
}

// How we draw the pixel depends on the bitdepth
switch(imgFile->format->BytesPerPixel)
{
case 1:
ubuff8 = (Uint8*) imgFile->pixels;
ubuff8 += (y * imgFile->pitch) + x;
*ubuff8 = (Uint8) color;
break;

case 2:
ubuff8 = (Uint8*) imgFile->pixels;
ubuff8 += (y * imgFile->pitch) + (x*2);
ubuff16 = (Uint16*) ubuff8;
*ubuff16 = (Uint16) color;
break;

case 3:
ubuff8 = (Uint8*) imgFile->pixels;
ubuff8 += (y * imgFile->pitch) + (x*3);

if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
{
c1 = (color & 0xFF0000) >> 16;
c2 = (color & 0x00FF00) >> 8;
c3 = (color & 0x0000FF);
}
else
{
c3 = (color & 0xFF0000) >> 16;
c2 = (color & 0x00FF00) >> 8;
c1 = (color & 0x0000FF);
}

ubuff8[0] = c3;
ubuff8[1] = c2;
ubuff8[2] = c1;
break;

case 4:
ubuff8 = (Uint8*) imgFile->pixels;
ubuff8 += (y*imgFile->pitch) + (x*4);
ubuff32 = (Uint32*)ubuff8;
*ubuff32 = color;
break;

default:
fprintf(stderr, "Error: Unknown bitdepth!\n");
return false;
}

/* Unlock the imgFile if needed */
if(SDL_MUSTLOCK(imgFile))
SDL_UnlockSurface(imgFile);
}
}

// Free this temporary surface
SDL_FreeSurface( imgFile1 );

// Create the texture
glGenTextures( 1, texture );

// Bind the texture
glBindTexture( GL_TEXTURE_2D, *texture );

// Build the texture now
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, imgFile->w, imgFile->h, GL_BGR, GL_UNSIGNED_BYTE, imgFile->pixels );

// Free the final image since we are done with it now
SDL_FreeSurface( imgFile );

// Return success
return true;
}




To use it:

SDL_Surface* imgFile1 = ...;
GLuint Mytexture;

if( !SurfacetoTexture( imgFile1, &Mytexture ) )
;// Error code handeling here


The imgFile1 that you pass in will be freed, so comment out the respective SDL_FreeSurface if you still need it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this