Sign in to follow this  
starfruit64

SDL_TTF crashes c++ program?

Recommended Posts

Hello, this is my first time using this forum so if im doing something wrong please tell me. I am very new to programming and I have been playing around with SDL for a while. I am now trying to display text on the screen using SDL_ttf. Using an internet tutorial, I have made a "Display text" function in my Screen class. Before I added the code my program ran fine. Now it crashes, even if my main function is blank. My ide shows me no error. When I try to run the program in windows cmd i get the error: "The program can't start because SDL2_ttf.dll is missing from your computer. Try reinstalling the program to fix this problem."  This is strange because I can see "libSDL2_ttf.dll.a" in my SDL2 folder. 

Share this post


Link to post
Share on other sites

I can see "libSDL2_ttf.dll.a" in my SDL2 folder. 
 

'*.dll.a' is not a dynamic '.dll' library.  If library ends with .a - then this library is linked statically. In your case it's .dll.a, means it's import library, it tells your compiler's linker to search for actual function in some .dll file, linked later dynamically, by system. You still need libSDL2_ttf.dll

Share this post


Link to post
Share on other sites

 

I can see "libSDL2_ttf.dll.a" in my SDL2 folder. 
 

'*.dll.a' is not a dynamic '.dll' library.  If library ends with .a - then this library is linked statically. In your case it's .dll.a, means it's import library, it tells your compiler's linker to search for actual function in some .dll file, linked later dynamically, by system. You still need libSDL2_ttf.dll

 

This fixed the  "The program can't start because SDL2_ttf.dll is missing from your computer. Try reinstalling the program to fix this problem." but now I get a "The application was unable to start correctly (0xc000007b). Click OK to close the application." error, followed by a crash. Again, my main code is blank, and threes a single class with a header and .cpp (That I haven't even included).

Share this post


Link to post
Share on other sites

now I get a "The application was unable to start correctly (0xc000007b).
 

Check that dll you've copied was compiled for the same runtime as your main project. If something won't match (32-bit dll in 64-bit program, debugging/multithreading settings, etc), then program will fail to start.

Share this post


Link to post
Share on other sites

 

now I get a "The application was unable to start correctly (0xc000007b).
 

Check that dll you've copied was compiled for the same runtime as your main project. If something won't match (32-bit dll in 64-bit program, debugging/multithreading settings, etc), then program will fail to start.

 

This fixes the "The application was unable to start correctly (0xc000007b)." error. Now i just get a crash. Anytime i use something related to SDL_TTF i get a crash, with no error in Eclipse. Any ideas?

Share this post


Link to post
Share on other sites

Anytime i use something related to SDL_TTF i get a crash
 

Now it might be anything, since it's your actions. You'll have to show minimal crashing example, which we can build and test. Maybe you didn't initialize library properly, or misused it in some other way.

Share this post


Link to post
Share on other sites

 

Anytime i use something related to SDL_TTF i get a crash
 

Now it might be anything, since it's your actions. You'll have to show minimal crashing example, which we can build and test. Maybe you didn't initialize library properly, or misused it in some other way.

 

 

Alright here is the minimal it takes to crash the program. I tested each step as i added code, and it only crashed once i got to this:

#include <iostream>
#include <fstream>
#include <SDL.h>
#include "SDL_ttf.h"
#include "Input.h"
#include "Screen.h"

const static int WIDTH = 800;
const static int HIGHT = 600;

using namespace std;
int main(int argc, char* argv[]) {

	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		SDL_Quit();
	}
	if (TTF_Init() == -1) {
		SDL_Quit();

	}

	SDL_Window *window = SDL_CreateWindow("test",
	SDL_WINDOWPOS_UNDEFINED,
	SDL_WINDOWPOS_UNDEFINED, WIDTH, HIGHT, SDL_WINDOW_SHOWN);
	if (window == NULL) {
		return false;
	}

	SDL_Renderer *renderer = SDL_CreateRenderer(window, -1,
			SDL_RENDERER_PRESENTVSYNC);
	if (renderer == NULL) {
		return false;
		SDL_DestroyWindow(window);
		SDL_Quit();
	}

	SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
			SDL_TEXTUREACCESS_STATIC, WIDTH, HIGHT);
	if (texture == NULL) {
		return false;
		SDL_DestroyWindow(window);
		SDL_DestroyRenderer(renderer);
		SDL_Quit();
	}

	TTF_Font* font = TTF_OpenFont("Sans.ttf", 24);

		SDL_Color color = {255, 255, 255};

		SDL_Surface* surfaceMessage = TTF_RenderText_Solid(font, "Hello World!", color);

		SDL_Texture* message = SDL_CreateTextureFromSurface(renderer, surfaceMessage);
		SDL_Rect message_rect;
		message_rect.x = 0;
		message_rect.y = 0;
		message_rect.w = 100;
		message_rect.h = 100;



		SDL_RenderCopy(renderer, message, NULL, &message_rect);


	SDL_Quit();
	TTF_Quit();
	return 0;
}
Edited by starfruit64

