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

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

    Hướng dẫn cách hiện thực giới hạn FPS - Limit FPS với thư viện SDL.
    17/10/2015 27/09/2020 4 phút đọc
    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ó tượng trưng cho số frame trên 1 giây mà máy tính có thể render, FPS càng cao thể hiện độ mượt của game càng cao.

    Ý tưởng

    Với đoạn mã như dưới đây:

    #include <stdio.h>
    #include <SDL.h>
    
    #undef main
    int main()
    {
    	SDL_Window* window = NULL;
    	SDL_Renderer* renderer = NULL;
    	bool isRunning = true;
    	SDL_Event mainEvent;
    	int x = 0;
    
    	//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;
    	}
    
    	//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);
    		//draw in here
    		SDL_Log("Frame :%d", x++);
    		//draw to 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;
    }

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

    ss_1

    Limit FPS - giới hạn frame rate

    Giả sử ở đây là mỗi lần biến x được in ra thì xem như một frame được vẽ lên màn hình, frame được vẽ ra quá nhanh, không thể biết được là bao nhiêu frame/second.

    Ý tưởng là xác định và kiểm soát số frame được render trên 1 giây bằng cách:

    Gọi:

    • FPS là số frame mà cần render trên 1 giây. Gán: const int FPS = 60;
    • DELAY_TIME là thời gian tính trên lý thuyết để máy tính tính toán và render xong 1 frame. Như vậy mỗi frame sẽ cần khoảng 16 miliseconds để có thể tính toán và render lên màn hình. Gán: const int DELAY_TIME = 1000 / FPS; ( 1000 milisecond/FPS)
    • frameStart là thời gian bắt đầu của 1 frame;
    • frameTime là thời gian thực sự để máy tính tính toán và render xong 1 frame kể từ thời điểm bắt đầu.

    Kiểm tra nếu frameTime < DELAY_TIME thì delay một khoảng thời gian bằng đúng DELAY_TIME - frameTime, nghĩa là nếu máy tính tính toán và render xong 1 frame nhanh hơn số thời gian lý thuyết cần cho 1 frame nên phải delay khoảng thời gian còn lại.

    Hiện thực

    #include <stdio.h>
    #include <SDL.h>
    
    #undef main
    int main()
    {
    	SDL_Window* window = NULL;
    	SDL_Renderer* renderer = NULL;
    	bool isRunning = true;
    	SDL_Event mainEvent;
    	int x = 0;
    
    	const int FPS = 60;
    	const int DELAY_TIME = 1000 / FPS;
    
    	Uint32 frameStart;
    	Uint32 frameTime;
    	//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;
    	}
    
    	//set background color
    	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    	//main loop
    	while (isRunning)
    	{
    		frameStart = SDL_GetTicks();
    		//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);
    		//draw in here
    		SDL_Log("Frame :%d", x++);
    		//draw to screen
    		SDL_RenderPresent(renderer);
    
    		frameTime = SDL_GetTicks() - frameStart;
    		if (frameTime < DELAY_TIME)
    		{
    			SDL_Delay(DELAY_TIME - frameTime);
    		}
    	}
    	//Destroy a window.
    	SDL_DestroyWindow(window);
    	//Destroy a renderer
    	SDL_DestroyRenderer(renderer);
    	//cleans up all initialized subsystems
    	SDL_Quit();
    	return 0;
    }

    Hàm SDL_GetTicks() có chức năng lấy về tổng số miliseconds từ khi SDL được khởi tạo.

    Với mỗi vòng lặp, lấy thời gian bắt đầu của 1 frame, sau khi tính toán và render xong, lấy tiếp thời gian mà máy tính đã tính toán và render xong 1 frame, kiểm tra điều kiện, nếu thỏa mãn sẽ delay số miliseconds còn lại (DELAY_TIME - frameTime) sau đó mới bắt đầu sang frame tiếp theo.

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

    ss_2

    Download demo

    Stdio_SDL_FPS_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