Rendering Text on the screen in real time

Hello

I’m following Lazy Foo’s tutorial on rendering True Type Fonts. This would be in SDL 2 and it is his 16th tutorial.

It seems he loads the Fonts into video memory before rendering it to the screen .

This is nice but I would like to load things in real time. For example, I have a position of a character I would like to display that continuously updates. I can’t do this if it loads once .

I’ve tried putting the load media function in later but SDL crashes. In addition, I’ve tried following this tutorial ( http://stackoverflow.com/questions/3604889/sdl-sdl-ttf-how-do-you-render-text-in-sdlsdl-ttf-c) in order to render text as a surface. But that isn’t working. I’m not sure how to handle both textures and surfaces at the same time.

IS there an elegant way to get TTF on the screen in real time? I feel like this should be much easier.

I don’ really understand what you’re archiving. Mind me.

You could use SDL_TTF’s TTF_RenderGlyph() to render a single glyph (an image of the character, from the font file) into a surface, and optionally call TTF_GlyphMetrics() to get the glyph metrics information, then place the glyph surface anywhere you want on the screen. You can also use SDL_CreateTextureFromSurface() to create a new texture from the surface you get from that function, if you’re using SDL2 renderer.

If you’re archiving something like type writer effect, you could recall TTF_RenderText() to get the new surface every frame, or with a little logic that recall the function only when text changed.

Anyway if you need finer-grain control over how the text is rendered, I’d suggest you to try using FreeType 2 directly instead of SDL_TTF.

How many times per second do you want to display the text? How is it not
real time to have in video memory what you want rendered each sync cycle of
the monitor?On Feb 2, 2014 4:07 PM, “shinn497” wrote:

Hello

I’m following Lazy Foo’s tutorial on rendering True Type Fonts. This would
be in SDL 2 and it is his 16th tutorial.

It seems he loads the Fonts into video memory before rendering it to the
screen .

This is nice but I would like to load things in real time. For example, I
have a position of a character I would like to display that continuously
updates. I can’t do this if it loads once .

I’ve tried putting the load media function in later but SDL crashes. In
addition, I’ve tried following this tutorial (
http://stackoverflow.com/questions/3604889/sdl-sdl-ttf-how-do-you-render-text-in-sdlsdl-ttf-c)
in order to render text as a surface. But that isn’t working. I’m not sure
how to handle both textures and surfaces at the same time.

IS there an elegant way to get TTF on the screen in real time? I feel like
this should be much easier.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Are you trying to use SDL 1 or 2?

The font is indeed no inside the video memory. In fact I think it’s not even read into main memory entirely, unless you specified so (using TTF_OpenFontRW()).

The SDL_ttf is designed so you have to render text into a surface, then you blit it to the screen. This surface has to be blit every frame otherwise once you clear the screen it would disappear. You could, also, re-render the text every frame (although rendering text is quite heavy). That could be called ‘real-time text rendering’ I believe.

But if you want finer grain control over how the text is rendered, I think you have to go with using FreeType 2 (as I mentioned earlier).

Again could you explain more about what you’re trying to archive ? An example would be great. I still don’t really understand what you’re aiming to.

Thanks!

By real time, I mean I want to update and continually change the text. Specifically I want to display the X,Y position of the sprite I’m using. In Lazy_Foo’s tutorial, he uses the lTexture text wrapper class to convert the TTF surface into a texture and then renders the texture. This is unsuitable since he loads the Font once at the beginning and then Renders it in the loop. I have to continually update the font.

Currently I’m using SDL 2 (I said this in my original post by the way).

I’m going to try alex rou’s method since it seems the simplest but I’d prefer to still use textures. I’m sure the specifcs of both blitting a surface and rendering a texture. Sorry I’m kind of a noob. Games have text fonts in them all the time. You would think there would be a simple and elegant way of doing this.

The typical way for games to have performant text is to have, for each font used, a big texture atlas with all the necessary glyphs in it (either created beforehand with a tool, or at startup time with some code to get the glyphs rasterized from e.g. FreeType and upload them to the texture.)

Then the game can simply reference a subsection of the glyph-atlas (via texture coordinates of the vertices to be drawn) when it wants to draw a character. No re-uploading of glyphs to the GPU necessary.

This also lets the game batch up extremely long strings into a single draw call, since all the characters just reference different parts of the same texture and the game can just draw a bunch of vertices forming quads with a single call, so it?s quite efficient.

I don?t think all of that is viable with SDL_Render though (the batching part in particular.)On Feb 3, 2014, at 5:12 AM, shinn497 wrote:

By real time, I mean I want to update and continually change the text. Specifically I want to display the X,Y position of the sprite I’m using. In Lazy_Foo’s tutorial, he uses the lTexture text wrapper class to convert the TTF surface into a texture and then renders the texture. This is unsuitable since he loads the Font once at the beginning and then Renders it in the loop. I have to continually update the font.

Currently I’m using SDL 2 (I said this in my original post by the way).

I’m going to try alex rou’s method since it seems the simplest but I’d prefer to still use textures. I’m sure the specifcs of both blitting a surface and rendering a texture. Sorry I’m kind of a noob. Games have text fonts in them all the time. You would think there would be a simple and elegant way of doing this.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Update I tried implementbing alex’s examplbe but it came out white. It compiled though. I still left pieces from Lazy Foo’s code where he set up the render window and I kept his init and loadmedia functions.

Anyone want to tell me what I’m still doing wrong? I will need to render sprites as textures as well as blit fonts so I need to keep some of this stuff.

Code:
/This source code copyrighted by Lazy Foo’ Productions (2004-2013)
and may not be redistributed without written permission.
/

//Using SDL, SDL_image, SDL_ttf, standard IO, math, and strings
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <stdio.h>
#include
#include

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//The window we’ll be rendering to
SDL_Window* gWindow = NULL;

//The window renderer
SDL_Renderer* gRenderer = NULL;

//Globally used font
TTF_Font *gFont = NULL;

SDL_Surface *text_surface;
SDL_Surface *screen;
//Render text
SDL_Color textColor = { 0xFF, 0xA5, 0xFF };

bool init()
{
//Initialization flag
bool success = true;

//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
	printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
	success = false;
}
else
{
	//Enable VSync
	if( !SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" ) )
	{
		printf( "Warning: VSync not enabled!" );
	}

	//Set texture filtering to linear
	if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
	{
		printf( "Warning: Linear texture filtering not enabled!" );
	}

	//Create window
	gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
	if( gWindow == NULL )
	{
		printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
		success = false;
	}
	else
	{
		//Create renderer for window
		gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
		if( gRenderer == NULL )
		{
			printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
			success = false;
		}
		else
		{
			//Initialize renderer color
			SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );

			//Initialize PNG loading
			int imgFlags = IMG_INIT_PNG;
			if( !( IMG_Init( imgFlags ) & imgFlags ) )
			{
				printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
				success = false;
			}

			 //Initialize SDL_ttf
			if( TTF_Init() == -1 )
			{
				printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() );
				success = false;
			}
		}
	}
}

return success;

}

