Unity/OpenGL

[OpenGL][VAO, VBO] ์‚ผ๊ฐํ˜•๊ทธ๋ฆฌ๊ธฐ

์˜ฅ์ฒœ์ง€ํ–ฅ์‚ฌ 2023. 11. 17. 10:34
728x90

 

Open GL es ์ด๋ก ์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋น„์ฃผ์–ผ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด Open GL์‹ค์Šต์„ ํ•˜๊ณ ์žˆ๋‹ค.
์ด๋ฒˆ์—๋Š” Open GL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด ํ•จ์ˆ˜๋กœ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋ ค๊ณ  ํ•œ๋‹ค.
 

์ฒซ๋ฒˆ์งธ๋กœ๋Š” GLUT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋ฒ„ํ…์Šค์˜ ์ขŒํ‘œ, ์ƒ‰์ƒ ๋ฒกํ„ฐ๊ฐ’์„ ์ง€์ •ํ•ด์ฃผ์–ด
๊ฐ„๋‹จํ•˜๊ฒŒ ๊ทธ๋ ค๋ณด๋Š” ์ฝ”๋“œ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ๋‹ค.
 

#include <glut.h>

void Display()
{
	//ํ™”๋ฉด ์ง€์šฐ๊ณ  ๋ฒ„ํผ ํด๋ฆฌ์–ด
	glClear(GL_COLOR_BUFFER_BIT);

	//์‚ผ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ ์‹œ์ž‘ ------------------------------------------------------------
	glBegin(GL_TRIANGLES);

	//๋ฒ„ํ…์Šค ์ƒ‰์ƒ, ์œ„์น˜ ์ง€์ •
	glColor3f(1, 0, 0);	 
    glVertex2f(-0.6, -0.75);
	
	glColor3f(0, 1, 0);	 
    glVertex2f(0.6, -0.75);
	
	glColor3f(0, 0, 1);	 
	glVertex2f(0, 0.75);


	//์‚ผ๊ฐํ˜•๊ทธ๋ฆฌ๊ธฐ ๋ -----------------------------------------------------------------
	glEnd();

	// ํ™”๋ฉด์— ์‚ผ๊ฐํ˜• ํ‘œ์‹œ
	glFlush();
}

int main(int argc, char** argv) 
{
	//OpenGL ์œˆ๋„์šฐ ์ดˆ๊ธฐํ™”
	glutInit(&argc, argv);

	//RGB์‚ฌ์šฉํ•˜๋Š” ์œˆ๋„์šฐ ํ•œ๊ฐœ ์ƒ์„ฑ
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

	//์œˆ๋„์šฐ ์œ„์น˜, ํฌ๊ธฐ, ์ด๋ฆ„ ์ง€์ •
	glutInitWindowPosition(80, 80);
	glutInitWindowSize(400, 300);
	glutCreateWindow("OpenGL Triangle");

	//Display ํ•จ์ˆ˜ ํ˜ธ์ถœ
	glutDisplayFunc(Display);

	glutMainLoop();
}

 
Disply() ํ•จ์ˆ˜ ๋‚ด์—์„œ ์‚ผ๊ฐํ˜• ์ขŒํ‘œ์™€ ์ƒ‰์ƒ ๋ฒกํ„ฐ๊ฐ’์„ ์ง€์ •ํ•œ๋‹ค. ์ด๋•Œ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋Š” ์ฝ”๋“œ๋Š” glBegin() ๋’ค,  glEnd() ์•ž์—์„œ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
 
ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ์œ„ํ•ด์„œ๋Š” GLUT ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์™€์•ผํ•˜๋Š”๋ฐ, ์ด๋ฅผ ์œ„ํ•ด ๋‚˜๋Š” glut.dllํŒŒ์ผ์„ ํ•ด๋‹น cppํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ์•ˆ์— ๋„ฃ์–ด๋‘์—ˆ๋‹ค.

 
 
