이번 글에서는 셰이더에 행렬 변환을 적용해보려고 한다. 이 예제로 한번 사람의 팔과 비슷하게 동작하는 프로그램을 작성해보려고 한다. 키보드를 눌러 각도를 조작하면 팔이 회전할 수 있다. 팔의 회전은 상박따로, 하박 따로 회전한다. 기본 코드 틀 #include #include #include "Shader.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include #include #include float vertice[] { -0.3, -0.2, 1.0, // left - bottom +0.3, -0.2, 1.0, // right - bottom -0.3, +0.0, 1.0, // left - top +0.3, +0.0, 1.0, // ri..
이제 지금까지 정리한 변환을 실제 코드로 구현해보려고 한다. OpenGL 과 관련하여 행렬 연산을 간편하게 지원하는 glm 라이브러리를 사용하면 편하게 행렬을 만들고 연산할 수 있다. https://github.com/g-truc/glm GitHub - g-truc/glm: OpenGL Mathematics (GLM) OpenGL Mathematics (GLM). Contribute to g-truc/glm development by creating an account on GitHub. github.com 우선 위 깃허브에 가서 최신버전의 glm 을 다운받는다. 다운받은 glm 파일은 외부 include 디렉터리로 꼭 등록해주자. 이제 glm 을 사용하여 행렬연산을 할 수 있다. 이때는 위와 같은 헤더..
지난 글에서 OpenGL 에서 사용하는 전체 변환의 과정과 함께, 그 변환 하나하나에 사용되는 기본 변환인 이동, 회전, 크기조절 3가지를 정리하였다. 이번 글에서는 각각의 기본 변환이 연속적으로 일어나 하나의 행렬곱 형태로 묶인 복합 변환에 대해 정리한다. 용어 복합 행렬 (Composite Matrix) 는 연속된 변환 행렬을 모두 곱한 하나의 행렬이다. 복합 변환 (composite Transformation) : 복합 행렬로 표현되는 일련의 연속된 변환이다. 만약 어떤 물체 P 에 대해 크기조절 변환 S1 을 가하고, 회전 R1 을 가한 뒤, 다시 크기를 S2로 조절했다고 하면 이 물체를 구성하는 새로운 정점 P' = S2 * R1 * S1 * P 로 표현할 수 있다. 기존 물체 왼쪽에 변환 행렬..
Trnasformation 객체의 위치를 옮기거나 모습을 변형하는 것 (이동, 회전, 크기 변경) 변환을 할 때는 행렬을 사용하는 것이 효율적이다. OpenGL 에서 사용할 때는 Shader 의 input vertex 를 변환하는 것으로 적용한다. 다음이 OpenGL 에서 사용하는 변환의 큰 과정이다. 대문자 V 는 vertex 정점을 의미하고, M 은 matrix 행렬을 의미한다. V clip 이라는 정점을 얻기 위해 V local 이라는 정점에 model 행렬, view 행렬, projection 행렬 순으로 변환을 적용한다는 의미이다. 이를 OpenGL 방식 코드로 보면 이렇게 된다. 입력 정점으로 V local 이 들어오면, 여기에 model 행렬을 곱해 변환하고, view 행렬을 곱해 변환하고,..
Sampler GLSL 에서 텍스쳐 객체를 저장하기 위한 내장 데이터 타입 (일종의 컨테이너) 이다. 텍스쳐 타입에 따라 sampler1D, sampler2D, sampler3D 등으로 분류되며, uniform 변수로 선언한다. 기본적으로 디폴트값이 정해져 있어서, 텍스쳐를 하나만 바인딩하는 경우에는 직접 유니폼 변수에 값을 등록하지 않아도 바로 사용할 수 있다. 텍스쳐를 유니폼 변수에 직접 등록하기 텍스쳐를 유니폼 변수에서 사용할 때는 텍스쳐의 위치에 해당하는 정수값을 넘겨주게 된다. 이러한 텍스쳐의 위치를 texture unit 이라고 한다. 이 텍스쳐 유닛의 기본값은 0이다. (그래서 하나를 바인딩할 때는 바로 가져다 사용할 수 있는 것) 텍스쳐 유닛을 사용하는 이유는 사용자가 셰이더로 하여금 1개..
Texture Wrapping 텍스쳐의 좌표 범위는 (0,0) 에서 (1,1) 이다. 만약 이 범위 밖의 좌표를 지정할 경우, OpenGL은 기본적으로 텍스쳐를 반복한다. 만약 단순 반복하는게 아니라 대칭반복하거나, 클램핑하거나, 지정한 색으로 채우고 싶을 경우, 아래와 같은 다양한 옵션을 사용할 수 있다. GL_REPEAT, GL_MIRRORED_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER 이 설정값은 텍스쳐를 컨텍스트에 바인딩한 이후, 설정값을 넣는다. x축, y축에 대해 각각 설정을 지정해야 하는데, 아래와 같이 glTexParameteri 함수를 사용하여 지정할 수 있다. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, ..
Texture 이번 글에서는 객체에 2D 이미지를 입힐 수 있는 '텍스쳐' 라는 기능에 대해 정리한다. 택스쳐는 어떤 이미지 위에 도형 틀을 그리는 것과 비슷하다. 이를 텍스쳐를 도형에 매핑한다고 하는데, 텍스쳐를 도형(가령 삼각형)에 매핑하기 위해서는, 도형의 vertex가 texture의 어느 위치에 해당하는지를 지정해야 한다. 이때 텍스쳐 좌표계를 통해서 위치를 지정할 수 있는데, 텍스쳐 좌표계는 x, y 축에서 0~1사이의 값을 가진다. 기준점은 왼쪽 아래를 원점으로 한다. 그리고 이 텍스쳐 좌표계를 통해 텍스쳐의 색상을 가져올 수도 있는데, 이를 sampling 이라고 한다. Texture 생성 // Create Texture & Bind unsigned int texture; glGenText..
직사각형에 색상 입히기 예제 지난 글에 작성했던 내용을 한번 코드로 실습해보고자 한다. 우선 아래와 같이 색상을 입힌 직사각형 코드를 준비했다. #include #include #include "Shader_s.h" #include float vertex_data[] = { -0.5, -0.5, 1.0, 0.2, 0.2, 0.2, // 왼쪽 아래 0.5, -0.5, 1.0, 0.3, 0.3, 0.3, // 오른쪽 아래 -0.5, 0.5, 1.0, 0.4, 0.4, 0.4, // 왼쪽 위 0.5, 0.5, 1.0, 0.5, 0.5, 0.5, // 오른쪽 위 }; unsigned int index_data[] = { 0, 1, 2, 1, 2, 3 }; int main() { glfwInit(); glfwWi..
GLSL GLSL은 GL Shader Language 의 약자로, 셰이더 프로그래밍을 위한 C 기반의 언어이다. 대표적인 사용 방법은 아래와 같다. #version version_number // Open GL 버전 in type in_variable_name; in type in_variable_name2; // 셰이더에 들어오는 입력 변수 out type out_variable_name; // 셰이더가 처리한 뒤 내보내는 출력 변수 uniform type uniform_name; // 모든 정점에 대해 동일하게 사용되는 전역 변수 void main() { out_variable_name = weird_stuff_we_processed; } GLSL 데이터 타입 GLSL은 대부분의 C 데이터 타입을 지..
지난 글에서는 VBO 와 VAO 를 사용하여 삼각형을 그리는 방법에 대해 정리하였다. 이번 글에서는 EBO를 사용하여 정점 데이터를 중복으로 사용하지 않도록 하는 과정을 정리한다. 먼저 지난 예제를 토대로 사각형을 그리는 예제를 아래와 같이 작성하였다. #include #include unsigned int createAndCompileShader(GLenum shaderEnum, const char* shaderSourceCode); unsigned int createShaderProgramWithShaders(unsigned int vertexShader, unsigned int fragmentShader); const char* VertexShaderSourceCode = "#version 330 ..