bool loadMedia()
{
//Loading success flag
bool success = true;

//Open the font
gFont = TTF_OpenFont( "./gearhead.ttf", 28 );
if( gFont == NULL )
{
	printf( "Failed to load lazy font! SDL_ttf Error: %s\n", TTF_GetError() );
	success = false;
}
else
{

}

return success;

}

void close()
{

//Free global font
TTF_CloseFont( gFont );
gFont = NULL;

//Destroy window
SDL_DestroyRenderer( gRenderer );
SDL_DestroyWindow( gWindow );
gWindow = NULL;
gRenderer = NULL;

//Quit SDL subsystems
TTF_Quit();
IMG_Quit();
SDL_Quit();

}

int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( “Failed to initialize!\n” );
}
else
{
//Load media
if( !loadMedia() )
{
printf( “Failed to load media!\n” );
}
else
{
//Main loop flag
bool quit = false;

		//Event handler
		SDL_Event e;

		//While application is running
		while( !quit )
		{
			//Handle events on queue
			while( SDL_PollEvent( &e ) != 0 )
			{
				//User requests quit
				if( e.type == SDL_QUIT )
				{
					quit = true;
				}
			}

			//Clear screen
			SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
			SDL_RenderClear( gRenderer );

            if(!(text_surface=TTF_RenderText_Solid(gFont,"Hello World!",textColor))) {
            //handle error here, perhaps print TTF_GetError at least
            } else {
            SDL_BlitSurface(text_surface,NULL,screen,NULL);
            //perhaps we can reuse it, but I assume not for simplicity.
            //SDL_FreeSurface(text_surface);
            }


			//Update screen
			SDL_RenderPresent( gRenderer );
		}
	}
}

//Free resources and close SDL
close();

return 0;

}

[quote=“shinn497”]Update I tried implementbing alex’s examplbe but it came out white. It compiled though. I still left pieces from Lazy Foo’s code where he set up the render window and I kept his init and loadmedia functions.

Anyone want to tell me what I’m still doing wrong? I will need to render sprites as textures as well as blit fonts so I need to keep some of this stuff.

You cannot render surfaces like that using a renderer, you have to decide if you want to use the renderer or not.

If you want to continue using a renderer then you have to first convert the surface to a texture.

SDL_Texture* tex = SDL_CreateTextureFromSurface( Renderer, Surface );

Then to display it:

SDL_RenderCopy( Renderer, tex, NULL, NULL );
SDL_RenderPresent( Renderer );

You can safely store the surface returned by TTF_RenderText and the texture generated by SDL_CreateTexture (generate and store these outside the loop if they are not changing). However for changing texts you have to regenerate the surface and texture each time the text gets updated. This will be extremely slow compared to making textures for 0 - 9 then drawing each number individually to form the coordinates, this way you only generate each texture once.

Greetings,

If you so happened to be interested in the kind of implementation that Alex talks about with using a texture atlas (indeed an efficient means of going about TTF rendering), take a look at:

include/nomlib/graphics/fonts/TrueTypeFont.hpp
src/graphics/fonts/TrueTypeFont.cpp

(Supporting files include the other files within that directory path, minus BitmapFont & IFont).

