โ ์๋์ฐ ์์ฑํ๊ธฐ
1. GLFW ์ด๊ธฐํ ๋ฐ ์ค์
// GLFW ์ด๊ธฐํ
glfwInit();
// GLFW์๊ฒ ์ฌ์ฉํ ๋ฒ์ (3.3)์ ์๋ฆผ
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// ๋ช
์์ ์ผ๋ก core-profile์ ์ฌ์ฉํ๋ค๊ณ ์๋ฆผ
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
* ์๋์ฐ ์ต์
, ๊ฐ ๋ชฉ๋ก
https://www.glfw.org/docs/latest/window.html#window_hints
2. ์๋์ฐ ๊ฐ์ฒด ์์ฑ
// ์๋์ฐ์ ๋๋น, ๋์ด, ์๋์ฐ ์ด๋ฆ ์ง์
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
// ์๋์ฐ ์์ฑ ์คํจ ์ ์ฌ์ฉ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ฑฐ
if (window == NULL)
{
glfwTerminate();
return -1;
}
// GLFW์๊ฒ window์ ์ปจํ
์คํธ๋ฅผ ํ์ฌ ์ฐ๋ ๋์ ์ฃผ ์ปจํ
์คํธ๋ก ์ง์ ํ๊ฒ ๋ค๊ณ ์๋ฆผ
glfwMakeContextCurrent(window);
3. GLAD ์ด๊ธฐํ
// GLAD ์ด๊ธฐํ ๋ฐ ์ค์
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
return -1;
}
4. ViewPort ์ค์
// ์๋์ฐ ์ผ์ชฝ ์๋ ๋ชจ์๋ฆฌ์ ์์น, ์๋์ฐ ๋๋น์ ๋์ด ์ง์ (ํฝ์
)
glViewport(0, 0, 800, 600);
// ์ฝ๋ฐฑ ์ ์ธ
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
// ์ฝ๋ฐฑ ๋ฑ๋ก
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
* ์ฌ์ฉ์๊ฐ ์ฐฝ์ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ๋ ๋ทฐํฌํธ๋ ์กฐ์ ํด์ผ ํ๋ค. (์ฝ๋ฐฑ ๋ฑ๋ก)
5. Engine ์ค๋น
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window); // ์ด์ ํ๋ ์์ ๋ฒํผ์ ํ์ฌ ํ๋ ์์ ๋ฒํผ๋ฅผ ์ค์ (double buffer)
glfwPollEvents(); // ํ์ฌ ํ๋ ์์ ์
์ถ๋ ฅ ์ด๋ฒคํธ ์ฒ๋ฆฌ
}
* ํ์ฌ ์์ฉ ํ๋ก๊ทธ๋จ์ ํ๋์ ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ฆฌ๊ณ ๋ฐ๋ก ์ข
๋ฃ๋๋ค → ์ค์ง ๋ช
๋ น์ ๋ฐ๊ธฐ ์ ๊น์ง ๊ณ์ ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ฆฌ๊ณ ์
๋ ฅ์ ๋ฐ๋๋ก ์ฒ๋ฆฌ
(Render Loop๋ผ๊ณ ํจ)
* Double Buffer
์์ฉ ํ๋ก๊ทธ๋จ์ด single buffer๋ก ์ด๋ฏธ์ง๋ฅผ ๊ทธ๋ฆฌ๋ฉด ํฝ์
์ ๊ต์ฒดํ๋ ๊ณผ์ ์์ ์ด๋ฏธ์ง๊ฐ ๊น๋นก์ด๋ ํ์์ด ๋ฐ์ํ ์ ์๋ค.
→ ์ด๋ฅผ ์๋ฐฉํ๊ธฐ ์ํด double buffer๋ฅผ ์ด์ฉํ์ฌ ๋ ๋๋ง ์๋ฃ ํ ๋ฒํผ๋ฅผ ๊ต์ฒดํ๋ ์์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ํ์ํ๋ค.
โ ํค๋ณด๋ ์ ๋ ฅ ๋ฐ๊ธฐ
// ์ฌ์ฉ์๊ฐ esc๋ฅผ ๋๋ฅธ ๊ฒฝ์ฐ WindowShouldClose ์์ฑ์ true๋ก ์ค์ ํ์ฌ while๋ฌธ(๋ ๋๋ง ๋ฃจํ)์ ํ์ถ
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
* ํค ํ ํฐ ๋ชฉ๋ก
https://www.glfw.org/docs/3.3/group__keys.html
* ์
๋ ฅ ๋ ํผ๋ฐ์ค ๋ชฉ๋ก
https://www.glfw.org/docs/3.3/group__input.html#ga2485743d0b59df3791c45951c4195265
โ Clear
// ํ๋ ์ ๋ง๋ค ํ๋ฉด์ ์ง์ ์ด์ ํ๋ ์์ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง๋ค์ด ๋จ์์์ง ์๊ฒ ํ๋ค → ์ง์ ํ ์ปฌ๋ฌ๋ก ์น ํจ
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
(glClearColor ํจ์๋ก '์ํ๋ฅผ ์ค์ ' ํ๊ณ , glClear ํจ์๋ก '์ํ๋ฅผ ์ฌ์ฉ' ํ๋ ๋๋)
* ํ๋ผ๋ฏธํฐ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๋นํธ๋ COLOR, DEPTH, STENCIL ๋ฒํผ ๋นํธ๊ฐ ์๋ค.
6. ์ ๋ฆฌ
// ํ ๋นํ ๋ชจ๋ ์์์ ์ ๋ฆฌํ๋ค
glfwTerminate();
โ ์์ค ์ฝ๋
#include <glad/glad.h>
#include <GLFW/glfw3.h>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
int main(void)
{
// GLFW ์ด๊ธฐํ
glfwInit();
// ์๋์ฐ ์ค์
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// ์๋์ฐ ์์ฑ
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
// GLAD ์ด๊ธฐํ
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
return -1;
}
// ๋ทฐํฌํธ ์ค์
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
while (!glfwWindowShouldClose(window))
{
// esc ํค ์
๋ ฅ ๋ฐ์ ์ข
๋ฃ
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
// ํด๋ฆฌ์ด
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window); // ์ปฌ๋ฌ ๋ฒํผ๋ฅผ ์ค์ (๋๋ธ ๋ฒํผ)
glfwPollEvents(); // ์
์ถ๋ ฅ ์ด๋ฒคํธ ์ฒ๋ฆฌ
}
glfwTerminate(); // ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
'๐จ Graphics > ๐ต OpenGL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [OpenGL] Shader (2) | 2024.07.24 |
|---|---|
| [OpenGL] EBO (0) | 2024.07.18 |
| [OpenGL] ์ผ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ (0) | 2024.07.17 |
| [OpenGL] ๊ฐ๋ฐ ํ๊ฒฝ ์ธํ (0) | 2024.07.11 |
| [OpenGL] ๊ฐ์ (0) | 2024.07.10 |