The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
[SDL2]-Problems With SDL_BlitSurface()-Need Help!
JeZ-l-Lee


Joined: 20 Sep 2009
Posts: 572
Location: Long Island, New York, United States, Earth
[SDL2]-Problems With SDL_BlitSurface()-Need Help!

Hi,

I am on a quest to make my SDL2_TTF based TTF text drawing function as fast as technically possible!
I am using current SDL2 with current SDL2_TTF and am trying to optimize TTF text drawing.

My optimization idea is to save the last 100 TTF text drawn surfaces
and search the 100 TTF text drawn surface cache for an identical TTF text
and use the TTF text drawn surface from cache to significantly improve TTF text drawing performance.

My header file has the following code:
Code:
int TextCacheCurrentIndex;

#define NumberOfTextCached     100
struct TextCached
{
    SDL_Surface *TextSurface;
    SDL_Surface *TextOutlineSurface;
    char TextCachedText[255];
    int ScreenX;
    int ScreenY;
} TextsCached[NumberOfTextCached];

My TTF text drawing function has the following code:
Code:
//-------------------------------------------------------------------------------------------------
void Visuals::DrawTextOntoScreenBuffer(const char *textToDisplay, TTF_Font *font, int posX, int posY
                                       , Uint8 XJustification, Uint8 textRed, Uint8 textGreen, Uint8 textBlue
                                       , Uint8 outlineRed, Uint8 outlineGreen, Uint8 outlineBlue)
{
SDL_Color textColor = { textRed, textGreen, textBlue, 255 };
SDL_Color outlineColor = { outlineRed, outlineGreen, outlineBlue, 255 };
SDL_Surface *text = NULL;
SDL_Surface *textOutline = NULL;
SDL_Texture *textTexture = NULL;
SDL_Texture *textOutlineTexture = NULL;
SDL_Rect destinationRect;
SDL_Rect destinationOutlineRect;
int windowWidth;
int windowHeight;
int textCacheCheckIndex = 0;

    for (textCacheCheckIndex = 0; textCacheCheckIndex < NumberOfTextCached; textCacheCheckIndex++)
    {
        if ( strcmp(TextsCached[textCacheCheckIndex].TextCachedText, textToDisplay) == 0
           && TextsCached[textCacheCheckIndex].ScreenX == posX
           && TextsCached[textCacheCheckIndex].ScreenY == posY )  break;
        else if ( textCacheCheckIndex == (NumberOfTextCached-1) )  textCacheCheckIndex = NumberOfTextCached;
    }

    if (textCacheCheckIndex < NumberOfTextCached)
    {
        if ( SDL_BlitSurface(TextsCached[TextCacheCurrentIndex].TextSurface, NULL, text, NULL) != 0 )
            printf( "SDL_BlitSurface(text) Failed: %s\n", SDL_GetError() );

        if ( SDL_BlitSurface(TextsCached[TextCacheCurrentIndex].TextOutlineSurface, NULL, textOutline, NULL) != 0 )
            printf( "SDL_BlitSurface(textOutline) Failed: %s\n", SDL_GetError() );
    }
    else
    {
        text = TTF_RenderText_Blended(font, textToDisplay, textColor);
        textOutline = TTF_RenderText_Solid(font, textToDisplay, outlineColor);
        strcpy(TextsCached[TextCacheCurrentIndex].TextCachedText, textToDisplay);
        TextsCached[TextCacheCurrentIndex].ScreenX = posX;
        TextsCached[TextCacheCurrentIndex].ScreenY = posY;

        if ( SDL_BlitSurface(text, NULL, TextsCached[TextCacheCurrentIndex].TextSurface, NULL) != 0 )
            printf( "SDL_BlitSurface(TextSurface) Failed: %s\n", SDL_GetError() );

        if ( SDL_BlitSurface(textOutline, NULL, TextsCached[TextCacheCurrentIndex].TextOutlineSurface, NULL) != 0 )
            printf( "SDL_BlitSurface(TextOutlineSurface) Failed: %s\n", SDL_GetError() );

        if (TextCacheCurrentIndex < NumberOfTextCached)  TextCacheCurrentIndex++;
        else  TextCacheCurrentIndex = 0;
    }

    if (XJustification == JustifyLeft)
    {
        posX = posX + (text->w / 2);
    }
    else if (XJustification == JustifyCenter)
    {
        posX = (640 / 2);
    }
    else if (XJustification == JustifyRight)
    {
        posX = (640 - posX) - (text->w / 2);
    }
    else if (XJustification == JustifyCenterOnPoint)
    {
        posX = posX;
    }

    textTexture = SDL_CreateTextureFromSurface(Renderer, text);
    textOutlineTexture = SDL_CreateTextureFromSurface(Renderer, textOutline);

    SDL_GetWindowSize(Window, &windowWidth, &windowHeight);

    float winWidthFixed;
    float winHeightFixed;
    if (ForceAspectRatio == false)
    {
        winWidthFixed = (float)windowWidth / 640;
        winHeightFixed = (float)windowHeight / 480;
    }
    else
    {
        winWidthFixed = 1;
        winHeightFixed = 1;
    }

    destinationRect.x = (posX * winWidthFixed) - ( (text->w * winWidthFixed) / 2 );
    destinationRect.y = (posY * winHeightFixed) - (winHeightFixed / 2) + 3;
    destinationRect.w = text->w * (winWidthFixed);
    destinationRect.h = text->h * (winHeightFixed);

    destinationOutlineRect.x = destinationRect.x;
    destinationOutlineRect.y = destinationRect.y;
    destinationOutlineRect.w = destinationRect.w;
    destinationOutlineRect.h = destinationRect.h;

    for (Sint16 y = -3; y < 4; y+=1)
    {
        for (Sint16 x = -3; x < 4; x+=1)
        {
            destinationOutlineRect.x = destinationRect.x + x;
            destinationOutlineRect.y = destinationRect.y + y;
            SDL_RenderCopyEx(Renderer, textOutlineTexture, NULL, &destinationOutlineRect, 0, NULL, SDL_FLIP_NONE);
        }
    }

    SDL_RenderCopyEx(Renderer, textTexture, NULL, &destinationRect, 0, NULL, SDL_FLIP_NONE);

    SDL_DestroyTexture(textOutlineTexture);
    SDL_DestroyTexture(textTexture);
    SDL_FreeSurface(text);
    SDL_FreeSurface(textOutline);
}

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