I’d stick with regenerating the texture each time the text is updated, AKA the slow, but easy method, just like Alex describes. I did the same thing he describes in my code before re-writing it. (I refactored my code for fine-grain access into rendering, not because of performance).

Cheers!On 2014/02/ 03, at 4:03, AlexRou wrote:

[quote=“shinn497”]Update I tried implementbing alex’s examplbe but it came out white. It compiled though. I still left pieces from Lazy Foo’s code where he set up the render window and I kept his init and loadmedia functions.

Anyone want to tell me what I’m still doing wrong? I will need to render sprites as textures as well as blit fonts so I need to keep some of this stuff.

You cannot render surfaces like that using a renderer, you have to decide if you want to use the renderer or not.

If you want to continue using a renderer then you have to first convert the surface to a texture.

SDL_Texture* tex = SDL_CreateTextureFromSurface( Renderer, Surface );

Then to display it:

SDL_RenderCopy( Renderer, tex, NULL, NULL );
SDL_RenderPresent( Renderer );

You can safely store the surface returned by TTF_RenderText and the texture generated by SDL_CreateTexture (generate and store these outside the loop if they are not changing). However for changing texts you have to regenerate the surface and texture each time the text gets updated. This will be extremely slow compared to making textures for 0 - 9 then drawing each number individually to form the coordinates, this way you only generate each texture once.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

So ,if I want to have my own Fonts from a texture, i should load 0123456789abcdef… and then write a function that associates each character to a position in the surface and then renders each individually?

It just seems odd that this isn’t built in to SDL or someone hasn’t made a library for it … sigh.

BTW I’m not entirely sure what the renderer is . Is there some literature on it and the specifics of what a surface is vs a texture?

shinn497 wrote:

So ,if I want to have my own Fonts from a texture, i should load 0123456789abcdef… and then write a function that associates each character to a position in the surface and then renders each individually?

It just seems odd that this isn’t built in to SDL or someone hasn’t made a library for it … sigh.

BTW I’m not entirely sure what the renderer is . Is there some literature on it and the specifics of what a surface is vs a texture?

The renderer is hardware accelerated rendering, using surfaces alone is software rendering. For a simple game and people starting out software rendering is more than enough, I would suggest you start off with SDL 1 and get familiar with things before using SDL 2 since there are less tutorials available and the renderer can confuse you. You can follow the lazy foo tutorials for SDL 1, do not skip to the parts you are interested in and do them one by one starting from the first one and make sure you understand what each tutorial is teaching you.

So ,if I want to have my own Fonts from a texture, i should load 0123456789abcdef… and then write a function that associates each character to a position in the surface and then renders each individually?

Yes. (Very similar in concept to how bitmap fonts are rendered). Lazy foo tutorials has all the implementation details you need for this.

It just seems odd that this isn’t built in to SDL or someone hasn’t made a library for it … sigh.

BTW I’m not entirely sure what the renderer is . Is there some literature on it and the specifics of what a surface is vs a texture?

Sorry, no literature from me other than perhaps the migration guide for SDL2. Surfaces are stored in system RAM, and are best used where pixel-level manipulation is needed. Note that a surface is unaccelerated (work has to be done by CPU). Textures, on the other hand, are stored in GPU’s memory and therefore accelerated. Textures are an expensive resource to create, and are also bound by video RAM (therefore a limited resource), but are more efficient when used correctly. The expensive calls on a texture involve anytime you copy pixels to and from. In short: surfaces for processing (rescaling, pixel collision, etc) and textures for final rendering.On 2014/02/ 03, at 5:17, shinn497 wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Can you point me to the Lazy Foo tutorial where he does this? Since I’m going based off his tutorials, it would be easier to implement.

I can see how without researching ttf or openGL it would seem like you have
mentioned. Experts have combed over the way it’s done for years to produce
what you see in lazy foo’s examples. He didn’t make all that up. An example
of this is that it would seem like a good thing to make a texture with
1234567890abcdefgh and so on and then display a segment of this texture
each time you want a particular glyph from it. This is like a bitmap font.
For all of the reasons ttf are better than bmf it’s not a good idea unless
you just don’t need professional results or you plan to write extra code to
plan for the data ttf provides. Ttf has data components that change how one
glyph is presented only if it follows another particular glyph or anywhere
on that line there is a particular other glyph for example. If that sounds
complicated then hang on to your hat because I simplified it quite a bit!
Don’t think for minute that I’m disrespecting lazy. He takes the pieces of
sdl and crafts them with c into a simple form artwork that starting coders
can grasp. He’s an artist!
Anyone just staring out with sdl should trust that the makers of sdl and
sdl libs are bringing their A game, and that if you follow how they lead,
you are doing it right. Later when you understand what the codes are doing
in detail, by all means, try to improve on their work, build use case
specific examples, join the tide of code that lifts all boats of starting
game makers :slight_smile:
I’m standing on a chair waving a flag right now that says C/C++ &
SDL2. lol. I promise to build a web page that explains this stuff with use
case code included.