๋‚˜๋Š” 400*300 ํฌ๊ธฐ์˜ ์œˆ๋„์šฐ์œ„์— ๊ฐ ๋ฒ„ํ…์Šค์˜ ์ขŒํ‘œ์™€ ์ƒ‰์ƒ๊ฐ’์ด ๋‹ค๋ฅธ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ ค์ฃผ์—ˆ๋‹ค.
๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 
 
 


 
 
 
๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€ GLFW ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
์—ฌ๊ธฐ์„œ GLUT ๊ณผ GLFW ์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์ƒ๊ธฐ๋Š” ์˜๋ฌธ์ด ์žˆ์„ํ…๋ฐ ๊ทธ์— ๋Œ€ํ•œ ๋‹ต์€ chat gpt์˜ ๋Œ€๋‹ต์„ ์ฐจ์šฉํ•˜๋„๋กํ•˜๊ฒ ๋‹ค.

GLFW๋Š” OpenGL์„ ์œ„ํ•œ C ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์œˆ๋„์šฐ ์ƒ์„ฑ, ์ž…๋ ฅ ์ฒ˜๋ฆฌ, OpenGL ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ ๋“ฑ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. GLFW๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ์„ ์ง€์›ํ•˜๋ฉฐ, ์œˆ๋„์šฐ ์‹œ์Šคํ…œ๊ณผ์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ, ์œˆ๋„์šฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ํ‚ค๋ณด๋“œ ๋ฐ ๋งˆ์šฐ์Šค ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด, GLUT๋Š” OpenGL Utility Toolkit์˜ ์•ฝ์ž๋กœ, C/C++์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. GLUT๋Š” ๋‹จ์ˆœํ™”๋œ API๋ฅผ ์ œ๊ณตํ•˜์—ฌ OpenGL ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ฃผ๋กœ ๊ฐ„๋‹จํ•œ ๊ทธ๋ž˜ํ”ฝ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์‚ฌ์šฉ๋˜๋ฉฐ, ์œˆ๋„์šฐ ์ƒ์„ฑ, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ, ๊ธฐ๋ณธ์ ์ธ ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋“ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ œํ•œ์ ์ธ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 
์š”์•ฝํ•˜์ž๋ฉด GLFW๋Š” ๋น„๊ต์  ์ •๊ตํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” OpenGL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ณ , GLUT๋Š” ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ๊ทธ๋ž˜ํ”ฝ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•˜๊ธฐ ์šฉ์ดํ•œ OpenGL ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ ๊ฒƒ์ด๋‹ค.
 
 
 
์‚ฌ์‹ค๋งํ•ด๋ณด์ž๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์–ด๋–ค๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋“  ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋Š”๋ฐ์—๋Š” ๋ฐฉ์‹์ด ํฌ๊ฒŒ ์ฐจ์ด๋‚˜์ง€๋Š” ์•Š์„๊ฒƒ์ด๋‹ค.
๋‹ค๋งŒ, ์•„๋ž˜ ๋ฐฉ๋ฒ•์€ VAO์™€ VBO๋ฅผ ์‚ฌ์šฉํ•ด ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๊ณ , ํŒŒ์ผ์„ ์ฝ์–ด์™€ ์‰์ด๋”๋ฅผ ์ง์ ‘ ์ปดํŒŒ์ผ ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋‹ค.
 
์„ธ๋ถ€ ์‚ฌํ•ญ์€ ์ฃผ์„์„ ์ฐธ๊ณ ํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.

//API ํ—ค๋” ํฌํ•จ
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <string>

//shader ID ๋ฒˆํ˜ธ ์ €์žฅ์šฉ ๋ณ€์ˆ˜ ์„ ์–ธ
GLuint VBO, VAO, shader;

