우리는 삼각형을 그릴 텐데 Shader를 불러오고, VAO, VBO, EBO를 연결해준 뒤 무한루프에서 그릴 수 있게 해 주면 된다.
// shader.vs
#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
}
// shader.fs
#version 460 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
FragColor = vec4(ourColor, 1.0f);
}
GLSL로 작성된 Vertex Shader, Fragment Shader를 읽어와서 컴파일한 후, 프로그램에 붙여주어야 한다.
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vertexShaderCode, NULL);
glCompileShader(vertex);
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fragmentShaderCode, NULL);
glCompileShader(fragment);
- 해당하는 Shader Type에 따라 생성해주어야 한다.
- ShaderCode는 해당 파일에서 const char*로 읽어온다.
- 해당하는 Shader에 코드를 넣어준다.
- 컴파일해준다.
프로그램도 쉐이더를 불러오는 방식과 비슷하다.
GLuint ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
glDeleteShader(vertex);
glDeleteShader(fragment);
- 프로그램 생성
- Vertex Shader, Fragment Shader를 프로그램에 붙여준다.
- 프로그램을 링크해준다.
- 사용한 vertex, Fragment는 지워준다.
이제 쉐이더 끝!
해당하는 정점과, 정점의 인덱스를 선언하여 VAO를 바인드 하여 VBO, EBO에 정보를 전달해준다.
float vertices[] = {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
uint32_t indices[] = {
0, 1, 3,
1, 2, 3
};
해당 정점, 순서를 지정한다.
GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
- VAO 생성해서 바인드 한다.
- VBO 생성해서 바인드 하면 GL_ARRAY_BUFFER를 타깃으로 하는 모든 버퍼는 VBO를 사용하게 된다.
- glVertexAttribPointer()로 Vertex Shader에서 사용할 정점 속성에 대해 알려준다.
- 첫 번째 파라미터가 Vertex Shader에서의 layout의 위치다.
- 두 번째 파라미터는 해당 정점의 속성 값의 크기이다.
- 세 번째 파라미터는 해당하는 데이터의 타입이다.
- 네 번째 파라미터는 데이터를 정규화할 것인지 정하는 것인데, GL_TRUE로 설정하면 [0~1], 부호가 있다면 [-1~1]의 범위를 갖게 한다.
- 다섯 번째 파라미터는 데이터가 시작하는 위치의 offset이다.
- glEnableertexAttribArray()로 해당하는 Vertex Shader에서의 layout의 위치를 사용할 수 있게 한다.
- EBO 또한 VBO와 같은 방식이지만, GL_ELEMENT_ARRAY_BUFFER를 바인딩한다.
이후 무한 루프에서 그려주면 된다.
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(m_program);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
해당 프로그램을 사용하도록 해준다.
glDrawElements()를 이용해서 그릴 프리미티브의 특성을 정해준다.
- 첫 번째 파라미터는 프리미티브의 유형을 정해준다.
- 두 번째 파라미터는 몇 개의 정점을 그릴지에 대해 정한다.
- 세 번째 파라미터는 정점 인덱스의 자료형을 정한다.
- 네 번째 파라미터는 정점 인덱스의 오프셋이다.
'OpenGL' 카테고리의 다른 글
OpenGL[Lighting] (0) | 2022.10.18 |
---|---|
OpenGL[Coordinate System] (0) | 2022.10.18 |
OpenGL[01](Shader) (1) | 2022.10.12 |
OpenGL[00](First Window) (0) | 2022.10.12 |
vcpkg를 이용한 GLFW, GLM, ASSIMP, GLAD setup (0) | 2022.10.06 |