R A Manard
whisper8.com
p.s. Here is a full sdl2 example game code! Please don’t hate on it, cuz
it’s alpha. It’s not ready for release but it looks useful to you.On Mon, Feb 3, 2014 at 11:39 AM, shinn497 wrote:

Can you point me to the Lazy Foo tutorial where he does this? Since I’m
going based off his tutorials, it would be easier to implement.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

-------------- next part --------------
A non-text attachment was scrubbed…
Name: TWINDRAGON_SDL2_GAME_EXAMPLE.zip
Type: application/zip
Size: 9264 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20140203/e17aa51e/attachment.zip

Ok update. I noticed that in Lazy’s 32nd tutorial he changed the text in real time. This is the one for handling text input. In it he has a string variable that he loads into his lTexture class everytime he wants to update. I’m trying that right now but, every time I try to call the loadfromrenderedtext function my program crashes. It is weird. It works from the loadmedia function that Lazy Foo wrote but not anywhere else.

Why is this? I’m including my code. I wrote it so that it will load a texture when you hit backspace, a which point it will crash. I’m so close to getting this is to work and any advice would be so appreciated.

Code:
/This source code copyrighted by Lazy Foo’ Productions (2004-2013)
and may not be redistributed without written permission.
/

//Using SDL, SDL_image, standard IO, and strings
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include
#include <SDL_ttf.h>
#include
#include
//Level Dimensions
const int LEVEL_WIDTH = 4000;
const int LEVEL_HEIGHT = 700;
//Screen dimension constants
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int IDLE_FRAMES = 9;
const int RUN_FRAMES = 9;
const int JUMP_FRAMES = 12;
const float JILL_SCALE = 1.5;
const float GRAVITY = 1;
const int FRAME_SIZE = 100;
const int ANIM_SPEED = 4;
const int JUMP_SPEED = 17;
// Animation Variable.
// Note the sign Convention
enum Anim{
JILL_Walk,
JILL_Run,
JILL_Idle,
JILL_Dash,
Jill_Jump
};

//Texture wrapper class
class LTexture
{
public:
//Initializes variables
LTexture();

	//Deallocates memory
	~LTexture();

	//Loads image at specified path
	bool loadFromFile( std::string path );

	#ifdef _SDL_TTF_H
	//Creates image from font string
	bool loadFromRenderedText( std::string textureText, SDL_Color textColor );
	#endif

	//Deallocates texture
	void free();

	//Set color modulation
	void setColor( Uint8 red, Uint8 green, Uint8 blue );

	//Set blending
	void setBlendMode( SDL_BlendMode blending );

	//Set alpha modulation
	void setAlpha( Uint8 alpha );

	//Renders texture at given point
	void render( int x, int y, float scaler, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );

	//Gets image dimensions
	int getWidth();
	int getHeight();

private:
	//The actual hardware texture
	SDL_Texture* mTexture;

	//Image dimensions
	int mWidth;
	int mHeight;

};

class LTimer
{
private:
//The clock time when the timer started
Uint32 mStartTicks;

//The ticks stored when the timer was paused
Uint32 mPausedTicks;

//The timer status
bool mPaused;
bool mStarted;

public:
//Initializes variables
LTimer();

//The various clock actions
void start();
void stop();
void pause();
void unpause();

//Gets the timer's time
Uint32 getTicks();

//Checks the status of the timer
bool isStarted();
bool isPaused();

};

class Jill
{
public:

    int framer();

	//The dimensions of the dot
	static constexpr  int JILL_WIDTH = 100;
	static constexpr  int JILL_HEIGHT = 100;

	//Maximum axis velocity of the dot
	static constexpr  float JILL_VEL = 3;

	//Initializes the variables
	Jill();


	//Takes key presses and adjusts the dot's velocity
	void handleEvent( SDL_Event& e,const  Uint8* KeyStates );

	//Moves the dot
	void move();

	//Shows the dot on the screen
	void render(int camX, int camY, SDL_Rect* clip, SDL_Rect* clip2);

    void land();

	Anim GetAnim();

    //Position accessors
	int getPosX();
	int getPosY();

private:
	//The X and Y offsets of the dot
	float mPosX, mPosY;

	//The velocity of the dot
	float mVelX, mVelY;

    //Vertical distance
    float VertDis;

    //Vertical Velocity
    float VertVel;


	// The Current Animation
	Anim JillAnim ;

	// FlipState
	bool IsFlipped;

    bool InAir;

	// Collision Detection
	SDL_Rect mCollider;

	// The animation frame
	int Frame;

};
void printF(char *c, int x, int y);

//Starts up SDL and creates window
bool init();

//Loads media
bool loadMedia();

//Frees media and shuts down SDL
void close();

//Box collision detector
bool checkCollision( SDL_Rect a, SDL_Rect b );

//The window we’ll be rendering to
SDL_Window* gWindow = NULL;

//The window renderer
SDL_Renderer* gRenderer = NULL;

//Scene textures
LTexture gKunoTexture;
LTexture gBGTexture;
LTexture gTextTexture;
// SDL_Surface *DebugText = NULL;
//SDL_Color textColor = { 0, 0, 0 };
const int ANIMATION_FRAMES = IDLE_FRAMES + RUN_FRAMES + JUMP_FRAMES;
SDL_Rect gSpriteClips[ ANIMATION_FRAMES ];
//Globally used font
TTF_Font *gFont = NULL;

