Scop 구현기 5편: 행렬과 사용 점
·
Dev/Grapics
이전 글에서는 Model 클래스에서 OBJ 파일을 파싱하고 정점 데이터를 처리하는 흐름을 살펴보았습니다.이번 글에서는 그 정점들이 실제로 화면에 어떻게 그려지는지를 결정짓는 핵심 요소, 바로 "행렬(Matrix)"에 대해 깊이 있게 분석합니다.3D 그래픽스에서 행렬은 단순한 계산 도구가 아니라, '시점', '위치', '존재'를 결정하는 철학적 도구입니다.1. 왜 행렬이 필요한가?3D 그래픽스에서 모델을 불러온다고 해서 곧바로 화면에 보이는 건 아닙니다.그 이유는 모델의 정점(Vertex)들이 여전히 '자기 내부(Local Space)'에 존재하기 때문입니다. 예를 들어, 정점이 (0, 0, 0)이라고 하면, 이는 오브젝트 기준의 원점을 의미하지 화면 기준의 원점은 아닙니다.우리는 화면(스크린)이라는 2차..
Scop 구현기 4편: Model 클래스
·
Dev/Grapics
전 편에서 Shader코드들을 분리해 클래스로 따로 만들었다이제는 기본. obj 파일을 파싱 해서 VAO와 VBO 그리고 정점들에 대한 데이터 들을 클래스 단위로 분리해 보자! Scop에서 가장 중요한 클래스가 아닐까 싶다1. 왜 Model 클래스를 도입했나?삼각형 그리기를 생각해 본다면 VAO, VBO, 위치 데이터, 셰이더 정보 등이 전부 흩어져 있다 이걸 하나로 묶지 않으면각 객체마다 VAO/VBO를 일일이 관리해야 하고draw 호출마다 셰이더 바인딩도 반복하고좌표, 색상, 메시 정보를 통합적으로 다루기 어렵다그래서 이 모든 "하나의 그릴 대상"을 감싸는 클래스를 만들게 된 것이다.2. Model 클래스는 어떤 책임을 가져야 할까?처음에는 단순히 "정점 데이터를 갖는 그릇" 정도로만 생각했다하지만 ..
Scop 구현기 3편: 셰이더 클래스를 만들기로 했다
·
Dev/Grapics
OpenGL 셰이더를 매번 glCreateShader → glCompileShader → glLinkProgram 반복하는 게너무 지저분하고 비효율적이라는 생각이 들었다.심지어 하나만 있을 땐 모르겠는데, 앞으로 이게 10개, 20개 넘어가면… 말 다했지 뭐.그래서 아예 셰이더 클래스를 하나 짜기로 했다.헤더부터 깔끔하게 작성했다.class Shader {public: Shader(const char* vsPath, const char* fsPath); ~Shader(); void Use(); GLuint GetId(); void SetBool(const std::string& name, bool value) const; void SetInt(const std::string& name, int value..
Scop 구현기 2편: VAO와 VBO의 세계
·
Dev/Grapics
윈도우를 띄우는 것까지 했으니 이제 삼각형을 그려보겠습니다. 삼각형 그리기 전체 코드#include #include #include #include const char* vertexShaderSource = R"(#version 330 corelayout (location = 0) in vec3 aPos;void main() { gl_Position = vec4(aPos, 1.0);})";const char* fragmentShaderSource = R"(#version 330 coreout vec4 FragColor;void main() { FragColor = vec4(1.0, 0.5, 0.2, 1.0); // 주황색})";void processInput(GLFWwindow* window){ if (..
Scop 구현기 1편: 윈도우 하나 띄우는 게 뭐라고 (Object Viewer)
·
Dev/Grapics
앞선 지식들을 구현하며 공부하느라 많이 정리를 하지 못했습니다.구현했던 순서대로 작성을 해보겠습니다! 윈도우를 만들기 위한 전체 코드#include #include #include #include int main(void){ if (!glfwInit()) { std::cerr 1. OpenGL 프로젝트의 시작은 항상 창 만들기부터!OpenGL은 "그래픽"만 담당합니다. 운영체제 창은 만들어주지 않죠.그래서 우리는 GLFW 같은 라이브러리를 써야 해요. GLFW는 "운영체제에 독립적인 윈도우 생성 및 입력 처리"를 담당합니다.#include 헤더를 포함한 뒤 glfw 함수를 사용하기 위해 초기화해야 합니다.if (!glfwInit()) { std::cerr  glfwInit() 은 GLFW를 사용하기 위..
Rasterization vs Ray Tracing
·
Dev/Grapics
렌더링 기술의 두 갈래, 무엇이 다르고 왜 중요한가? 게임 그래픽을 담당하는 개발자 A는 GPU 성능을 쥐어짜며 실시간 렌더링을 구현하고 있었습니다.그런데 어느 날, 팀의 아티스트가 무심코 묻습니다."레이 트레이싱 쓰면 더 예쁘지 않아요? 왜 안 써요?" 개발자 A는 한숨을 쉬며 이렇게 답합니다."아름다움은 계산량과 반비례하거든요...." 그래서 오늘의 질문은 이것입니다. 왜 어떤 렌더링은 Rasterization을 쓰고, 어떤 렌더링은 Ray Tracing을 쓸까?둘은 어떻게 다르고, 각각 어떤 장단점이 있을까? 이 글에서는 두 기술의 핵심 원리, 차이점, 그리고 실제 적용 사례까지 알아보겠습니다.1. Rasterization - 화면에 삼각형을 빠르게 찍는 기술Rasterization은 3D 공간의 ..
셰이더는 그낭 함수일까?
·
Dev/Grapics
GPU 프로그래밍의 착각과 진실1. 셰이더는 정말 함수일까?void main(){ gl_Position = ...;} 처음 GLSL 셰이더 코드를 보면 진짜 함수처럼 생겼다.C 언어와 똑같은 void main()에, 변수 선언, 수식, return 없이도 끝나는 심플한 구조까지. 그래서 흔히 이렇게 착각하곤 한다."아하, 셰이더도 함수니까 그냥 내가 부르면 되겠네?" 그런데 막상 실행해 보면 이상하다.main()을 딱 한 번 쓴 것 같은데, 화면 전체에 셰이더가 작동한다.어라? 내가 호출한 적 없는데? 그럼 셰이더는 대체 뭐지?그냥 함수처럼 보이는데.... 진짜 함수는 아닌 걸까?2. 셰이더란 무엇인가?셰이더는 GPU에서 실행되는 작은 프로그램이다.이 프로그램은 정점(Vertex), 픽셀(Fragm..
OpenGL의 좌표계, 진짜로 이해하기
·
Dev/Grapics
"왜 0, 0, 0에 두었는데 화면에 안 보일까? 1.  좌표계가 헷갈리는 이유OpenGL에서 처음 물체를 렌더링 할 때 이런 경험이 있다면 당신만 그런 게 아니다분명히 (0, 0, 0)에 모델을 뒀는데 화면에 아무것도 안 보인다.카메라는 설정했는데 방향이 어디를 보는지 감이 없다.gl_Position 계산했는데 화면이 시커멓다.이런 혼란의 원인은 대부분 좌표계와 변환에 대한 이해 부족이다.OpenGL에서의 렌더링은 단순한 그리기가 아니라,"모델의 좌표를 변환해 최종 스크린까지 도달시키는 여정"이다.2. 좌표계란 무엇인가?좌표계(Coordinate System)는 공간의 기준을 정의하는 약속이다.어디를 기준으로 (0, 0, 0)인지, 각 축이 어느 방향을 향하는지를 정의한다. OpenGL은 총 6단계의 ..
정점(Vertex)이란 무엇인가? - 그래픽 세계의 가장 작은 시작점
·
Dev/Grapics
1. 정점이라는 단어, 너무 자주 보인다컴퓨터 그래픽스를 막 시작하면 다음과 같은 단어들을 자주 보게 된다Vertex BufferVertex Shadergl_Positionlayout (location = x) 이 단어들은 모두 정점(Vertex)이라는 개념과 밀접하게 연결되어 있다.하지만 처음엔 너무 당연하다는 듯 쓰이기 때문에 "그래서... 정점이라는 게 도대체 뭐야?"라는 질문이 생기기 마련이다.2. 정점은 '점'이 아니다단어 뜻 그대로만 보면, 정점(Vertex)은 공간 위의 점 하나로 생각할 수 있다.하지만 그래픽에서의 정점은 단순한 위치 정보만 담고 있는 것이 아니다.정확히 말하자면, 정점은 '위치 + 속성 정보들'의 묶음이다. 예를 들어, 게임 캐릭터의 얼굴 한 지점은 단순히 (x,y,z) ..
렌더링 파이프라인: 그래픽이 만들어지는 과정
·
Dev/Grapics
1. glDrawElements() 또는 glDrawArrays() 줄 뒤에 무슨 일이?우리가 흔히 쓰는 glDrawElements()나 glDrawArrays() 같은 함수.이 한 줄의 호출 뒤에, 정확히 무슨 일이 벌어지고,어떻게 해서 한 줄의 코드가 화면에 그림을 그릴 수 있을까?2. 렌더링 파이프라인 전체 그림"정점 데이터가 픽셀이 되는 과정"  1. Vertex Specification (정점 입력)CPU가 넘겨준 정점 데이터를 GPU가 이해하도록 연결glVertexAttribPointer() 등을 통해 설정위치, 색상, 텍스처 좌표 등glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, po..