Share this post


Link to post
Share on other sites

This code would crash if no "Sans.ttf" file could be found in app's current working directory. It doesn't crash otherwise for me. Check what's result from `TTF_OpenFont()`, is it null or a valid pointer.

Share this post


Link to post
Share on other sites
Also when you detect an error (e.g. window == null), try printing SDL_GetError() to the console before quitting. If you get an error with SDL_TTF, use TTF_GetError().

If you "return false" from main(), technically you are reporting your program ran successfully. Main returns an "Int", not a boolean (although a boolean will convert to an Int). So when an error occurs, use " return 1" instead, or you can use EXIT_FAILURE (http://en.cppreference.com/w/cpp/utility/program/EXIT_status).

Share this post


Link to post
Share on other sites

This code would crash if no "Sans.ttf" file could be found in app's current working directory. It doesn't crash otherwise for me. Check what's result from `TTF_OpenFont()`, is it null or a valid pointer.

How can I check this? I think you are right in that i dont have Sans.ttf in the current working directory, but how can i find out what that directory is?

Share this post


Link to post
Share on other sites

Working directory could be anything, and probably you don't need to know that at all.

What you need to know is where .exe file located, so resources could be read by the path relative to .exe location. See SDL_GetBasePath() function: https://wiki.libsdl.org/SDL_GetBasePath

Place your assets near exe file, maybe in subdirectories. Then open it by concatenated name - base path and asset file name.

Share this post


Link to post
Share on other sites

Working directory could be anything, and probably you don't need to know that at all.

What you need to know is where .exe file located, so resources could be read by the path relative to .exe location. See SDL_GetBasePath() function: https://wiki.libsdl.org/SDL_GetBasePath

Place your assets near exe file, maybe in subdirectories. Then open it by concatenated name - base path and asset file name.

Alright you and everyone else has been super helpful. This fixed the crash but now when I run the program and update the screen, the text isn't there. My code is this: 


#include <iostream>
#include <fstream>
#include <SDL.h>
#include "SDL_ttf.h"
#include "Input.h"
#include "Screen.h"


using namespace std;
Screen screen;
Input input;
SDL_Renderer *renderer;
int main(int argc, char* argv[]) {
	 screen.init();

	 screen.test_text();

	 screen.update();


	 while (true) {
	     string event = input.check_event();
	     if(event == "1"){
	    	 break;
	     }
	 }

	TTF_Quit();
	SDL_Quit();
    return 0;
}


 

screen.init(); does this:

bool Screen::init() {
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		return false;
	}
	if(TTF_Init()==-1) {
		     printf("TTF_Init: %s\n", TTF_GetError());
		     exit(2);
	 }

	window = SDL_CreateWindow("Particle Simulation", SDL_WINDOWPOS_UNDEFINED,
	SDL_WINDOWPOS_UNDEFINED, WIDTH, HIGHT, SDL_WINDOW_SHOWN);
	if (window == NULL) {
		return false;
	}
	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
	if (renderer == NULL) {
		return false;
		SDL_DestroyWindow(window);
		SDL_Quit();
	}
	texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
			SDL_TEXTUREACCESS_STATIC, WIDTH, HIGHT);
	if (texture == NULL) {
		return false;
		SDL_DestroyWindow(window);
		SDL_DestroyRenderer(renderer);
		SDL_Quit();
	}
	buffer = new Uint32[WIDTH * HIGHT];

	return true;
} 

screen.test_text(); does this:

void Screen::test_text(){
	TTF_Font* font = TTF_OpenFont("C:\\Users\\KP7\\Desktop\\C++2\\Hero\\Debug\\block.ttf", 24); 

	SDL_Color color = {255, 255, 255};  

	SDL_Surface* surfaceMessage = TTF_RenderText_Solid(font, "Hello World!", color); 

	SDL_Texture* message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); 

	SDL_Rect message_rect; 
	message_rect.x = 0;  
	message_rect.y = 0; 
	message_rect.w = 100; 
	message_rect.h = 100; 

	

	SDL_RenderCopy(renderer, message, NULL, &message_rect); 
} 

and screen.update(); does this:

void Screen::update() {
	SDL_UpdateTexture(texture, NULL, buffer, WIDTH * sizeof(Uint32));
	SDL_RenderClear(renderer);
	SDL_RenderCopy(renderer, texture, NULL, NULL);
	SDL_RenderPresent(renderer);
} 

This just displays a black screen for me. Does anyone know why?

Share this post


Link to post
Share on other sites

Screen::update does a SDL_RenderClear, which essentially deletes everything you tried to render in test_text.

Additionally, you have a SDL_RenderCopy there as well, which I assume would overwrite anything you have in text_text.

 

You should reshuffle your code a bit:

1. Load everything you need (fonts, etc.).

2. While loop, lasting until some condition:

3a. Clear.

3b. Draw stuff (background, then text). Could also be just text, to make things slightly less complicated.

3c. Present.

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