// ์…ฐ์ด๋” ํŒŒ์ผ๋‚ด์šฉ ์ฝ์–ด์˜ค๊ธฐ -> ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
std::string	ReadFile(const char* filePath)
{
	std::string content;
	std::ifstream fileStream(filePath, std::ios::in);

	while (!fileStream.is_open())
	{
		printf("%s ํŒŒ์ผ ์ฝ๊ธฐ๋ฅผ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.\n", filePath);
		return "";
	}

	std::string line = "";
	while (!fileStream.eof())
	{
		std::getline(fileStream, line);
		content.append(line + "\n");
	}

	fileStream.close();
	return content;
}

//์‰์ด๋” ์ปดํŒŒ์ผ -> ID ๋ฐ˜ํ™˜
GLuint	AddShader(const char* shaderCode, GLenum shaderType)
{
	GLuint new_shader = glCreateShader(shaderType); 

	const GLchar* code[1];
	code[0] = shaderCode;

	glShaderSource(new_shader, 1, code, NULL); //์‰์ด๋” ์ฝ”๋“œ -> ์‰์ด๋”์— ์—ฐ๊ฒฐ

	GLint result = 0;
	GLchar err_log[1024] = { 0 };

	glCompileShader(new_shader); //์‰์ด๋” ์ปดํŒŒ์ผ
	glGetShaderiv(new_shader, GL_COMPILE_STATUS, &result); //์ปดํŒŒ์ผ ์„ฑ๊ณต bool
	if (!result)
	{
		glGetShaderInfoLog(new_shader, sizeof(err_log), NULL, err_log);
		printf("Error compiling the %d shader: '%s'\n", shaderType, err_log);
		return 0;
	}
	return new_shader;
}

// ๋ฒ„ํ…์Šค, ํ”„๋ž˜๊ทธ๋จผํŠธ ์‰์ด๋”๋ฅผ ์ปดํŒŒ์ผ -> ์‰์ด๋” ํ”„๋กœ๊ทธ๋žจ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜
// vsCode = ๋ฒ„ํ…์Šค ์‰์ด๋” ์ฝ”๋“œ, fsCode = ํ”„๋ž˜๊ทธ๋จผํŠธ ์‰์ด๋” ์ฝ”๋“œ -> ๋ฌธ์ž์—ด
void	CompileShader(const char* vsCode, const char* fsCode)
{
	GLuint vs, fs;

	shader = glCreateProgram(); //์‰์ด๋” ํ”„๋กœ๊ทธ๋žจ ์ƒ์„ฑ ํ›„ ID๋ฐ˜ํ™˜

	if (!shader)
	{
		printf("Error: Cannot create shader program.");
		return;
	}

	vs = AddShader(vsCode, GL_VERTEX_SHADER); //ID์ƒ์„ฑ -> ์ปดํŒŒ์ผ
	fs = AddShader(fsCode, GL_FRAGMENT_SHADER);
	glAttachShader(shader, vs);  //๋ฒ„ํ…์Šค ์‰์ด๋” ํ”„๋กœ๊ทธ๋žจ ์ฒจ๋ถ€
	glAttachShader(shader, fs); // ํ”„๋ž˜๊ทธ๋จผํŠธ ์‰์ด๋” ํ”„๋กœ๊ทธ๋žจ ์ฒจ๋ถ€

	GLint result = 0;
	GLchar err_log[1024] = { 0 };

	glLinkProgram(shader);  // ์‰์ด๋” ์ฝ”๋“œ๋ฅผ ๋ช…๋ น์–ด๋กœ ๋ณ€ํ™˜ , GPU์‹คํ–‰ํŒŒ์ผ ์ƒ์„ฑ
	glGetProgramiv(shader, GL_LINK_STATUS, &result); //๋งํฌ ์„ฑ๊ณต์—ฌ๋ถ€ ํ™•์ธ 
	if (!result)
	{
		glGetProgramInfoLog(shader, sizeof(err_log), NULL, err_log);
		printf("Error linking program: '%s'\n", err_log);
		return;
	}
}

