Main.c
---
#include "Framework/App.h"
int main(void)
{
if (false == App_Init())
{
return 1;
}
return App_Run();
}
App.c
---
#include "App.h"
#include "common.h"
#include "Renderer.h"
#include "timer.h"
bool App_Init()
{
if (false == Renderer_Init())
{
return false;
}
return true;
}
void processInput()
{
}
float count = 0;
void undate()
{
// 비례식
// 프레임 : 시간
// 1 : deltaTime = fps : 1
// 1 = deltaTime * fps
// fps = 1 /deltaTime
count += DELTA_TIME;
if (count > 0.5 && count < 1)
{
char str[128] = "";
sprintf_s(str, sizeof(str), "현재 FPS : %d", (int32)(1 / Timer_GetDeltaTime()));
Renderer_DrawText(str, strlen(str));
}
else if (count > 1)
count = 0;
}
void render()
{
Renderer_Flip();
}
void cleanup()
{
Renderer_Cleanup();
}
int32 App_Run()
{
atexit(cleanup);
Timer_Init(60);
const int32 FIXED_FPS = 60;
const float FIXED_TIME = 1.0f / FIXED_FPS;
// game loop : 게임을 동작시키는 루프. 프레임(Frame)이라고 한다.
while (true)
{
if (Timer_Update()) //deltatime : 프레임 간의 시간. 이전 프레임으로부터 현재 프레임을 시작할 때까지 걸린 시간
{
processInput(); // 입력 처리
undate(); // 게임 업데이트
render(); //게임 출력
}
}
return 0;
}
Renderer.c
#include "App.h"
#include "common.h"
#include "Renderer.h"
#include "timer.h"
bool App_Init()
{
if (false == Renderer_Init())
{
return false;
}
return true;
}
void processInput()
{
}
float count = 0;
void undate()
{
// 비례식
// 프레임 : 시간
// 1 : deltaTime = fps : 1
// 1 = deltaTime * fps
// fps = 1 /deltaTime
count += DELTA_TIME;
if (count > 0.5 && count < 1)
{
char str[128] = "";
sprintf_s(str, sizeof(str), "현재 FPS : %d", (int32)(1 / Timer_GetDeltaTime()));
Renderer_DrawText(str, strlen(str));
}
else if (count > 1)
count = 0;
}
void render()
{
Renderer_Flip();
}
void cleanup()
{
Renderer_Cleanup();
}
int32 App_Run()
{
atexit(cleanup);
Timer_Init(60);
const int32 FIXED_FPS = 60;
const float FIXED_TIME = 1.0f / FIXED_FPS;
// game loop : 게임을 동작시키는 루프. 프레임(Frame)이라고 한다.
while (true)
{
if (Timer_Update()) //deltatime : 프레임 간의 시간. 이전 프레임으로부터 현재 프레임을 시작할 때까지 걸린 시간
{
processInput(); // 입력 처리
undate(); // 게임 업데이트
render(); //게임 출력
}
}
return 0;
}
Timer.c
#include "common.h"
#include "Timer.h"
clock_t s_prevTick;
float s_deltaTime;
float s_fixedTime;
void Timer_Init(int32 fps)
{
// 고정 시간을 계산한다.
s_fixedTime = 1.0 / fps;
// 시점을 하나 찍어준다.
s_prevTick = clock();
}
void Timer_Update(void)
{
// 1. 현재 시점을 구한다.,
clock_t currentTick = clock();
// 2. 현재 시점과 이전 시점의 차이를 통해 흐른 시간을 구한다.
float deltatime = (float)(currentTick - s_prevTick) / CLOCKS_PER_SEC;
// 3. 이전 프레임으로부터 시간이 얼마 지나지 않았다면
if (deltatime < s_fixedTime)
{
return false;
}
// 4. 변수를 업데이트한다.
s_deltaTime = deltatime;
s_prevTick = currentTick;
return true;
}
float Timer_GetDeltaTime(void)
{
return s_deltaTime;
}
common.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <Windows.h>
#include "Type.h"
App.h
#pragma once
#include "Type.h"
/// <summary>
/// 애플리케이션 초기화한다.
/// </summary>
/// <returns>초기화에 성공했으면 true, 아니면 false</returns>
bool App_Init();
/// <summary>
/// 애플리케이션을 실행한다.
/// </summary>
/// <returns>앱이 정상적으로 종료됐다면 0, 아니라면 0이 아닌값</returns>
int32 App_Run();
Timer.h
#pragma once
/// <summary>
/// 타이머를 초기화한다.
/// </summary>
/// <param name="fps">고정할 FPS</param>
void Timer_Init(int32 fps);
/// <summary>
/// 타이머를 업데이트한다.
/// </summary>
/// <return>업데이트 성공했다면 true, 아니라면 flase</return>
bool Timer_Update(void);
/// <summary>
/// 델타타임을 구한다.
/// </summary>
/// <return>DeltaTime : 프레임 간의 시간. 이전 프레임으로부터 현재 프레임을 시작할 때까지 걸린 시간</return>
float Timer_GetDeltaTime(void);
#define DELTA_TIME Timer_GetDeltaTime();
Renderer.h
#pragma once
#include "Type.h"
/// <summary>
/// 랜더러를 초기화한다.
/// </summary>
/// <returns>초기화에 성공했으면 true, 아니면 false</returns>
bool Renderer_Init(void);
/// <summary>
/// 랜더러를 정리한다.
/// </summary>
void Renderer_Cleanup(void);
/// <summary>
/// 화면을 바꾼다.
/// </summary>
void Renderer_Flip(void);
void Renderer_DrawText(const char* text, int32 numberOfChar);
Type.h
#pragma once
#include <stdbool.h>
#include <stdint.h>
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
렌더링 파이프라인(Rendering Pipeline)
- 3차원 공간의 물체가 있을 때, 이를 바라보는 특정 시점을 기준으로 2차원 이미지로 출력하는데 필요한 일련의 단계들이다.
- 렌더링 : 컴퓨터 프로그램을 사용하여 모델 또는 이들을 모아놓은 scene file 로 부터 영상을 만들어 내는 과정
- 파이프라인의 파이프 : 렌더링을 하기 위해서 수행해야 하는 단계
- GPU : 그래픽, 3D데이터 처리를 위한 장치
- 셰이더(Shader)
- 3D공간에서 최종적으로 화면에 출력하는 픽셀의 색을 정해주는 함수
- 화면에 출력할 픽셀의 위치와 색상을 계산하는 함수
- 고수준 게임 에디터
- 유니티 언리얼 엔진
- 저수준 그래픽 API 활용
- 저수준 그래픽 API (Application Program Interface)
렌더링 파이프라인 도식화