STDIO
Tìm kiếm gần đây
    Nội dung
    0
    0
    Chia sẻ
    Nội dung
    0
    0
    Chia sẻ

    Load Texture trong SDL

    Cách load hình ảnh lên màn hình sử dụng framework SDL (Simple DirectMedia Layer).
    15/10/2015 02/11/2020 5 phút đọc
    Load Texture trong SDL

    Các đối tượng sử dụng trong bài viết

    • SDL_Window: struct giữ tất cả các thông tin của cửa sổ được tạo ra, chẳng hạn như size, postion, border, fullscreen.
    • SDL_Renderer: struct xử lý tất cả các công việc rendering lên cửa sổ.
    • SDL_Surface: chứa 1 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 1 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: struct đại diện cho 1 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

    Sử dụng project ở bài viết Xử Lý Sự Kiện trong SDL nhưng giữ lại main loop và main event, tiếp tục khai báo thêm 1 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ừ 1 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ó 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);

    * 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);

    Đoạn code trên có khai báo đối tượng SDL_Rect với 2 biến 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 muốn vẽ. Ví dụ có 1 texture được load lên, để vẽ 1 phần nào đó của texture thay vì vẽ toàn bộ texture đó lên mà hình, 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 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, 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);
    }
    • SDL_RenderClear(): xóa màn hình sau mỗi frame với màu của background được set.
    • SDL_RenderCopy(): hàm sử dụng để render texture với các tham số:
      • renderer: đối tượng được sử dụng để render.
      • texture: đối tượng texture muốn render.
      • sourceRect: 1 phần nào đó của texture muốn render. Nếu để NULL nó sẽ render toàn bộ texture.
      • desRect: 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 chữ nhật này. Nếu để NULL texture sẽ được vẽ full màn hình.
    • SDL_RenderPresent(): 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ờ, thay đổi các thông số của sourceRectdesSource để 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;

    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

    0 Bình luận
    Lập Trình Game

    Lập Trình Game

    Kiến thức, kỹ thuật, kinh nghiệm lập trình game.

    Khi bạn nhấn vào sản phẩm do chúng tôi đề xuất và mua hàng, chúng tôi sẽ nhận được hoa hồng. Điều này hỗ trợ chúng tôi có thêm kinh phí tạo nhiều nội dung hữu ích. Tìm hiểu thêm.
    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
      developer@stdio.vn
    • 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 - 2021