opengl

opengl 움직이는 삼각형

현구구 2022. 8. 23. 16:11

 

#include <sb7.h>
#include <vmath.h> //수학 함수 해더파일 sin,cos
// sb6::application을 상속받는다.
class my_application : public sb7::application
{
public: //쉐이더 컴파일 과정
	// 렌더링 virtual 함수를 작성해서 오버라이딩한다.

	GLuint compile_shaders(void)
	{
		GLuint vertex_shader;
		vertex_shader = glCreateShader(GL_VERTEX_SHADER); //버텍스 쉐이더 생성

		GLuint fragment_shader;
		fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);

		GLuint program;
		program = glCreateProgram();

		const GLchar* vertex_shader_source[] =
		{
			"#version 430 core\n"
			"layout (location = 0) in vec4 move;\n"
			"layout (location = 1) in vec4 color;\n"
			"out vec4 color_vertex;\n"
			"void main(void)\n"
			"{\n"
			"const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),\n"
			"vec4(-0.25, 0.25, 0.5, 1.0),\n"
			"vec4(0.25, 0.25, 0.5,1.0));\n"
			"gl_Position = vertices[gl_VertexID]+move;\n"
			"color_vertex= color;\n"
			"}\n"
		};
		const GLchar* fragment_shader_source[] =
		{
			"#version 430 core                          \n"
			"in vec4 color_vertex;\n"
			"                                           \n"
			"out vec4 color;                            \n"
			"                                           \n"
			"void main(void)                            \n"
			"{                                          \n"
			"   color = color_vertex;   \n"
			"}                                          \n"
		};

		glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
		glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);

		glCompileShader(vertex_shader);
		glCompileShader(fragment_shader);

		glAttachShader(program, vertex_shader);
		glAttachShader(program, fragment_shader);

		glLinkProgram(program);

		glDeleteShader(vertex_shader);
		glDeleteShader(fragment_shader);

		return program;
	}
	virtual void startup()
	{
		rendering_program = compile_shaders();
		glGenVertexArrays(1, &vertex_array_object);
		glBindVertexArray(vertex_array_object);
	}
	virtual void shutdown()
	{
		glDeleteVertexArrays(1, &vertex_array_object);
		glDeleteProgram(rendering_program);
	}
	virtual void render(double currentTime) // = tick함수 무한반복 currentTime -> 1초 / render virtual 로 재정의(override)
	{

		//=============배경=======================================
		const GLfloat red[] = { (float)sin(currentTime) * 0.5f + 0.5f, (float)cos(currentTime) * 0.5f + 0.5f, 0.0f, 1.0f };
		//static 이면 안됨 색 안바뀜
		glClearBufferfv(GL_COLOR, 0, red);
		//========================================attrib으로 보낼것들==== 
		GLfloat move[] = { (float)sin(currentTime), (float)cos(currentTime) * 0.5f, 0.0f, 0.0f };
		glVertexAttrib4fv(0, move);

		GLfloat color[] = { (float)cos(currentTime) * 0.5f + 0.5f, (float)sin(currentTime) * 0.5f + 0.5f, 0.0f, 1.0f };
		glVertexAttrib4fv(1, color);
		//=====================프로그램 시작================================
		glUseProgram(rendering_program);
		glDrawArrays(GL_TRIANGLES, 0, 3);

	} //모든 OpenGL 함수는 gl 로 시작 
private:
	GLuint rendering_program;
	GLuint vertex_array_object;
};


// DECLARE_MAIN의 하나뿐인 인스턴스
DECLARE_MAIN(my_application) // int main() 대체, class명 삽입

layout 기능은 쉽게 말해서 render 함수에서 설정한 변수를 shader로 불러오는 역할을 한다

layout move 는 render 함수에서 정의한 삼각형의 위치를 움직이도록 한 float형 배열이며 번호는 0으로 한다

color는 삼각형의 색깔을 나타내며 번호는 1로 하여 각 layout 번호가 겹치지 않도록 한다

 

이때 color는 버텍스 쉐이더가 아닌 프래그먼트 쉐이더에서 다루는 것이므로 다시 out 을 통해 프래그먼트 쉐이더로 보내준다

보내는 변수명은 color_vertex로 한다

프래그먼트 쉐이더에서는 버텍스 쉐이더에서 받아온 color_vertex를 받아와 삼각형의 색을 지정해준다

그리고 render함수에서 컴파일 된 rendering_program을 사용한다고 지정해주고

삼각형을 그린다