When I run the game, it prints some SDL_BlitSurface() errors and then quickly crashes.
Here is command prompt output:
Code:
SDL2 initialized.
SDL2 window created.
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
OpenGL Warning: Assertion failed: obj, file D:\tinderbox\add-4.3\src\VBox\Additi
ons\common\crOpenGL\pack\packspu_glsl.c, line 210
SDL renderer created.
Loaded all TTF fonts into memory.
No USB joysticks are plugged in.
SDL2_Mixer initialized.
Loaded all music into memory.
Loaded all sounds into memory.
Main loop started...
SDL_BlitSurface(TextSurface) Failed: SDL_UpperBlit: passed a NULL surface
SDL_BlitSurface(TextOutlineSurface) Failed: SDL_UpperBlit: passed a NULL surface

SDL_BlitSurface(TextSurface) Failed: SDL_UpperBlit: passed a NULL surface
SDL_BlitSurface(TextOutlineSurface) Failed: SDL_UpperBlit: passed a NULL surface

SDL_BlitSurface(TextSurface) Failed: SDL_UpperBlit: passed a NULL surface
SDL_BlitSurface(TextOutlineSurface) Failed: SDL_UpperBlit: passed a NULL surface

SDL_BlitSurface(text) Failed: SDL_UpperBlit: passed a NULL surface
SDL_BlitSurface(textOutline) Failed: SDL_UpperBlit: passed a NULL surface

Process returned -1073741819 (0xC0000005)   execution time : 5.248 s
Press any key to continue.

My question is how do I properly use SDL_BlitSurface() to copy one SDL_Surface to another SDL_Surface using SDL2?
I am receiving "SDL_BlitSurface(...) Failed: SDL_UpperBlit: passed a NULL surface" errors and don't know how to fix them?
I need to copy SDL_Surface to another new SDL_Surface - am I missing something in my code to successfully do this?

Any help would be appreciated, thank you!
[SDL2]-Problems With SDL_BlitSurface()-Need Help!
Jonas Kulla
Guest

SDL is telling you that you're passing a NULL surface pointer into the blit function.

Have you tried investigating why your code is doing that?
Re: [SDL2]-Problems With SDL_BlitSurface()-Need Help!
JeZ-l-Lee


Joined: 20 Sep 2009
Posts: 572
Location: Long Island, New York, United States, Earth
Jonas Kulla wrote:
SDL is telling you that you're passing a NULL surface pointer into the blit function.

Have you tried investigating why your code is doing that?
Hi,

I've looked for hours and can't figure out why it's a NULL surface pointer.
I am relatively new to SDL2 and was hoping someone could look at the above code
and tell me what is wrong with it?

Do I need to do something to initialize a new SDL_Surface?
The optimization will work when this NULL surface pointer issue is solved.
Thanks!

Here is a URL link to the forum post for people reading this in the mailing list:
http://forums.libsdl.org/viewtopic.php?t=10830