//๋ฒ„ํ…์Šค, ํ”„๋ž˜๊ทธ๋จผํŠธ ์‰์ด๋” ๊ฒฝ๋กœ๋ฅผ ์ฝ์–ด์™€ ์‰์ด๋” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜
void CreateShaderProgramFromFiles(const char* vsPath, const char* fsPath)
{
	std::string vsFile = ReadFile(vsPath);
	std::string fsFile = ReadFile(fsPath);
	const char* vsCode = vsFile.c_str();
	const char* fsCode = fsFile.c_str();

	CompileShader(vsCode, fsCode);
}

//์‚ผ๊ฐํ˜•์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
void CreateTriangle()
{
	//๋ฒ„ํ…์Šค ์ขŒํ‘œ ์ •์˜
	GLfloat vertices[] = {
		-1.0f, -1.0f, 0.0f,
		1.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f
	};

	//VAO๋Š”  ํ•˜๋‚˜ ์ด์ƒ์˜ VBO๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด, ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จ, ID๊ฐ€์ง
	glGenVertexArrays(1, &VAO); //๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ ์ƒํƒœ๋ฅผ์ €์žฅ, ์ฝ๊ธฐ์œ„ํ•œ ๊ฐ€์ด๋“œ
	glBindVertexArray(VAO); //VAO๋ฅผ ๋ฐ”์ธ๋”ฉ

	//VBO๋Š” ํ•œ ์ •์ ์˜ ์œ„์น˜, ์ƒ‰์ƒ, ๋…ธ๋ฉ€์ •๋ณด๋ฅผ ๊ฐ€์ง, ๊ณ ์œ ID
	glGenBuffers(1, &VBO); // VBO์ƒ์„ฑ - ๋ฒ„ํ…์Šค ๋ฒ„ํผ ์˜ค๋ธŒ์ ํŠธ
	glBindBuffer(GL_ARRAY_BUFFER, VBO); //GL_ARRAY_BUFFER(openGL context)๋กœ VBO๋ฅผ ๋ฐ”์ธ๋”ฉ
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); //GPU๊ฐ€ VBO๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ์ •๋ณด ์ „๋‹ฌ
	glEnableVertexAttribArray(0);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	glBindVertexArray(0);

