STDIO
Tìm kiếm gần đây

    Nội dung

    Load Texture Trong SDL

    15/10/2015
    03/06/2020
    Load Texture Trong SDL
    Với những engine như cocos2dx, hay unity thì việc load hình ảnh lên màn hình khá là dễ dàng, nhưng đối với framework SDL thì khá là phức tạp. Trong phạm vi bài viết này tôi sẽ hướng dẫn các bạn load hình ảnh lên màn hình sử dụng framework SDL (Simple DirectMedia Layer).

    Giới thiệu

    Với những engine như cocos2dx, hay unity thì việc load hình ảnh lên màn hình khá là dễ dàng, nhưng đối với framework SDL thì khá là phức tạp. Trong phạm vi bài viết này tôi sẽ hướng dẫn các bạn load hình ảnh lên màn hình sử dụng framework SDL (Simple DirectMedia Layer).

    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ác đối tượng sử dụng trong bài viết

    SDL_Window: là struct giữ tất cả các thông tin của cửa sổ mà chúng ta tạo ra như size, postion, border, fullscreen.

    SDL_Renderer: là struct xử lý tất cả các công việc rendering lên cửa sổ.

    SDL_Surface: chứa một tập hợp các pixel (a collection of pixels) để có thể render lên cửa sổ sử dụng software rendering (CPU).

    SDL_Texture: chứa một tập hợp các pixel (a collection of pixels) để có thể render lên cửa sổ sử dụng hardware rendering (GPU).

    SDL_Rect: là struct đại diện cho một hình chữ nhật gồm có các thông tin là x, y, w, h.

    Tạo đối tượng SDL_Texuture

    Tôi tiếp tục sử dụng project ở bài viết Xử Lý Sự Kiện Trong SDL nhưng chỉ lại giữ lại main loopmain event. Và tiếp tục khai báo thêm một số biến sử dụng trong chương trình là renderer, tempSurface, texture, sourceRect, desRect.

    int main()
    {
    
    	SDL_Window* window = NULL;
    	SDL_Renderer* renderer = NULL;
    	SDL_Surface* tempSurface = NULL;
    	SDL_Texture* texture = NULL;
    	SDL_Event mainEvent;
        SDL_Rect sourceRect;
        SDL_Rect desRect;
    	bool isRunning = true;
    
    	//initializes  the subsystems
    	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    	{
    		printf("Unable to initialize SDL %s\n", SDL_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;
    	}
    	//main loop
    	while (isRunning)
    	{
    		//main event
    		while (SDL_PollEvent(&mainEvent))
    		{
    			switch (mainEvent.type)
    			{
    				//User - requested quit
    				case SDL_QUIT:
    				{
    					isRunning = false;
    					break;
    				}
                    default:
                    {
                        break;
                    }
                }
    		}
    	}
    
    	//Destroy a window.
    	SDL_DestroyWindow(window);
    
    	//cleans up all initialized subsystems
    	SDL_Quit();
    	return 0;
    }

    Tạo đối tượng renderer để có thể render lên cửa sổ bằng cách:

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

    Tiếp theo tạo tempSurface từ một file hình có đuôi mở rộng là .bmp và tạo texture từ tempSurface đó. Sau đó hủy tempSurface. Ở đây file hình ảnh của tôi có tên là "texture_demo.bmp" được đặt trong thư mục gốc của solution.

    tempSurface = SDL_LoadBMP("texture_demo.bmp");
    texture = SDL_CreateTextureFromSurface(renderer, tempSurface);
    SDL_FreeSurface(tempSurface);

    Lưu ý: Hàm SDL_LoadBMP() chỉ nhận được hình ảnh có đuôi mở rộng là .bmp.

    Sử dụng hàm SDL_QueryTexture() để lấy ra thông tin chiều rộng và chiều cao của texture.

    SDL_QueryTexture(texture, NULL, NULL, &sourceRect.w, &sourceRect.h);

    Ở trên tôi có tạo khai báo đối tượng SDL_Rect là sourceRect và desRect. Chức năng của chúng như sau:

    sourceRect: sử dụng để thông tin về chiều cao, chiều rộng của texture ta muốn vẽ. Ví dụ ta có một texture được load lên. Nhưng ta không muốn vẽ toàn bộ texture đó lên mà hình mà ta chỉ muốn vẽ một phần nào đó của texture này mà thôi, ta sẽ sử dụng đối tượng hình chữ nhật này để fix lại x, y, w, h.

    desRect: sử dụng để xác định tọa độ của texture mà ta muốn vẽ trên màn hình.

    Vẽ Texture lên màn hình

    Lấy thông tin về chiều cao và chiều rộng của texture sau khi texure được tạo:

    SDL_QueryTexture(texture, NULL, NULL, &sourceRect.w, &sourceRect.h);
    
    sourceRect.x = desRect.x = 0;
    sourceRect.y = desRect.y = 0;
    desRect.w = sourceRect.w;
    desRect.h = sourceRect.h;

    Set background màu đen cho cửa sổ sử dụng hàm:

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    

    Với tham số thứ nhất chính là đối tượng renderer, 3 tham số tiếp theo lần lượt là các giá trị màu r, g, b, a.

    Trong main loop tôi tiến hành vẽ texture lên cửa sổ

    //main loop
    while (isRunning)
    {
    	SDL_RenderClear(renderer);
    	//main event
    	while (SDL_PollEvent(&mainEvent))
    	{
    		switch (mainEvent.type)
    		{
    			//User - requested quit
    			case SDL_QUIT:
    			{
    				isRunning = false;
    				break;
    			}
    			default:
    			{
    				break;
    			}
    		}
    	}
    
    	SDL_RenderCopy(renderer, texture, &sourceRect, &desRect);
    	SDL_RenderPresent(renderer);
    }
    • Dòng 4: Xóa màn hình sau mỗi frame với màu của background được set với ở SDL_SetRenderDrawColor.
    • Dòng 23: Đây là mà chúng ta sử dụng để render texture với các tham số là:
      •  Tham số thứ nhất: đối tượng mà chúng ta sử dụng để render.
      • Tham số thứ hai: đối tượng texture mà ta muốn render.
      • Tham số thứ ba: một phần nào đó của texture mà ta muốn render. Nếu để NULL nó sẽ render toàn bộ texture.
      • Tham số thứ tư: hình chữ nhật xác đinh tọa độ mà texture muốn vẽ trên cửa sổ. Nếu chiều rộng và chiều cao lớn hơn hoặc nhỏ hơn texture muốn vẽ thì texture sẽ bị scale theo hình nhật này. Nếu để NULL texture sẽ được vẽ full màn hình.
    • Dòng 24: Cập nhập, vẽ lên cửa sổ.

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

    ss_1

    Bây giời, tôi thay đổi các thông số của sourceRect desSource để có thể vẽ được 1/4 hình ảnh ở vị trí x= 200, y = 200 trên màn hình:

    sourceRect.x = 0;
    sourceRect.y = 0;
    sourceRect.w = sourceRect.w / 2;
    sourceRect.h = sourceRect.h / 2;
    
    desRect.x = 200;
    desRect.y = 200;
    desRect.w = sourceRect.w;
    desRect.h = sourceRect.h;

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

     

    Source code toàn bộ chương trình

    #include <stdio.h>
    #include <SDL.h>
    
    #undef main
    int main()
    {
    
    	SDL_Window* window = NULL;
    	SDL_Renderer* renderer = NULL;
    	SDL_Surface* tempSurface = NULL;
    	SDL_Texture* texture = NULL;
    	SDL_Event mainEvent;
    	SDL_Rect sourceRect;
    	SDL_Rect desRect;
    	bool isRunning = true;
    
    	//initializes  the subsystems
    	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    	{
    		printf("Unable to initialize SDL %s\n", SDL_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;
    	}
    
    	//create a tempSurface
    	tempSurface = SDL_LoadBMP("texture_demo.bmp");
    	//create a texutre from surface
    	texture = SDL_CreateTextureFromSurface(renderer, tempSurface);
    	//free surface
    	SDL_FreeSurface(tempSurface);
    
    
    	SDL_QueryTexture(texture, NULL, NULL, &sourceRect.w, &sourceRect.h);
    
    	sourceRect.x = 0;
    	sourceRect.y = 0;
    	sourceRect.w = sourceRect.w / 2;
    	sourceRect.h = sourceRect.h / 2;
    
    	desRect.x = 200;
    	desRect.y = 200;
    	desRect.w = sourceRect.w;
    	desRect.h = sourceRect.h;
    
    	//set background color
    	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    
    	//main loop
    	while (isRunning)
    	{
    		// clear the window to black
    		SDL_RenderClear(renderer);
    		//main event
    		while (SDL_PollEvent(&mainEvent))
    		{
    			switch (mainEvent.type)
    			{
    				//User - requested quit
    				case SDL_QUIT:
    				{
    					isRunning = false;
    					break;
    				}
    				default:
    				{
    					break;
    				}
    			}
    		}
    
    		// copy a portion of the texture to the current rendering target.
    		SDL_RenderCopy(renderer, texture, &sourceRect, NULL);
    		//draw to the screen
    		SDL_RenderPresent(renderer);
    	}
    
    	//Destroy a window.
    	SDL_DestroyWindow(window);
    
    	//Destroy a renderer
    	SDL_DestroyRenderer(renderer);
    
    	//cleans up all initialized subsystems
    	SDL_Quit();
    	return 0;
    }
    

    Download demo

    Stdio_SDL_LoadTexure_VS2013.zip

    Thảo luận

    Đăng nhập

    Bài viết liên quan

    Play Audio Trong SDL

    Play Audio Trong SDL

    Âm thanh là một trong những thành phần không thể thiếu và nó có vai trò quan trọng trong game, làm cho game chúng ta sinh động và hấp dẫn hơn. Trong phạm vi bài viết này ...

    Nguyễn Nghĩa

    15/10/2015

    Draw Text Trong SDL

    Draw Text Trong SDL

    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ễ ...

    Nguyễn Nghĩa

    17/10/2015

    Load Sprite Trong DirectX 9

    Load Sprite Trong DirectX 9

    Thao tác với Sprite, Sprite animation là một trong những kỹ thuật cần thiết trong lập trình game. Bài viết sẽ giới thiệu tổng quan về Sprite, Sprite animation, tổng quan ...

    Huỳnh Minh Tân

    10/10/2017

    Xử Lý Sự Kiện Trong SDL

    Xử Lý Sự Kiện Trong SDL

    Xử lý sự kiện trong game vô cùng quan trọng, đòi hỏi chúng ta phải thao tác với bàn phím, chuột, hay touch đối với những dòng có màn hình cảm ứng. Framework SDL có hỗ trợ ...

    Nguyễn Nghĩa

    13/10/2015

    Áp Dụng Kĩ Thuật OOP Trong Quá Trình Xây Dựng Framework Dựa Trên Thư Viện SDL

    Áp Dụng Kĩ Thuật OOP Trong Quá Trình Xây Dựng Framework Dựa Trên Thư Viện SDL

    Trong quá trình xây dựng Engine của bản thân mình, thông qua bài viết Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer) của Nghĩa Nguyễn ...

    Hoàng Thái

    09/09/2015

    Sprite Animation Trong DirectX 9

    Sprite Animation Trong DirectX 9

    Thao tác Sprite animation là một trong những kỹ thuật cần thiết trong lập trình game. Bài viết sẽ hướng dẫn tạo tập tin lưu tọa độ các tile từ một sprite sheet có sẵn và ...

    Huỳnh Minh Tân

    02/11/2017

    Hiện Thực Frame Per Second (FPS) Trong SDL

    Hiện Thực Frame Per Second (FPS) Trong SDL

    Frame Per Second (FPS) là một khái niệm khá phổ biến trong game nó có ý nghĩa là số frame trên 1 giây mà máy tính có thể render, FPS càng cao thì thể hiện độ mượt của ...

    Nguyễn Nghĩa

    17/10/2015

    Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer)

    Khởi Tạo Môi Trường Lập Trình Game Sử Dụng Thư Viện SDL (Simple DirectMedia Layer)

    Trong quá trình xây dựng engine game, tôi cần một số thư viện cung cấp những hàm API để thao tác với hệ thống cấp thấp bên dưới như âm thanh, bàn phím, chuột và các hệ ...

    Nguyễn Nghĩa

    08/10/2015

    Sprite Sheet Trong Cocos2dx 3.x.x

    Sprite Sheet Trong Cocos2dx 3.x.x

    Bài viết nằm trong loạt bài viết chường trình Tự Học Cocos2d-x 3.x.x. Sprite Sheet là một trong những phương pháp tiêu chuẩn trong ngành công nghiệp games nhằm sẽ quản ...

    Trương Xuân Đạt

    23/01/2015

    Khởi Tạo Đối Tượng Trong Runtime

    Khởi Tạo Đối Tượng Trong Runtime

    Trong một vài trường hợp, việc khởi tạo đối tượng mà không khai báo trước khi chạy chương trình là điều cần thiết. Một số đối tượng như item, bullet hay các đối tượng ...

    Rye Nguyen

    08/08/2015

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    [email protected]

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020