Search…

Draw Text trong SDL

27/09/20204 min read
Hướng dẫn cách vẽ những dòng text trong game bằng cách sử dụng một thư viện mở rộng của SDL SDL_ttf (TrueType  Font).

Cài đặt thư viện

Tải thư viện tại đây, tại mục Development Libraries download file SDL2_ttf-devel-2.0.12-VC.zip (cho nền tảng Windows).

ss_1

Sau khi download xong và giải nén ra, được hai thư mục là include và lib, tính hợp thư viện SDL_ttf vào project trong Visual Studio hoàn toàn tương tự như đối với thư viện SDL_mixer.

Cần thêm chỉ thị #include <SDL_tff.h> vào đầu mỗi file muốn sử dụng thư viện này:

#include <SDL_ttf.h>

Draw Text lên màn hình

Trước khi bắt đầu thao tác với các hàm trong bộ thư viện, khởi tạo bằng cách sử dụng hàm TTF_Init(), hàm trả về 1 nếu khởi tạo thành công và ngược lại trả về 0 nếu khởi tạo thất bại.

//Initialize the truetype font API.
if (TTF_Init() < 0)
{
	SDL_Log("%s", TTF_GetError());
	return -1;
}

Tương tự sau khi thoát khỏi chương trình thì cần giải phóng tài nguyên:

//Shutdown and cleanup the truetype font API.
TTF_Quit();

Giống như vẽ một hình ảnh lên màn hình, vẽ một đoạn text lên màn hình cũng tương tự:

SDL_ttf có định nghĩa sẵn một struct có tên là TTF_Font giúp quản lý các thông tin liên quan đến font chữ để có thể vẽ lên màn hình. Và đi kèm với struct này thì có một hàm load prototype như sau:

TTF_Font* TTF_OpenFont(const char *file, int ptsize);

Với hai đối số truyền vào là tên của font chữ có đuôi mở rộng là .ttf và font size.

Bài viết sử dụng font chữ VeraMoBd.ttf, với font size 30.

TTF_Font* font = NULL;
font = TTF_OpenFont("VeraMoBd.ttf", 30);

Tiếp theo, tạo đối tượng surface và texture từ đối tượng font này:

SDL_Color fg = { 243, 156, 18 };
std::string text = "Welcome you to Stdio.vn";
SDL_Surface* surface = TTF_RenderText_Solid(font, text.c_str(), fg);

Dùng hàm TTF_RenderText_Solid với các đối số truyền vào là đối tượng font, chuỗi muốn hiển thị và màu sắc muốn vẽ. SDL_ttf có 3 chế độ để tạo đối tượng surface như sau:

Solid

TTF_RenderText_Solid Draw LATIN1 text in solid mode
TTF_RenderUTF8_Solid Draw UTF8 text in solid mode
TTF_RenderUNICODE_Solid Draw UNICODE text in solid mode
TTF_RenderGlyph_Solid Draw a UNICODE glyph in solid mode

Shaded

TTF_RenderText_Shaded       Draw LATIN1 text in shaded mode
TTF_RenderUTF8_Shaded Draw UTF8 text in shaded mode
TTF_RenderUNICODE_Shaded Draw UNICODE text in shaded mode
TTF_RenderGlyph_Shaded Draw a UNICODE glyph in shaded mode

Blended

TTF_RenderText_Blended  Draw LATIN1 text in blended mode
TTF_RenderUTF8_Blended Draw UTF8 text in blended mode
TTF_RenderUNICODE_Blended Draw UNICODE text in blended mode
TTF_RenderGlyph_Blended Draw a UNICODE glyph in blended mode

Có thể thử từng hàm để xem sự khác biệt của nó.

Tiếp theo, tạo đối tượng texture và hủy surface.

SDL_Texure* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);

Sử dụng SDL_Rect để xác định tọa độ muốn vẽ trên màn hình:

SDL_Rect srcRest;
SDL_Rect desRect;
TTF_SizeText(font, text.c_str(), &srcRest.w, &srcRest.h);

srcRest.x = 0;
srcRest.y =  0;

desRect.x = 200;
desRect.y = 270;

desRect.w = srcRest.w;
desRect.h = srcRest.h;

Cuối cùng drawupdate

//Copy a portion of the texture to the current rendering target.
SDL_RenderCopy(renderer, texture, &srcRest, &desRect);
//draw to screen
SDL_RenderPresent(renderer);

Source code demo

#include <stdio.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include <string>

#undef main

int main()
{
	SDL_Window* window = NULL;
	SDL_Renderer* renderer = NULL;
	bool isRunning = true;
	SDL_Event mainEvent;
	TTF_Font* font = NULL;
	SDL_Surface* surface = NULL;
	SDL_Texture* texture = NULL;

	//initializes  the subsystems
	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
	{
		printf("Unable to initialize SDL %s\n", SDL_GetError());
		return -1;
	}

	//Initialize the truetype font API.
	if (TTF_Init() < 0)
	{
		SDL_Log("%s", TTF_GetError());
		return -1;
	}

	//Create window
	window = SDL_CreateWindow("Stdio.vn - SDL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 640, SDL_WINDOW_SHOWN);
	if (window == NULL)
	{
		printf("Could not create window %s", SDL_GetError());
		return -1;
	}

	//create a renderer
	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
	if (renderer == NULL)
	{
		printf("Could not create render %s", SDL_GetError());
		return -1;
	}

	font = TTF_OpenFont("VeraMoBd.ttf", 30);

	SDL_Color fg = { 243, 156, 18 };

	std::string text = "Welcome you to Stdio.vn";
	surface = TTF_RenderText_Solid(font, text.c_str(), fg);
	texture = SDL_CreateTextureFromSurface(renderer, surface);
	SDL_FreeSurface(surface);

	SDL_Rect srcRest;
	SDL_Rect desRect;
	TTF_SizeText(font, text.c_str(), &srcRest.w, &srcRest.h);

	srcRest.x = 0;
	srcRest.y =  0;

	desRect.x = 200;
	desRect.y = 270;

	desRect.w = srcRest.w;
	desRect.h = srcRest.h;

	//set background color
	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	//main loop
	while (isRunning)
	{
		//main event
		while (SDL_PollEvent(&mainEvent))
		{
			switch (mainEvent.type)
			{
				//User - requested quit
				case SDL_QUIT:
				{
					isRunning = false;
					break;
				}
				default:
				{
					break;
				}
			}
		}
		// clear the window to black
		SDL_RenderClear(renderer);
		//Copy a portion of the texture to the current rendering target.
		SDL_RenderCopy(renderer, texture, &srcRest, &desRect);
		//draw to screen
		SDL_RenderPresent(renderer);
	}
	//Destroy a window.
	SDL_DestroyWindow(window);
	//Destroy a renderer
	SDL_DestroyRenderer(renderer);
	//Shutdown and cleanup the truetype font API.
	TTF_Quit();
	//cleans up all initialized subsystems
	SDL_Quit();
	return 0;
}

Kết quả sau khi chạy chương trình

ss_2

Download demo

Stdio_SDL_DrawText_VS2013.zip

Tham khảo

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024