int main(void)
{
	// GLFW ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ดˆ๊ธฐํ™”
	if (!glfwInit())
		exit(EXIT_FAILURE);

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // OpenGL ๋ฒ„์ „(x.y ์ค‘ x)
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); // 4.6์— ๋งž์ถฐ ์‹คํ–‰(x.y ์ค‘ y)
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // ๋” ์ด์ƒ ์“ฐ์ด์ง€ ์•Š๋Š” ํ•˜์œ„ ํ˜ธํ™˜ ๊ธฐ๋Šฅ๋“ค ์—๋Ÿฌ ์ฒ˜๋ฆฌ
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // ์ƒ์œ„ ํ˜ธํ™˜์„ฑ ์ง€์›

	//GLFW์ฐฝ ์ƒ์„ฑ
	GLFWwindow* window = glfwCreateWindow(1080, 720, "title", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//์ปจํ…์ŠคํŠธ ์ปค๋ ŒํŠธ ์œˆ๋„์šฐ ์ƒ์„ฑ
	glfwMakeContextCurrent(window);

	//ํ”„๋ ˆ์ž„ ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ทฐํฌํŠธ ์„ค์ •
	int framebuf_width, framebuf_height;
	glfwGetFramebufferSize(window, &framebuf_width, &framebuf_height);
	glViewport(0, 0, framebuf_width, framebuf_height);

	//Glew ์ดˆ๊ธฐํ™”
	if (glewInit() != GLEW_OK)
	{
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	//์‚ผ๊ฐํ˜• ์ƒ์„ฑ
	CreateTriangle();
	CreateShaderProgramFromFiles("shader.vert", "shader.frag");

	//๋ Œ๋”๋ง๋ฃจํ”„
	while (!glfwWindowShouldClose(window))
	{
		//
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glUseProgram(shader);

		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glBindVertexArray(0);

		glUseProgram(0);

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwTerminate();

	return 0;
}

 
 
OpenGL์€ ํ•˜๋‚˜์˜ State Machine์œผ๋กœ ์„ค๋ช…๋˜๋Š”๋ฐ, state๋ฅผ ํ•œ๋ฒˆ ์„ค์ •ํ•˜๋ฉด ํ•ด๋‹น state์— ๋”ฐ๋ผ ์ž‘๋™ํ•˜๊ณ  ์ด state๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ํ•œ ๊ทธ ์ƒํƒœ๊ฐ€ ๊ณ„์† ์œ ์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 
๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•ด๋ณด์ž๋ฉด ๊ฐ€์žฅ ์ตœ๊ทผ์— ์„ค์ •๋œ  state๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ธฐ๊ณ„๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค.
 
๋”ฐ๋ผ์„œ, OpenGL object๋Š” ์ด state๋ฅผ ๊ฐ–๋Š” ๊ตฌ์กฐ์ฒด์™€ ๊ฐ™๊ณ  ์œ„ ์ฝ”๋“œ์—์„œ Open GL Object๋Š” GL_ARRAY_BUFFER ๋ผ๋Š”OpenGL context์— ๋ฐ”์ธ๋“œ ๋˜์–ด  context์— ์—ฐ๊ฒฐ๋œ state๋ฅผ current state๋กœ ์ธ์‹ํ•˜๊ณ , ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋œ๋‹ค.
 
๊ทธ๋Ÿผ ํ•ด๋‹น ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ค OpenGL oject๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์„๊นŒ?
 
์ฒซ๋ฒˆ์งธ๋กœ๋Š”  VBO๋ผ๋Š” OpenGL๊ฐ์ฒด๋‹ค.
VBO( Vertex Buffer Object ) ๋Š” ๋ฒ„ํ…์Šค์˜ ์ •์  ๋ฐ์ดํ„ฐ๋Š” ์œ„์น˜, ์ƒ‰์ƒ, ํ…์Šค์ฒ˜ ์ขŒํ‘œ ๋“ฑ์˜ ์†์„ฑ์„ ํฌํ•จํ•˜๊ณ ์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค.
 
VBO๋ฅผ ์™œ ์‚ฌ์šฉํ•˜๋ƒ๊ณ  ๋ฌป๋Š”๋‹ค๋ฉด ์„ฑ๋Šฅํ–ฅ์ƒ์ด ๋ชฉ์ ์ด๋‹ค.
์ •์  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜๋ก GPU๊ฐ€ ๊ณ„์†ํ•ด์„œ ๊ผญ์ง“์ ์„ ๊ทธ๋ฆฌ๋Š”๊ฒƒ์€ ํšจ์œจ์ ์ด์ง€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ CPU์—์„œ ๊ทธ๋ž˜ํ”ฝ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์ €์žฅ๋˜์–ด ์›ํ•˜๋Š” ๋•Œ์— GPU๊ฐ€ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒŒ๋˜๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ์ •์ ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑ, ์ €์žฅํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ Vertex Specification์ด๋ผ๊ณ  ํ•œ๋‹ค. VBO๋Š” ์ด ๊ณผ์ •์—์„œ ์ •์ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” OpenGL๊ฐ์ฒด๋กœ์„œ ์‚ฌ์šฉ๋œ๋‹ค.
 
์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด VBO๋Š”๋‹จ์ˆœํ•œ ๋ฐฐ์—ด์— ์ง€๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿผ GPU๋Š” ์ด ๋ฐฐ์—ด์„ ์–ด๋–ป๊ฒŒ ์‚ผ๊ฐํ˜•์œผ๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ผ๊นŒ?

	//๋ฒ„ํ…์Šค ์ขŒํ‘œ ์ •์˜
	GLfloat vertices[] = {
		-1.0f, -1.0f, 0.0f,
		1.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f
	};

 
์ด ๋•Œ ์šฐ๋ฆฌ๋Š” Attribute์— ๋Œ€ํ•ด ์•Œ์•„์•ผํ•œ๋‹ค.
Vertex Attribute๋Š” VBO๊ฐ€ ํฌํ•จํ•˜๊ณ ์žˆ๋Š” ์ •์ ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํ˜•์‹์œผ๋กœ ์ €์žฅ๋˜์–ด์žˆ๋Š”์ง€๋ฅผ GPU๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์œผ๋กœ  Attribute๋ฅผ ์—ฐ๋™์‹œ์ผœ์ฃผ์–ด์•ผ GPU๊ฐ€ ์‚ผ๊ฐํ˜•์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
์œ„ ์ฝ”๋“œ์—์„œ๋Š” glVertexAttribPointer() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๊ณ ์žˆ๋‹ค.
 
์ด๋ ‡๊ฒŒ ์œ„ ์ฝ”๋“œ์—์„œ VBO๋Š” Gen -> Bind -> Data ์˜์ˆœ์„œ๋กœ ์‚ฌ์šฉ ๋˜๊ณ ์žˆ๋‹ค.
 
-
 
๋‘๋ฒˆ์งธ๋กœ ์„ค๋ช…ํ•  OpenGL Object๋Š” VAO์ด๋‹ค.
VAO( Vertex Array Object ) ๋Š” ์œ„ ๊ณผ์ •์—์„œ VBO๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ธ๋“œ, ์ €์žฅํ•˜๊ณ  attribute๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์„ ํ•˜๋‚˜์˜ state๋กœ ๋ฌถ์–ด์„œ OpenGL Object์— ์ €์žฅํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด์ด๋‹ค.
์•ž์„œ ๋งํ–ˆ๋“ฏ ์ž‘์—…์„ ํ•˜๋‚˜๋กœ ๋ฌถ์€ state๋ฅผ current state๋กœ ๋งŒ๋“ค์–ด ์ž‘์—…์„ ํ•œ๋ฒˆ๋งŒ ํ•˜๊ฒŒ ํ•œ๋‹ค.
 
VAO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณผ์ •์€ Gen -> Bind ์˜ ์ˆœ์„œ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ณ 
VAO๋ฅผ ์ƒ์„ฑํ•œ ๋’ค OpenGL context์— ๋ฐ”์ธ๋“œ ํ•ด์ค„ ๋•Œ๋งˆ๋‹ค VAO์— ๊ณผ์ •์„ ์ €์žฅํ•˜๊ฒŒ ๋œ๋‹ค.
 
 
 


 
 
 
์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋ฒ„ํ…์Šค์‰์ด๋”์™€ ํ”„๋ž˜๊ทธ๋จผํŠธ ์‰์ด๋”, VBO, VAO.. ๊ทธ ์™ธ์—๋„ ์ƒ์†Œํ•œ ์šฉ์–ด๊ฐ€ ๋งŽ์ด๋‚˜์™€
ํ๋ฆ„์„ ์ดํ•ดํ•˜๋Š”๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์„ ์“ด ๊ฒƒ ๊ฐ™๋‹ค. 
 
ํŠนํžˆ, VBO์™€ VAO๋Š” ๋ฒ„ํ…์Šค ๋ฒ„ํผ, ์ธ๋ฑ์Šค๋ฒ„ํผ์™€์˜ ๊ด€๊ณ„์™€ ๋‹ฎ์•„์žˆ๋‹ค๊ณ  ์ฐฉ์˜คํ•ด 
๋‘˜์˜ ๊ฐœ๋…์„ ํ—ท๊ฐˆ๋ คํ•˜๊ณค ํ–ˆ๋Š”๋ฐ ์ด๋ฒˆ๊ธฐํšŒ์— ๋‘ ๊ฐœ๋…์— ๋Œ€ํ•œ ์ •์˜๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.
์˜ค๋Š˜ ๊ณต๋ถ€ ๋ !

 

728x90