일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- JWT
- Jinja2
- Enhanced Input System
- 언리얼프로그래머
- 프린세스메이커
- Express
- 스마일게이트
- 디자드
- node
- 레베카
- 데이터베이스
- 프메
- 카렌
- 정글사관학교
- VUE
- 미니프로젝트
- 마인크래프트뮤지컬
- EnhancedInput
- R
- Ajax
- 파이썬서버
- 언리얼뮤지컬
- Unseen
- 언리얼
- 으
- 게임개발
- 스터디
- Bootstrap4
- flask
- 알고풀자
- Today
- Total
Today, I will
[OpenGL] Learn Open GL 기본 코드 hello_window_clear 본문
*컴퓨터 그래픽스 강의와 Learn Open GL Code를 참고하여 작성한 포스팅입니다.
LearnOpenGL - Creating a window
Creating a window Getting-started/Creating-a-window The first thing we need to do before we start creating stunning graphics is to create an OpenGL context and an application window to draw in. However, those operations are specific per operating system an
learnopengl.com
hello_window_clear.cpp
해당 코드는 별다르게 렌더링하는 것이 없으나 LearnOpenGL 기본 코드 구조가 잘 나타나 있다.
여타 LearnOpenGL 코드 베이스를 공유하고 있으므로 정리 겸 포스팅을 해두기로 하였다.
#include <glad/glad.h>
#include <GLFW/glfw3.h>
GLFW와 GLAD 헤더(os 종속적인 작업을 처리해주는 라이브러리)
(1) GLFW : windowing과 Message handing을 처리
- 유저인터페이스에서 발생하는 이벤트 메시지들을 핸들링해준다.
(2) GLAD : 하우스키핑 jobs들을 대신 처리해준다.
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
GLFW init
기계적인 코드 부분으로, 변경할 일이 거의 없다.
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Open GL core 3.3을 쓰겠다
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Open GL core 3.3을 쓰겠다
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
// 윈도우를 만든다. SCR_WIDTH(폭), SCR_HEIGHT(높이)는 위에서 const로 선언 정의
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// 잘 만들어졌는지 확인한다.
glfwMakeContextCurrent(window); // 현재 윈도우에 open gl 컨텍스트가 만들어지도록 선언
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// 렌더링을 하려면, 프레임버퍼(픽셀들이 저장되는 곳)가 만들어져야 한다.
// 윈도우가 만들어지면서 프레임버퍼도 같이 만들어지게 된다. 일반적인 프레임버퍼 사이즈는 윈도우(녹색부분)에 해당하는 부분 만큼 만들어지게 된다.
// 렌더링을 할 스크린(뷰포트)을 같이 셋업하기 위해 callback을 쓴다. 윈도우 시스템은 기본적으로 메시지 콜백 매커니즘을 통해 메시지를 핸들링하게 된다.(추후 키보드 마우스 콜백 등 다양한 콜백을 추가하여 쓸 수 있다)
해당 코드에서는 프레임버퍼가 처음 만들어졌다는 이벤트가 발생하게 되고, 프레임버퍼 사이즈에 맞는 뷰포트를 만드는 조치를 framebuffer_size_callback 펑션이 수행한다. 이러한 콜백 펑션은 사용자가 정의해야 한다.
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height); // 오픈지엘 펑션이다.
}
프레임버퍼
2D array of pixels. 래스터라이제이션된 픽셀이 저장되는 곳으로 GPU 내에 있다.
엄밀히 따지면 RGBA와 Z-buffer(=depth buffer)이 저장되며 Double buffering 또한 일반적인 GPU 상에 전부 다 들어있다.
- A : 투명도
- Z-buffer : 각 픽셀마다 distance를 저장(픽셀마다 depth value가 있음)
- Double buffering : 2개의 똑같은 full frame buffers을 front와 back으로 나누어 back에다 애니메이션이 다 그려지면 front에 보여주는 방식을 꾀하여 flicker-free real time animation을 구현하는데 쓰인다.
뷰포트
glViewport(0, 0, width, height);
width, height는 프레임 버퍼의 크기,
프레임 버퍼와 똑같은 뷰포트를 만든다
렌더링 마지막 결과는 뷰포트(프로젝션 범위)에 디스플레이되는 것이다. 이 뷰포트의 크기가 얼마인지는 프레임버퍼 콜백에서 정해주어야 한다. 뷰포트는 스크린 사이즈에 종속적이다.
// glad: load all OpenGL function pointers
// GLAD init, 역시나 기계적인 코드
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
render loop
제일 중요
윈도우가 닫히기 전까지 끊임없이 돌면서 렌더링을 한다.
while (!glfwWindowShouldClose(window))
{
// input
processInput(window); // (1) 유저인터페이스 처리
// render (2) 렌더링파트이지만 이 코드에서는 사실상 렌더링하는 것이 없다.
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // normalize되어 있다 (0~1 사이의 rgb)
glClear(GL_COLOR_BUFFER_BIT); //<1> 프레임버퍼에서 컬러에 해당하는 비트를 다 클리어,
// rgb가 0.2f, 0.3f, 0.3f, 1.0f인 컬러로 프레임버퍼 컬러비트를 깨끗하게 지운다(결과 : 청록색)
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) 위에서 언급한 더블버퍼링
glfwSwapBuffers(window);
glfwPollEvents(); // 그 다음 이벤트가 무엇이 있는지 확인차 기다림
}
// glfw: terminate, clearing all previously allocated GLFW resources.
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
void processInput(GLFWwindow *window)
{
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
'Computer Science > 그래픽스' 카테고리의 다른 글
[그래픽스] HDR(High Dynamic Range), HDRI (0) | 2024.01.29 |
---|---|
[그래픽스] ray tracing intersection with triangle (ray 방정식과 삼각형의 교점 찾기) (1) | 2023.12.15 |
[그래픽스] 그래픽스 파이프라인 개념과 GPU에서의 쉐이더를 통한 가속화 (0) | 2023.11.17 |
[그래픽스] 선형대수-행렬, 그래픽스 프로그래밍에서 자주 쓰는 연산 (1) | 2023.10.20 |
[OpenGL] opengl graphics pipeline의 이해와 hello_triangle 속 VAO와 VBO의 쓰임 (0) | 2023.10.11 |