//Surface

SDL_Surface* fontSurface;
SDL_Surface* screen;
SDL_Color TextColor = { 0, 0, 0, 0xFF };

SDL_Rect fontRect;

LTexture::LTexture()
{
//Initialize
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}

LTexture::~LTexture()
{
//Deallocate
free();
}

bool LTexture::loadFromFile( std::string path )
{
//Get rid of preexisting texture
free();

//The final texture
SDL_Texture* newTexture = NULL;

//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
	printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
}
else
{
	//Color key image
	SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0xFF, 0, 0xFF ) );

	//Create texture from surface pixels
    newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface );
	if( newTexture == NULL )
	{
		printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
	}
	else
	{
		//Get image dimensions
		mWidth = loadedSurface->w;
		mHeight = loadedSurface->h;
	}

	//Get rid of old loaded surface
	SDL_FreeSurface( loadedSurface );
}

//Return success
mTexture = newTexture;
return mTexture != NULL;

}

#ifdef _SDL_TTF_H
bool LTexture::loadFromRenderedText( std::string textureText, SDL_Color textColor )
{
//Get rid of preexisting texture
free();

//Render text surface
SDL_Surface* textSurface = TTF_RenderText_Solid( gFont, textureText.c_str(), textColor );
if( textSurface != NULL )
{
	//Create texture from surface pixels
    mTexture = SDL_CreateTextureFromSurface( gRenderer, textSurface );
	if( mTexture == NULL )
	{
		printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
	}
	else
	{
		//Get image dimensions
		mWidth = textSurface->w;
		mHeight = textSurface->h;
	}

	//Get rid of old surface
	SDL_FreeSurface( textSurface );
}
else
{
	printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
}


//Return success
return mTexture != NULL;

}
#endif

void LTexture::free()
{
//Free texture if it exists
if( mTexture != NULL )
{
SDL_DestroyTexture( mTexture );
mTexture = NULL;
mWidth = 0;
mHeight = 0;
}
}

void LTexture::setColor( Uint8 red, Uint8 green, Uint8 blue )
{
//Modulate texture rgb
SDL_SetTextureColorMod( mTexture, red, green, blue );
}

void LTexture::setBlendMode( SDL_BlendMode blending )
{
//Set blending function
SDL_SetTextureBlendMode( mTexture, blending );
}

void LTexture::setAlpha( Uint8 alpha )
{
//Modulate texture alpha
SDL_SetTextureAlphaMod( mTexture, alpha );
}

void LTexture::render( int x, int y,float scaler, SDL_Rect* clip , double angle, SDL_Point* center, SDL_RendererFlip flip )
{
//Set rendering space and render to screen
SDL_Rect renderQuad = { x, y, mWidth, mHeight };

//Set clip rendering dimensions
if( clip != NULL )
{
	renderQuad.w = clip->w*scaler;
	renderQuad.h = clip->h*scaler;
}

//Render to screen
SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip );

}

int LTexture::getWidth()
{
return mWidth;
}

int LTexture::getHeight()
{
return mHeight;
}

Jill::Jill()
{
//Initialize the offsets
mPosX = 30;
mPosY = 400;

//Initialize the velocity
mVelX = 0;
mVelY = 0;

mCollider.w = JILL_WIDTH;
mCollider.h = JILL_HEIGHT;

//Initialize The Aniamtion
JillAnim = JILL_Idle;

// Set the Flip state and the other booleans
IsFlipped = false;

InAir = false;

Frame = 0;

        //Vertical distance
VertDis = 0;

    //Vertical Velocity
VertVel = 0;

}

int Jill::framer(){

if(JillAnim == JILL_Walk){
Frame ++;
if(Frame/ANIM_SPEED>17||(Frame/ANIM_SPEED)<9){
Frame =9*ANIM_SPEED;
}
}
else if(JillAnim == JILL_Idle){
Frame++;

                if(Frame/ANIM_SPEED>8){
                    Frame = 0;
                }
			}
			else if(JillAnim == Jill_Jump){
                Frame++;
                if((Frame/ANIM_SPEED)<18){
                Frame =18*ANIM_SPEED;
                }
                else if(Frame/ANIM_SPEED>=29){
                    land();
                }

			}
			return Frame;

}

void Jill::handleEvent( SDL_Event& e ,const Uint8* KeyStates )
{

/*
if (KeyStates[SDL_SCANCODE_DOWN]){

    mPosY += KUNO_VEL;
}

*/

//If a key was pressed

if( e.type == SDL_KEYDOWN && e.key.repeat == 0)
{
    //Adjust the velocity
    switch( e.key.keysym.sym )
    {
        case SDLK_UP: mVelY -= JILL_VEL; break;
        case SDLK_DOWN: mVelY += JILL_VEL; break;
        case SDLK_LEFT: mVelX -= JILL_VEL;  IsFlipped = true; break;
        case SDLK_RIGHT: mVelX += JILL_VEL; IsFlipped = false; break;
        case SDLK_SPACE: if(JillAnim != Jill_Jump){JillAnim = Jill_Jump; VertVel = JUMP_SPEED; InAir = true;} break;
    }

}


//If a key was released


if( e.type == SDL_KEYUP && e.key.repeat == 0 )
{
    //Adjust the velocity
    switch( e.key.keysym.sym )
    {

        case SDLK_UP: mVelY += JILL_VEL; break;
        case SDLK_DOWN: mVelY -= JILL_VEL; break;
        case SDLK_LEFT: mVelX += JILL_VEL; break;
        case SDLK_RIGHT: mVelX -= JILL_VEL; break;

    }
//}
}

}

