Jump to content
  • Advertisement
Sign in to follow this  
LordSputnik

SDL_CreateRGBSurface

This topic is 3790 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

Having solved my problem, I'm now printing off transparent text like there's no tomorrow... However, I've found that I can only print 8 or 9 letters using this function:
//Renders text onto a Rect in GL.
void SDL_GL_RenderText(char *text, 
                      TTF_Font *font,
                      SDL_Color color,
                      SDL_Color bgcolor,
                      SDL_Rect *location,
                      int alignment,int transp,textquality quality)
{
	SDL_Surface *initial;
	SDL_Surface *intermediary;
	SDL_Rect rect;
	int w,h;
	GLuint texture;
	
	/* Use SDL_TTF to render our text */
    if (quality == solid)
    {
        initial = TTF_RenderText_Solid(font, text, color);
    }
    else if (quality == shaded)
    {
        initial = TTF_RenderText_Shaded(font, text, color, bgcolor);
    }
    else if (quality == blended)
    {
        initial = TTF_RenderText_Blended(font, text, color);
    }
	
	/* Convert the rendered text to a known format */
   w = initial->w;
   h = initial->h;
   t_height = initial->h;
   t_width = initial->w;
   printf("SDL_GL_RENDER_TEXT: Text Height: %i Width: %i\n",h,w);

if((quality == shaded) && (transp = 1))
{
printf("Error: Cannot render shaded text as transparent!");  
}
   
   intermediary = SDL_CreateRGBSurface(0, w, h, 32, 
			0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

   printf("SDL_GL_RENDER_TEXT: BREAKPOINT ALPHA\n");

   SDL_BlitSurface(initial, NULL, intermediary, NULL);

	/* Tell GL about our new texture */
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, 
			GL_UNSIGNED_BYTE, intermediary->pixels );
	
	/* GL_NEAREST looks horrible, if scaled... */
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	/* prepare to render our texture */
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture);
	glColor3f(1.0f, 1.0f, 1.0f);

	
   printf("SDL_GL_RENDER_TEXT: BREAKPOINT EPSILON\n");	

	/* Draw a quad at location */
	switch(alignment)
	{
        case 0: //Left
        if(transp == 1)
        {
            DrawRectTransparent(location->x,location->y,(location->x + w),(location->y + h));
        }
        else
        {
            DrawRect(location->x,location->y,(location->x + w),(location->y + h));
        }
            break;
        case 1: //Center
        if(transp == 1)
        {
            DrawRectTransparent((location->x - (w/2)),location->y,(location->x + (w/2)),location->y + h);
        }
        else
        {
            DrawRect((location->x - (w/2)),location->y,(location->x + (w/2)),location->y + h);
        }
            break;
        case 2: //Right
        if(transp == 1)
        {
            DrawRectTransparent((location->x + w),(location->y + h),location->x,location->y);
        }
        else
        {
            DrawRect((location->x + w),(location->y + h),location->x,location->y);
        }
            break;
    }
	
   printf("SDL_GL_RENDER_TEXT: BREAKPOINT FREDDY\n");	

	/* Bad things happen if we delete the texture before it finishes */
	glFinish();

   printf("SDL_GL_RENDER_TEXT: BREAKPOINT GAMMA\n");	
	
	/* return the deltas in the unused w,h part of the rect */
	location->w = initial->w;
	location->h = initial->h;
	
   printf("SDL_GL_RENDER_TEXT: BREAKPOINT HALO\n");	

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

   printf("SDL_GL_RENDER_TEXT: BREAKPOINT INDIGO\n");	
}
Having identified the problem as being the SDL_CreateRGBSurface(), I was wondering if anyone could tell me how/where I'm going wrong, or if there's a much better way to do this. Thanks once more! Sputty.

Share this post


Link to post
Share on other sites
Advertisement
What is your actual problem? ie. What happens when you try? Error message? A crash? Visual problem? Your hard disk gets formatted?

Share this post


