Nội dung bài viết
Đăng ký học lập trình C++
Tại STDIO bạn được dạy nền tảng lập trình tốt nhất.
Đăng ký học
Nguyễn Nghĩa Việc xuất hiện những dòng thông báo, hướng dẫn trong game là khá quan trọng. Giúp cho người dùng có thể hiểu và tiếp cận với game của chúng ta một cách nhanh chóng và dễ dàng nhất. Vậy những dòng text đó được vẽ lên màn hình như thế nào, thì bài viết này tôi sẽ hướng dẫn các bạn vẽ những dòng text đó sử dụng một thư viện mở rộng của SDL có tên là SDL_ttf.

Giới thiệu

Việc xuất hiện những dòng thông báo, hướng dẫn trong game là khá quan trọng. Giúp cho người dùng có thể hiểu và tiếp cận với game của chúng ta một cách nhanh chóng và dễ dàng nhất. Vậy những dòng text đó được vẽ lên màn hình như thế nào, thì bài viết này tôi sẽ hướng dẫn các bạn vẽ những dòng text đó sử dụng một thư viện mở rộng của SDL có tên là SDL_ttf (TrueType  Font).

Tiền đề bài viết

Tiếp nối những bài viết hướng dẫn lập trình với framework SDL (Simple DirectMedia Layer).

Đối tượng hướng đến

Những lập trình viên đã có kiến thức vững chắc về ngôn ngữ lập trình C++, mong muốn xây dựng game cơ bản sử dụng framework SDL.

Cài đặt thư viện

Đầu tiên các bạn vào trang https://www.libsdl.org/projects/SDL_ttf/Tại mục Development Libraries download file SDL2_ttf-devel-2.0.12-VC.zip (vì ở đây tôi đang sử dụng nền tảng Windows).

ss_1

Sau khi download xong và giải nén ra ta được hai thư mục là include lib. Việc 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ác bạn có thể xem phần Cài đặt thư viện SDL_mixer ở bài viết Play Audio Trong SDL.

Chúng ta cần phải 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 chúng ta phải 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 ở bài viết Load Texture Trong SDL thì việc vẽ một đoạn text lên màn hình hoàn toàn tương tự:

SDL_ttf có định nghĩa sẵn một struct có tên là TTF_Font giúp ta 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à fontsize.

Bài viết này tôi sẽ sử dụng font chữ VeraMoBd.ttf, với fontsize 30.

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

Tiếp theo chúng ta 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);

Ở trên ta dùng hàm TTF_RenderText_Solid với các đối số truyền vào là đối tượng font, chuỗi ta muốn hiển thị và màu sắc mà ta 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ác bạn có thể thử từng hàm để xem sự khác biệt của nó.

Tiếp theo ta 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 độ ta 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 draw và update

//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

https://www.libsdl.org/projects/SDL_ttf/ - 06/08/2015

http://www.libsdl.org/projects/docs/SDL_ttf/SDL_ttf_35.html - 06/08/2015

 

 

 

THẢO LUẬN
ĐÓNG