void Jill::move()
{
//Move the dot left or right
mPosX += mVelX;

//If the dot went too far to the left or right
if( ( mPosX < 0 ) || ( mPosX + JILL_WIDTH > LEVEL_WIDTH ) )
{
    //Move back
    mPosX -= mVelX;
}

mPosY += mVelY;
//If the dot went too far up or down
if( ( mPosY < 0 ) || ( mPosY + JILL_HEIGHT > LEVEL_HEIGHT ) )
{

//    onGround = true;

    //Move back
    mPosY -= mVelY;
    /*
    mVelY = 0;
    onGround = true;
    mVelX = 0;
*/
}
VertVel-=GRAVITY;
VertDis+=VertVel;
if(VertDis<=0){
        land();

}

if(((mVelX)!= 0||(mVelY)!= 0)&&!(InAir)){
    JillAnim = JILL_Walk;
}
else if(!InAir){
    JillAnim = JILL_Idle;
}

}

void Jill::render(int camX, int camY, SDL_Rect* clip, SDL_Rect* clip2)
{
int rendY = mPosY - VertDis - camY;

gKunoTexture.render( mPosX - camX, mPosY-camY+110,JILL_SCALE, clip2 );

if(JillAnim == Jill_Jump){
    rendY -=30;
}


if(IsFlipped == false){
 /*       if(JillAnim == Jill_Jump){
        gKunoTexture.render( mPosX - camX, mPosY - camY,JILL_SCALE, clip );
        }
        else{  */
        gKunoTexture.render( mPosX - camX, rendY,JILL_SCALE, clip );

}
else if(IsFlipped == true){
gKunoTexture.render( mPosX - camX, rendY,JILL_SCALE, clip,0.0,NULL, SDL_FLIP_HORIZONTAL );
}
}

Anim Jill::GetAnim(){

return JillAnim;

}
int Jill::getPosX(){
return mPosX;
}
int Jill::getPosY(){
return mPosY;
}

void Jill::land(){
VertDis = 0;
VertVel = 0;
JillAnim = JILL_Idle;
InAir = false;

}

LTimer::LTimer()
{
//Initialize the variables
mStartTicks = 0;
mPausedTicks = 0;

mPaused = false;
mStarted = false;

}

void LTimer::start()
{
//Start the timer
mStarted = true;

//Unpause the timer
mPaused = false;

//Get the current clock time
mStartTicks = SDL_GetTicks();
mPausedTicks = 0;

}

void LTimer::stop()
{
//Stop the timer
mStarted = false;

//Unpause the timer
mPaused = false;

//Clear tick variables
mStartTicks = 0;
mPausedTicks = 0;

}

void LTimer::pause()
{
//If the timer is running and isn’t already paused
if( mStarted && !mPaused )
{
//Pause the timer
mPaused = true;

    //Calculate the paused ticks
    mPausedTicks = SDL_GetTicks() - mStartTicks;
	mStartTicks = 0;
}

}

void LTimer::unpause()
{
//If the timer is running and paused
if( mStarted && mPaused )
{
//Unpause the timer
mPaused = false;

    //Reset the starting ticks
    mStartTicks = SDL_GetTicks() - mPausedTicks;

    //Reset the paused ticks
    mPausedTicks = 0;
}

}

Uint32 LTimer::getTicks()
{
//The actual timer time
Uint32 time = 0;

//If the timer is running
if( mStarted )
{
    //If the timer is paused
    if( mPaused )
    {
        //Return the number of ticks when the timer was paused
        time = mPausedTicks;
    }
    else
    {
        //Return the current time minus the start time
        time = SDL_GetTicks() - mStartTicks;
    }
}

return time;

}

bool LTimer::isStarted()
{
//Timer is running and paused or unpaused
return mStarted;
}

bool LTimer::isPaused()
{
//Timer is running and paused
return mPaused && mStarted;
}

void printF(char *c, int x, int y){
/*fontSurface = TTF_RenderText_Solid(gFont, c, textColor);
fontRect.x = x;
fontRect.y = y;

    SDL_BlitSurface(fontSurface, NULL, screen, &fontRect);
    SDL_Flip(screen);

*/
}

