[OpenGL] 9. Shader (5) - 직사각형에 실시간으로 변하는 색상 입히기 (GLFW, GLAD)

2024. 4. 9. 20:10·CS/HCI 윈도우즈프로그래밍
반응형

직사각형에 색상 입히기 예제

지난 글에 작성했던 내용을 한번 코드로 실습해보고자 한다.

우선 아래와 같이 색상을 입힌 직사각형 코드를 준비했다.

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "Shader_s.h"
#include <iostream>

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();
	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, "Colored Rectangle", NULL, NULL);
	glfwMakeContextCurrent(window);

	// glad load
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "GLAD 로드 중 에러 발생\n";
		return -1;
	}

	// Shader 생성
	Shader shader("vertex_shader.vs", "fragment_shader.fs");

	// VAO, VBO, EBO
	unsigned int VAO, VBO, EBO;

	// VAO 생성 & Context에 바인딩
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	// VBO 생성, VAO에 바인딩, 데이터 소스 연결
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);

	// EBO 생성, VAO에 바인딩, EBO 소스 연결
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_data), index_data, GL_STATIC_DRAW);

	// Vertex Attribute 데이터 연결
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)0); // 위치
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float)*3)); // 색상
	glEnableVertexAttribArray(1);

	while (!glfwWindowShouldClose(window)) {
		glClearColor(0.5, 0.5, 0.5, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);

		shader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		/*glDrawArrays(GL_TRIANGLES, 0, 3);
		glDrawArrays(GL_TRIANGLES, 1, 3);*/

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}

 

셰이더 프로그램은 아래와 같이 작성했다.

 

// vertex_shader.vs

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 fragColor;
void main() {
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    fragColor = aColor;
}

 

// fragment_shader.fs

#version 330 core
in vec3 fragColor;
out vec3 aColor;
void main() {
    aColor = fragColor;
}

 

이 소스코드를 컴파일하면 아래와 같은 직사각형이 나온다.

 

지난번 삼각형 예제와 다른점은 색상이 추가된 점 하나이다.

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, // 오른쪽 위
};

 

vertex_data 에서 정점 정보에 더해 색상 RGB 정보도 같이 전달하였다.

물론 이에 맞게 AttribPointer도 코드를 수정했다.

// Vertex Attribute 데이터 연결
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)0); // 위치
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float)*3)); // 색상
	glEnableVertexAttribArray(1);

 

Attrib 번호 0에는 위치정보를, 1에는 색상정보를 저장하였다.

이 값은 vertex shader로 넘어간다.

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

 

지난 글에서 설명했듯, Attirb 번호가 그대로 location으로 들어간다.

out vec3 fragColor;
void main() {
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    fragColor = aColor;
}

 

vertex_shader가 입력받은 색상 벡터는 그대로 fragColor 라는 변수를 통해 내보내진다.

#version 330 core
in vec3 fragColor;
out vec3 aColor;
void main() {
    aColor = fragColor;
}

 

그리고 이 변수는 fragment_shader의 입력값으로 들어와 그대로 색상값을 출력하도록 한다.

(fragColor 라는 동일한 이름을 사용한 것에 주목하자!)

 

Uniform 변수 사용해보기

이제 이 직사각형의 색상을 시간이 지날 때마다 실시간으로 바꿔보자.

시간이 지날 때마다 실시간으로 색상을 바꾸려면 시간의 변화에 따라 색상값을 실시간으로 바꿔야한다.

이를 위해서는 CPU에서 시간에 따라 색상값을 생성하여 이 값을 GPU에 넘겨야 한다.

이때 활용하는 것이 바로 uniform 변수이다.

 

// Uniform 변수 생성 & 색상 초기값 세팅
int colorUniformLoc = glGetUniformLocation(shader.ID, "uniformColor");
glUniform3f(colorUniformLoc, 0.0, 0.0, 0.0);

 

main 함수에서 위와 같이 셰이더 프로그램에 uniform 변수를 정의해준다.

glCreateProgram 함수를 사용하면 그 반환값이 int 형이므로 그대로 사용하면 되고, Shader 클래스를 사용하는 경우, shader.ID를 사용하여 매개변수로 넘겨주면 된다.

 

변수에 값을 할당할 때는 glUniform3f() 와 같은 함수로 타입을 지정하고, 함수 매개변수로 값을 넘기면 된다.

 

		shader.use();
		glUniform3f(colorUniformLoc, 1.0, 0.0, 0.0); // 렌더링 루프에서 uniform 변수값을 지정해야 함.

 

유니폼 변수에 값을 할당하는 작업은 꼭 렌더링 루프 안에서 실행하자.

렌더링 루프 밖에서만 실행하고, 루프 안에서 실행하지 않으면 색상값이 입혀지지 않는다.

#version 330 core
// in vec3 fragColor;
out vec3 aColor;
uniform vec3 uniformColor;
void main() {
    // aColor = fragColor;
    aColor = uniformColor;
}

 

색상값을 사용할 fragment_shader 소스코드는 위와같이 바꿔주었다.

 

다음은 실행결과이다.

 

아주 쨍한 빨간색이 잘 나온다.

이제 시간이 지나면서 이 색이 동적으로 바뀌게 해보자.

 

시간에 따라 RGB 중 R 값을 다르게 설정해야 한다.

double time = glfwGetTime();
float redColor = abs(sin(time));
glUniform3f(colorUniformLoc, redColor, 0.0, 0.0); // 렌더링 루프에서 uniform 변수값을 지정해야 함.

 

해당 코드는 위와 같이 쓸 수 있다.

시간 값을 X축으로 하는 sin 함수를 그리고, 음수값을 무시하기 위해 절댓값을 취해준다.

 

시간이 지날 때마다 사각형의 색상이 바뀐다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'CS > HCI 윈도우즈프로그래밍' 카테고리의 다른 글

[OpenGL] 11. Shader (7) - Texture Wrapping, Filtering, MipMaps  (1) 2024.04.12
[OpenGL] 10. Shader (6) - Texture  (0) 2024.04.11
[OpenGL] 8. Shader (4) - GLSL  (0) 2024.04.09
[OpenGL] 7. Shader (3) - EBO (Element Buffer Object)  (0) 2024.04.08
[OpenGL] 6. Shader (2) - VAO  (1) 2024.04.07
'CS/HCI 윈도우즈프로그래밍' 카테고리의 다른 글
  • [OpenGL] 11. Shader (7) - Texture Wrapping, Filtering, MipMaps
  • [OpenGL] 10. Shader (6) - Texture
  • [OpenGL] 8. Shader (4) - GLSL
  • [OpenGL] 7. Shader (3) - EBO (Element Buffer Object)
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615)
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45)
        • 생각 정리 (23)
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[OpenGL] 9. Shader (5) - 직사각형에 실시간으로 변하는 색상 입히기 (GLFW, GLAD)
상단으로

티스토리툴바