Link to post
Share on other sites
I am not sure your problem but here is how I render out a surface
It is similar to what you are trying to do




void Sprockets::SDL_GL_SurfaceToTexture(SDL_Surface * surface)
{

//need to refine this
if(m_GLTexture!=0)
{
glDeleteTextures( 1, &m_GLTexture);
m_iTextureH=0;
m_iTextureW=0;
m_GLTexture=0;

}
int h=NearestPowerOfTwo(surface->h);
int w=NearestPowerOfTwo(surface->w);
Uint32 rmask, gmask, bmask, amask;
SDL_Surface * temp = NULL;
SDL_Surface * tempalpha = NULL;


#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif
tempalpha = SDL_DisplayFormatAlpha(surface);
SDL_SetAlpha(surface, 0, SDL_ALPHA_TRANSPARENT);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,32, bmask, gmask, rmask, amask);


CreateTexture(temp,tempalpha);

//SDL_UnlockSurface(temp);
SDL_FreeSurface(temp);

SDL_FreeSurface(tempalpha);
//return texture;
}

void Sprockets::CreateTexture(SDL_Surface * _baseSurface,SDL_Surface * _image)
{
int h=NearestPowerOfTwo(_image->h);
int w=NearestPowerOfTwo(_image->w);
if(_baseSurface && _image)
{
glGenTextures(1, &m_GLTexture);
glBindTexture(GL_TEXTURE_2D, m_GLTexture);
//SDL_LockSurface(temp);


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, 4, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, _baseSurface->pixels);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,_image->w,_image->h,GL_BGRA,GL_UNSIGNED_BYTE,_image->pixels);
m_iTextureH=h;
m_iTextureW=w;

}
return;
}



Share this post