bool init()
{
//Initialization flag
bool success = true;

//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
	printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
	success = false;
}
else
{
	//Enable VSync
	if( !SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" ) )
	{
		printf( "Warning: VSync not enabled!" );
	}

	//Set texture filtering to linear
	if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
	{
		printf( "Warning: Linear texture filtering not enabled!" );
	}

	//Create window
	gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
	if( gWindow == NULL )
	{
		printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
		success = false;
	}
	else
	{
		//Create renderer for window
		gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
		if( gRenderer == NULL )
		{
			printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
			success = false;
		}
		else
		{
			//Initialize renderer color
			SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );

			//Initialize PNG loading
			int imgFlags = IMG_INIT_PNG;
			if( !( IMG_Init( imgFlags ) & imgFlags ) )
			{
				printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
				success = false;
			}
					 //Initialize SDL_ttf
			if( TTF_Init() == -1 )
			{
				printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() );
				success = false;
			}
		}
	}
}

return success;

}

bool loadMedia()
{
//Loading success flag
bool success = true;

	gFont = TTF_OpenFont( "./Planet Of The Apes.ttf", 28 );
		if( gFont == NULL )
{
	printf( "Failed to load lazy font! SDL_ttf Error: %s\n", TTF_GetError() );
	success = false;
}
else
{
	//Render text
	SDL_Color textColor = { 0, 0, 0 };
	if( !gTextTexture.loadFromRenderedText( "sick", textColor ) )
	{
		printf( "Failed to render text texture!\n" );
		success = false;
	}

}

if( gFont == NULL )
{
	printf( "Failed to load lazy font! SDL_ttf Error: %s\n", TTF_GetError() );
	success = false;
}

//Load dot texture
// Kuno addition: load the kunoichi walk strip instead of the dot
if( !gKunoTexture.loadFromFile( "./JillSprites.png" ) )
{
	printf( "Failed to load dot texture!\n" );
	success = false;
}
	if( !gBGTexture.loadFromFile( "./BackGround.png" ) )
{
	printf( "Failed to load background texture!\n" );
	success = false;
}
else
{
//    int Frame_Subtotal = 0;
	//Set sprite clips
	// This is done in an array.
	for(int i = 0; i<9;i++){
	gSpriteClips[ i ].x =   i*FRAME_SIZE;
	gSpriteClips[ i ].y =   0;
	gSpriteClips[ i ].w =  FRAME_SIZE;
	gSpriteClips[ i ].h = FRAME_SIZE;

	}
	//Frame_Subtotal +=  IDLE_FRAMES;
	for(int i = 9; i < 18; i++){
      gSpriteClips[ i ].x =   (i-9)*FRAME_SIZE;
      gSpriteClips[ i ].y =   FRAME_SIZE;
      gSpriteClips[ i ].w =  FRAME_SIZE;
      gSpriteClips[ i ].h = FRAME_SIZE;
	}
    for(int i = 18; i <30; i++){
      gSpriteClips[ i ].x =   (i-18)*FRAME_SIZE;
      gSpriteClips[ i ].y =   2*FRAME_SIZE;
      gSpriteClips[ i ].w =  FRAME_SIZE;
      gSpriteClips[ i ].h = FRAME_SIZE+20;
    }
      gSpriteClips[ 30 ].x =  0;
      gSpriteClips[ 30 ].y =  400;
      gSpriteClips[ 30 ].w =  100;
      gSpriteClips[ 30 ].h =  50;
}
return success;

}

bool checkCollision( SDL_Rect a, SDL_Rect b )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;

//Calculate the sides of rect A
leftA = a.x;
rightA = a.x + a.w;
topA = a.y;
bottomA = a.y + a.h;

//Calculate the sides of rect B
leftB = b.x;
rightB = b.x + b.w;
topB = b.y;
bottomB = b.y + b.h;

//If any of the sides from A are outside of B
if( bottomA <= topB )
{
    return false;
}

if( topA >= bottomB )
{
    return false;
}

if( rightA <= leftB )
{
    return false;
}

if( leftA >= rightB )
{
    return false;
}

//If none of the sides from A are outside B
return true;

}

void close()
{
//Free loaded images
gKunoTexture.free();
gBGTexture.free();
//Free global font
TTF_CloseFont( gFont );
gFont = NULL;

//Destroy window
SDL_DestroyRenderer( gRenderer );
SDL_DestroyWindow( gWindow );
gWindow = NULL;
gRenderer = NULL;

//Quit SDL subsystems
IMG_Quit();
SDL_Quit();

}

