Thread: Render text

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    188

    Render text

    Ok, i have a small problem here with rendering TrueTypeFont text. The thing is, i don't know where and how to do this that i want to.

    I want it to display the points that the player have gathered. I know how to display the text but don't know how to make it show all the time. I don't know how to display a variable. Help me!

    Code:
    //The headers
    #include "SDL/SDL.h"
    #include "SDL/SDL_image.h"
    #include "SDL/SDL_ttf.h"
    #include <string>
    #include <iostream>
    #include <ctime> 
    #include <cstdlib>
    
    using namespace std;
    
    //Screen attributes
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;
    
    //The surfaces
    SDL_Surface *background = NULL;
    SDL_Surface *screen = NULL;
    SDL_Surface *piece = NULL;
    SDL_Surface *square = NULL;
    SDL_Surface *message = NULL;
    
    //The event structure
    SDL_Event event;
    
    //The font that's going to be used
    TTF_Font *font = NULL;
    
    //The color of the font
    SDL_Color textColor = { 255, 255, 255 };
    
    //The layers points and time
    string points;
    
    SDL_Surface *load_image( std::string filename ) 
    {
        //The image that's loaded
        SDL_Surface* loadedImage = NULL;
        
        //The optimized surface that will be used
        SDL_Surface* optimizedImage = NULL;
        
        //Load the image
        loadedImage = IMG_Load( filename.c_str() );
        
        //If the image loaded
        if( loadedImage != NULL )
        {
            //Create an optimized surface
            optimizedImage = SDL_DisplayFormat( loadedImage );
            
            //Free the old surface
            SDL_FreeSurface( loadedImage );
            
                    
            //If the image was optimized just fine
            if( optimizedImage != NULL )
            {
                //Map the color key
                Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0x0, 0xff, 0xff );
                
                //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
                SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey );
            }
        }
        
        //Return the optimized surface
        return optimizedImage;
    }
    
    SDL_Surface *apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
    {
        //Holds offsets
        SDL_Rect offset;
        
        //Get offsets
        offset.x = x;
        offset.y = y;
        
        //Blit
        SDL_BlitSurface( source, clip, destination, &offset );
        
        return 0;
    }
    
    bool init()
    {
        //Initialize all SDL subsystems
        if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
        {
            return false;    
        }
        
        //Set up the screen
        screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
        
        //If there was in error in setting up the screen
        if( screen == NULL )
        {
            return false;    
        }
        
        //Initialize SDL_ttf
        if( TTF_Init() == -1 )
        {
            return false;    
        }
        
        //Set the window caption
        SDL_WM_SetCaption( "Beautiful day", NULL );
        
        //If everything initialized fine
        return true;
    }
    
    bool load_files()
    {
        //Load the images
        background = load_image( "bg.png" );
        piece = load_image( "howto.png" );
        square = load_image( "square.png" );
        
        //Open the font
        font = TTF_OpenFont( "teen.ttf", 50 );
        
        //If there was a problem in loading the background
        if( background == NULL )
        {
            return false;    
        }
        
        //If there was a problem in loading the piece
        if( piece == NULL )
        {
            return false;    
        }
        
        //If there was a problem in loading the square
        if( square == NULL )
        {
            return false;    
        }
        
        //If everything loaded fine
        return true;
    }
    
    int clean_up()
    {
        //Free the surfaces
        SDL_FreeSurface( background );
        SDL_FreeSurface( piece );
        SDL_FreeSurface( square );
        SDL_FreeSurface( message );
        
        //Close the font that was used
        TTF_CloseFont( font );
        
        //Quit SDL_ttf
        TTF_Quit();
        
        //Quit SDL
        SDL_Quit();
        
        return 0;
    }
    
    //Random number
    int GetRand(int min, int max)
    {
      static int Init = 0;
      int rc;
      
      if (Init == 0)
      {
        srand(time(NULL));
        Init = 1;
      }
      
      rc = (rand() % (max - min + 1) + min);
      return (rc);
    }
    
    //Check if there is a collision
    bool check_coll( int sX, int sY, int pX, int pY )
    {
        //Square's position
        int sXl = sX;
        int sXr = sX + 29;
        int sYl = sY;
        int sYr = sY + 29;
        
        //Piece's position
        int pXl = pX;
        int pXr = pX + 75;
        int pYl = pY;
        int pYr = pY + 148;
        
        //Check if you hit the square
        if ((pXr >= sXl && pXr < sXr) || (pXl <= sXr && pXl > sXl) || (sXl >= pXl && sXl <= pXr) || (sXr <= pXr && sXr >= pXl)) 
        {
                 return true;
        }
        else
        {
            return false;
        }
    }
    
    //Move square if there is a collision
    void move_and_show_square( int & sX, int sY, int pX, int pY )
    {
         //If there is a collision
         if (check_coll( sX, sY, pX, pY ) == true)
         {
                         //Add points
                         points;
                         
                         //New position for the square
                         sX = GetRand(0,640);
                         
                         //Make the square move
                         SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00) );
                         apply_surface( 0, 0, background, screen );
                         piece = load_image( "piece.png" ); 
                         apply_surface( pX, pY, piece, screen ); 
         }
         
         //Apply the square
         apply_surface( sX, 300, square, screen );
    }
    
    int main( int argc, char* args[] )
    {
        //The piece's coordinates
        int x = 200;
        int y = 200;
        
        //The square's coordinates
        int sX = 400;
        int sY = 300;
        
        //Left flag
        bool left = false;
        
        //Right flag
        bool right = false;
        
        //Quit flag
        bool quit = false;
        
        //Initialize
        if( init() == false )
        {
            return 1;
        }
        
        //Load the files
        if( load_files() == false )
        {
            return 1;
        }
        
        //Apply the background
        apply_surface( 0, 0, background, screen );
        
        //Render and apply the points
        message = TTF_RenderText_Solid( font, "1", textColor );
        apply_surface( 20, 0, message, screen );
        
        //Apply the piece
        apply_surface( 70, 178, piece, screen );
        
        //While the user hasn't quit
        while( quit == false )
        {  
            //If there's an event to handle
            while (SDL_PollEvent(&event))
            {
                  if (event.type == SDL_KEYDOWN)
                  {
                                    switch(event.key.keysym.sym)
                                    {
                                                                   case SDLK_LEFT:
                                                                         left = true;
                                                                         break;
                                                                         
                                                                   case SDLK_RIGHT:
                                                                         right = true;
                                                                         break;
                                                                         
                                                                   case SDLK_ESCAPE:
                                                                        quit = true;
                                                                        break;
                   }                 }
                   
                   if (event.type == SDL_KEYUP)
                   {
                                     switch(event.key.keysym.sym)
                                     {
                                                                    case SDLK_LEFT:
                                                                          left = false;
                                                                          SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00) );
                                                                          apply_surface( 0, 0, background, screen );
                                                                          piece = load_image( "piece.png" ); 
                                                                          apply_surface( x, y, piece, screen ); 
                                                                          break;
                                                                    
                                                                    case SDLK_RIGHT:
                                                                         right = false;
                                                                         SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00) ); 
                                                                         apply_surface( 0, 0, background, screen );
                                                                         piece = load_image( "piece.png" ); 
                                                                         apply_surface( x, y, piece, screen ); 
                                                                         break;
                                     }
                   }      
                   
                }
                
                //Check if the right is pressed
                if (right == true)
                {
                             x = x + 1; 
                             if (x == 565) {
                                   x = x - 1;
                             }
                             SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00) ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-right.png" ); 
                             apply_surface( x, y, piece, screen ); 
                }
                
                //Check if the left is pressed
                if (left == true)
                {
                             x = x - 1; 
                             if (x == 0) {
                                   x = x + 1;
                             }
                             SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00) );
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-left.png" ); 
                             apply_surface( x, y, piece, screen ); 
                }  
                
                //Check collision and move the square
                move_and_show_square(sX, sY, x, y);
                 
                //If the user has Xed out the window
                if( event.type == SDL_QUIT )
                {
                    //Quit the program
                    quit = true;
                }
        
            //Update the screen
            if( SDL_Flip( screen ) == -1 )
            {
                return 1;    
            }
        }
            
            
        //Clean up
        clean_up();
        
        return 0;    
    }

  2. #2
    l'Anziano DavidP's Avatar
    Join Date
    Aug 2001
    Location
    Plano, Texas, United States
    Posts
    2,743
    Code:
        //Render and apply the points
        message = TTF_RenderText_Solid( font, "1", textColor );
        apply_surface( 20, 0, message, screen );
    As far as I could tell, this is the only point in the program where you render text and then display it to the screen, am I correct? On a brief glance at your code, I did not see any other points in the code where you display text.

    Taking that into account, the reason your text doesn't display forever is because you keep doing page flipping:

    Code:
            //Update the screen
            if( SDL_Flip( screen ) == -1 )
            {
                return 1;    
            }
    See that there? When you do page flipping, you are taking a huge block of memory, and you put that block of memory right onto the screen. The memory that is currently being displayed on the screen gets wiped, in preparation for the new block of memory that you are about to display.

    In the end, the new block gets displayed, and then you got a new fresh block to work with "off the screen".

    So what's happening is your text is probably being displayed for 1 frame of output. Then you page flip. After you flip the memory blocks, I see no evidence that you try to display the text again, and so it simply does not get displayed. You need to redraw it with every time you flip the memory blocks.

    So basically I would put your text output code at the very beginning of your while loop.

    If you want to display a variable, you need to convert that variable to a C-style string (a char *). You can convert integers and real numbers to char* strings using sprintf() or itoa(). itoa() is not a standard function, so you are safer with sprintf(). You can convert a C++ string (of the string class) to a char* string using the member function c_str().
    My Website

    "Circular logic is good because it is."

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Livijn View Post
    The thing is, i don't know where and how to do this that i want to.
    So the problem is that you don't know what you're doing.

    Welcome to the problems of many coders.

    The difference is that in order to get your project to work, you need to put the time and effort to understand it. Dropping a problem and saying you just don't understand what you're doing is not a way to encourage people to help you. It says that you're too lazy to even do some research into the problem.

    So if you won't do the research, why should someone else? And that's what I'm thinking now, partly because I'm overtired and partly because I'm not used to SDL and I don't know the answer offhand and I don't feel like researching it for you.

    Maybe when I've gotten some sleep and decided to be a little more human, I'll take a look.

  4. #4
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Actually i've been looking for the answer in weeks now. Can't find anything to help. I'm not good at searching, i guess. All i figured out was how the text stays. But how do i print a variable.

    If you don't want to help me with this problem, please give me some tips how to search.

    Have a nice day!

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You print a variable by first converting it to a string (there are various ways, all described in the FAQ) and then displaying the string.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Well, that doesn't seem to work at all...

    Code:
    Code:
                string points2 = IntToString( points );
                
                    //Render and apply the points
                    message = TTF_RenderText_Solid( font, points2 , textColor );
    Error:
    360 C:\Users\Fredrik\Desktop\Saker\Projekt\C++\SDL\Bea utiful Day\main.cpp cannot convert `std::string' to `const char*' for argument `2' to `SDL_Surface* TTF_RenderText_Solid(TTF_Font*, const char*, SDL_Color)'

    Anybody?

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    points2.c_str()
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Having trouble drawing text xlib.
    By Qui in forum Linux Programming
    Replies: 1
    Last Post: 05-10-2006, 12:07 PM
  2. Appending text to an edit control
    By dit6a9 in forum Windows Programming
    Replies: 3
    Last Post: 08-13-2004, 09:52 PM
  3. Text positioning and Text scrolling
    By RealityFusion in forum C++ Programming
    Replies: 3
    Last Post: 08-13-2004, 12:35 AM
  4. Scrolling The Text
    By GaPe in forum C Programming
    Replies: 3
    Last Post: 07-14-2002, 04:33 PM
  5. Replies: 1
    Last Post: 07-13-2002, 05:45 PM