Link to post
Share on other sites
What's actually happening is that I'm typing, and the letters are being converted from unicode to string(I know that that part isn't causing the error), then the text is rendered by TTF_Render_Solid, and then when I try to make a new surface to blit it on, a Segmentation Fault occurs, and SDL deploys its parachute.

I can render surfaces fine, as well as preset text. It's only when I type, and make a new quad each time the phrase is updated, that it starts crashing.

Share this post


Link to post
Share on other sites
I forgot to post the code, so I'll do that now:

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

textc = new char[text.size()+1];
strcpy (textc, text.c_str());

/* Use SDL_TTF to render our text */
if (quality == solid)
{
initial = TTF_RenderText_Solid(font, textc, color);
}
else if (quality == shaded)
{
initial = TTF_RenderText_Shaded(font, textc, color, bgcolor);
}
else if (quality == blended)
{
initial = TTF_RenderText_Blended(font, textc, color);
}

/* Convert the rendered text to a known format */
w = initial->w;
h = initial->h;
t_width = initial->w;
printf("SDL_GL_RENDER_TEXT: Text Height: %i Width: %i\n",h,w);

if((quality == shaded) && (transp = 1))
{
printf("Error: Cannot render shaded text as transparent!");
}

intermediary = SDL_CreateRGBSurface(0, w, h, 32,
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

SDL_BlitSurface(initial, NULL, intermediary, NULL);

/* Tell GL about our new texture */
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, intermediary->pixels );

/* GL_NEAREST looks horrible, if scaled... */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

/* prepare to render our texture */
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glColor3f(1.0f, 1.0f, 1.0f);

/* Draw a quad at location */
switch(alignment)
{
case 0: //Left
DrawRect(location->x,location->y,(location->x + w),(location->y + h));
break;
case 1: //Center
DrawRect((location->x - (w/2)),location->y,(location->x + (w/2)),location->y + h);
break;
case 2: //Right
DrawRect((location->x + w),(location->y + h),location->x,location->y);
break;
}

/* Bad things happen if we delete the texture before it finishes */
glFinish();

/* return the deltas in the unused w,h part of the rect */
location->w = initial->w;
location->h = initial->h;

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


The CreateRGB is freezing it. I've noticed that when I press individual keys, or put a small delay in the main loop, the problem takes a lot longer to manifest...

Maybe CreateRGB is taking too long to run, and so my key pushes are crashing the program... Would finding a substitute to creating a new surface each time be the best way to move forward?

Anyway, any ideas as to the cause of the problem, or the best solution are much appreaciated, as always...

Thanks again,

Sputty.

Share this post


Link to post
Share on other sites
I need to see how you are calling this or can you post a code snip it (that compiles) that has the same issue so we can compile and run it.

At this point I can only guess at your issue.
Are you opening the font each time?
Are you forgetting to close the font before you are reopening it?

Currently I do not see any issue with the way you are calling CreateRGB.

Share this post


Link to post
Share on other sites
I'll try to make a demo program for you by tomorrow... In the meantime, it's being called from this:

void PrintChat(string print,TTF_Font *printfont,int fr,int fg,int fb,int br,int bg,int bb,int x,int y,int align,int wrap)
{
SDL_Rect printloc;
char* printline;
int linesz = 0;
t_height = 0;
printloc.x = x;
printloc.y = y;
printf("Printing: %s",print.c_str());
int i;

if(print.compare((print.length()-(int)strlen("\n")),(int)strlen("\n"),"\n") == 0)
{
print = print.substr(0,(print.length()-(int)strlen("\n")));
}

char* printc = new char[print.size()+1];
strcpy (printc, print.c_str());
printline = strtok(printc, "\n");

while(printline != NULL && (print.compare((linesz+(int)strlen(printline)),(int)strlen("\n"),"\n") == 0))
{
linesz += ((int)strlen(printline)+(int)strlen("\n"));
printloc.y += TTF_FontLineSkip(printfont);
SDL_GL_RenderText(printline,printfont,SetRGB(fr,fg,fb),SetRGB(br,bg,bb),&printloc,align,1,solid);
printline = strtok(NULL,"\n");
}
if(printline != NULL)
{
linesz += (int)strlen("\n");
}
printline = new char [(print.length()-linesz)+1];
printf("PRINTCHAT: STRCOPY!\n");
strcpy (printline,(print.substr(linesz-1,(print.length()-linesz)+1)).c_str());
printf("PRINTCHAT: Loop Done! Printing: '%s'. LineSZ: %i\n",printline,linesz);
printloc.y += TTF_FontLineSkip(printfont);
printf("PRINTCHAT: Rendering!\n");
SDL_GL_RenderText(printline,printfont,SetRGB(fr,fg,fb),SetRGB(br,bg,bb),&printloc,align,1,solid);
printf("T_Width: %i",t_width);
printf("PRINTCHAT: Render Sucessful!\n");
SDL_GL_SwapBuffers();
}





Which is being called everytime a key is pressed. The key is converted to unicode, and added to the chat buffer string, which is then passed as the first argument in the above function. I have the font that I use initialized globally outside the function (as TTF_Font* uifont), because I'm using it for more than one thing. I'm pretty sure it crashed on the CreateRGB... could it be that I'm calling it too frequently?

Share this post


Link to post
Share on other sites
Ok, I made a sample program which demostrates the problem. It can be found here. Thanks once again! Try typing something long, and see how it crashes :/

Share this post


Link to post
Share on other sites
I've downloaded the program and am playing around with it, and it doesn't appear to be crashing on SDL_CreateRGBSurface. It's actually crashing on SDL_FreeSurface(initial). Or, at least commenting out that line stops it from crashing. The 'initial' pointer must be getting corrupted along the way, and when you free it, it probably frees more than it's supposed to...

Oh, and the program is VERY laggy. The SDL documentation recommends you do not use SDL_EnableUNICODE( SDL_ENABLE ), as it slows everything WAY down. It's not too hard to just check for the letters yourself, and seeing as how it's many times faster, it's definitely worth it.

"UNICODE translation does create a slight overhead so don't enable it unless its needed."

[Edit:] Commenting out either of the two SDL_FreeSurface() lines stops it from crashing.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!