int main( int argc, char* args[] )
{
std::string DeBugInfo;

std::ostringstream DebugConvert;

std::string DeBugOld = "";

bool renderText = false;

std::string TestText = "testing";
//Start up SDL and create window
if( !init() )
{
	printf( "Failed to initialize!\n" );
}
else
{
	//Load media
	if( !loadMedia() )
	{
		printf( "Failed to load media!\n" );
	}
	else
	{
		//Main loop flag
		bool quit = false;

		//Event handler
		SDL_Event e;

        SDL_Color TextColor = { 0, 0, 0, 0xFF };

     //   gTextTexture.loadFromRenderedText( "geese", TextColor );

        int frame = 11;

		//The jill that will be moving around on the screen
		Jill jill;

        //SDL camera
        SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };

		//While application is running
		while( !quit )
		{
			//Handle events on queue
			while( SDL_PollEvent( &e ) != 0 )
			{
				//User requests quit
				if( e.type == SDL_QUIT )
				{
					quit = true;
				}
                else if( e.type == SDL_KEYDOWN )
				{
					//Handle backspace
					if( e.key.keysym.sym == SDLK_BACKSPACE  )
					{

						renderText = true;
					}

				}

				//Handle input for the dot
				// The kunoichi

				const Uint8* currentKeyStates = SDL_GetKeyboardState( NULL );

				jill.handleEvent( e, currentKeyStates );
			}

			//Move the dot

			jill.move();
            //Center the camera over the dot
			camera.x = ( jill.getPosX() + Jill::JILL_WIDTH / 2 ) - SCREEN_WIDTH / 2;
			camera.y = ( jill.getPosY() + Jill::JILL_WIDTH/ 2 ) - SCREEN_HEIGHT / 2;

			//Keep the camera in bounds
			if( camera.x < 0 )
			{
				camera.x = 0;
			}
			if( camera.y < 0 )
			{
				camera.y = 0;
			}
			if( camera.x > LEVEL_WIDTH - camera.w )
			{
				camera.x = LEVEL_WIDTH - camera.w;
			}
			if( camera.y > LEVEL_HEIGHT - camera.h )
			{
				camera.y = LEVEL_HEIGHT - camera.h;
			}

              // Display infor... I don't know if I should be loading every frame
            DebugConvert << jill.getPosX();

            DeBugInfo = DebugConvert.str();

            if(renderText){
            //gTextTexture.loadFromRenderedText(TestText, textColor);
            gTextTexture.loadFromRenderedText("dick", TextColor);
            std::cout<<"dick";
            renderText = false;
            }



			//Clear screen
			SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
			SDL_RenderClear( gRenderer );

			//Render objects
            gBGTexture.render( 0, 0,1, &camera );
            gTextTexture.render( ( SCREEN_WIDTH - gTextTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gTextTexture.getHeight() ) / 2,1 );

            jill.render(camera.x, camera.y, &gSpriteClips[jill.framer()/ANIM_SPEED], &gSpriteClips[30]);

/*

            if(DeBugOld != DeBugInfo){

                DeBugOld = DeBugInfo;

         //       printF(DeBugInfo.c_str);

    //         std::cout<<DeBugInfo;
                std::cout<<"Debug chnged";
            }

*/

			//Update screen
			SDL_RenderPresent( gRenderer );

		}
	}
}

//Free resources and close SDL
close();

return 0;

}

[/code]

Sorry that is a lot of code and it is really messy.

I’ve isolated the problem to a SegFault Occuriing in TTFsizeUTF8.

according to the description, this occurs when there is a NULL font.

I believe I’ve confirmed this by checking if the font is NULL. I added a line that will print to console if gFont = NULL and it did.

anyone have an idea why this is? The gFont was already set in the load media function. Why would it turn back to NULL

Sorry that is a lot of code and it is really messy.

I’ve isolated the problem to a SegFault Occuriing in TTFsizeUTF8.

according to the description, this occurs when there is a NULL font.

I believe I’ve confirmed this by checking if the font is NULL. I added a
line that will print to console if gFont = NULL and it did.

anyone have an idea why this is? The gFont was already set in the load
media function. Why would it turn back to NULL


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

If you don’t need scalable fonts, you could always use something simpler
instead. Of course the basic method is the same: Load the font, create a
texture (or surface) and then render that on the screen in such a way that
it spells the words you want, but using a bitmap font instead of a TTF font
makes loading easier.
If you want an example, you can look at my SDL2 Ksec clock at
http://betteros.org/sw/ksec.php which uses SDL2 and PSF fonts (which come
with Linux) to display the time. The code is pretty minimal too.
If you really NEED ttf fonts, then nevermind, but I think most people,
especially game developers, do not need TTF at all. If you don’t need it,
it’s not worth the overhead in my opinion.

–PhilipOn Tue, Feb 4, 2014 at 10:14 AM, shinn497 wrote:

shinn497 wrote:

Can you point me to the Lazy Foo tutorial where he does this? Since I’m going based off his tutorials, it would be easier to implement.

This is what you would want in SDL 1 (you have to redownload and set things up again) http://lazyfoo.net/SDL_tutorials/lesson30/index.php

You should seriously consider going to SDL 1 instead and things will be less complex and less confusing for you.

I don’t care about complex or confusing! I actually prefer it since I find the more difficult things are the more powerful they become. I’m also really passionate about learning and solving from first principles. This is why my day job is a theoretical physicist :b (although I took a day off to figure this shit out). I was just a little frustrated since this caught me off guard. I thought it would be really easy.

Hey everyone thanks for your help! I solved the problem. The issue was that I was passing the font as a NULL pointer which was causing a segfault in the TTF font DLL. Not out of the clear though since, while I can update things on the screen, I’m having an issue converting ints to strings. I’ll figure it out though.

Btw thanks everyone for helping me! I’ve learned a lot. I will use this solution for the time being but will go through all of your suggestions. I’m a little time constraned since I’m developing on the off hours. But I will definately go through this thread in the future! Sorry my noobishness.