//배경색 칠하기//////////////////////////////////////////
// sb6.h 헤더 파일을 포함시킨다.
#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;
GLuint fragment_shader;
GLuint program;
program = glCreateProgram();
const GLchar* vertex_shader_source[] =
{
"#version 430 core\n"
"layout (location = 0) in vec3 pos;\n"
"layout (location = 1) in vec3 color;\n"
"layout (location = 2) in vec3 colormove;\n"
"uniform mat4 rotMat;\n" //선언을 여기서함
"out vec3 vsColor;\n"
"void main(void)\n"
"{\n"
"gl_Position = rotMat*vec4(pos.x,pos.y,pos.z,1.0);\n"
"vsColor= color+colormove;\n"
"}\n"
};
const GLchar* fragment_shader_source[] =
{
"#version 430 core \n"
"in vec3 vsColor;\n"
" \n"
"out vec4 fragColor; \n"
" \n"
"void main(void) \n"
"{ \n"
" fragColor = vec4(vsColor, 1.0); \n"
"} \n"
};
vertex_shader = glCreateShader(GL_VERTEX_SHADER); //버텍스 쉐이더 생성
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
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, &VAO);
glBindVertexArray(VAO);
//삼각형 세 점의 위치와 색 정의
GLfloat vertices[] = {
0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.0f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
//VBO를 생성하여 vertices 값들을 복사
GLuint VBO;
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 * 4, (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * 4, (void*)(12));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
virtual void shutdown()
{
glDeleteVertexArrays(1, &VAO);
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 };
const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, black);
//=============================================================
GLfloat colormove[] = { (float)sin(currentTime) * 0.5f, (float)cos(currentTime) * 0.5f, 0.0f, 0.0f };
glVertexAttrib4fv(2, colormove);
//================================================
glUseProgram(rendering_program);
float angle = currentTime * 50;
vmath::mat4 rm = vmath::rotate(angle, 0.0f, 0.0f, 1.0f);
GLint rotMatLocation = glGetUniformLocation(rendering_program, "rotMat");//rendering_program에 있는 rotMat 위치 받아옴
glUniformMatrix4fv(rotMatLocation, 1, GL_FALSE, rm);//받아왓으면 그 rotMatLocation에 rm 넣어줌
glBindVertexArray(VAO);//미리 설정한 vao를 그리기 위해 바인드한다
glDrawArrays(GL_TRIANGLES, 0, 12);
} //모든 OpenGL 함수는 gl 로 시작
private:
GLuint rendering_program;
GLuint VAO;
};
// DECLARE_MAIN의 하나뿐인 인스턴스
DECLARE_MAIN(my_application) // int main() 대체, class명 삽입
먼저 startup 함수에서 점의 위치와 점의 색을 정해준다
첫 줄 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f 의 경우 앞의 3개의 float 0.0, 0.0, 0.5는 점의 위치를,
뒤의 3개 1.0, 0.0, 0.0은 점의 색을 나타낸다.
저장한 vertices는 버텍스 쉐이더로 보내준다.
첫 줄 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f 의 경우 인덱스는 앞에서부터 0 - 1 - 2 - 3 - 4 - 5이다.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, (void*)0); 에서
0은 버텍스쉐이더로 보낼 layout인덱스를 나타낸다
3은 원소의 개수
6 * 4 에서 6은 한 줄의 원소개수(x,y,z,r,g,b) 4는 한 원소의 size (float의 size는 4)
(void*)0은 한 줄에서 시작할 인덱스이다 점 위치의 경우 0번인덱스에서 시작한다
(void*)12는 4(float size) * 3(한 줄에서 시작할 인덱스)를 나타낸다 즉 3번 인덱스부터 점의 색을 나타낸다
스타트업에서 지정해준 점의 위치와 점의 색은 버텍스 쉐이더로 보내준다
마지막으로
프래그먼트 쉐이더에서 uniform을 하나 생성한다 변수 이름은 rotMat
선언한 변수 rotMat는 render함수에서 설정해준다
위 코드는
1. x축 방향으로 돌도록 변수 rm 을 선언하고
2. 버텍스 쉐이더에 있는 rotMat uniform을 받아오는 rotMatLocation 변수를 하나 선언한다
3. 그 다음 rotMatLocation에 rm을 넣어주면 버텍스쉐이더로 변수가 넘어간다
//배경색 칠하기//////////////////////////////////////////
// sb6.h 헤더 파일을 포함시킨다.
#include <sb7.h>
#include <vmath.h> //수학 함수 해더파일 sin,cos
// sb6::application을 상속받는다.
class my_application : public sb7::application
{
public: //쉐이더 컴파일 과정
GLuint compile_shaders(void)
{
//쉐이더 객체 생성
GLuint vertex_shader_pung;
vertex_shader_pung = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader_pung;
fragment_shader_pung = glCreateShader(GL_FRAGMENT_SHADER);
//쉐이더 소스 코드
const GLchar* vertex_shader_source_pung[] =
{
//"#version 430 core\n"
//"\n"
//"void main(void)\n"
//"{\n"
//" gl_Position = vec4(0.0, 0.0, 0.5, 1.0);\n" //이게 중앙이래
//"}\n" //얘는 점 위치
"#version 430 core\n"
"\n"
"layout(location = 0) in vec4 offset;\n"
"layout(location = 5) in float angle_vs;\n"
"out vec4 vs_color;\n"
"void main(void)\n"
"{\n"
//점위치
" const vec4 vertices[12] = vec4[12](vec4(0.0, 0.0, 0.5, 1.0),\n"
" vec4(0.0, 0.5, 0.5, 1.0),\n"
" vec4(-0.5, 0.5, 0.5, 1.0),\n"
"vec4(0.0, 0.0, 0.5, 1.0),\n"
"vec4(0.5, 0.0, 0.5, 1.0),\n"
"vec4(0.5, 0.5, 0.5, 1.0),\n"
"vec4(0.0, 0.0, 0.5, 1.0),\n"
"vec4(-0.5, 0.0, 0.5, 1.0),\n"
"vec4(-0.5, -0.5, 0.5, 1.0),\n"
"vec4(0.0, 0.0, 0.5, 1.0),\n"
"vec4(0.0, -0.5, 0.5, 1.0),\n"
"vec4(0.5, -0.5, 0.5, 1.0));\n"
//회전행렬
"mat4 m1;\n"
"m1[0] = vec4(cos(angle_vs),sin(angle_vs),0.0,0.0);\n"
"m1[1] = vec4(-sin(angle_vs),cos(angle_vs),0.0,0.0);\n"
"m1[2] = vec4(0.0,0.0,1.0,0.0);\n"
"m1[3] = vec4(0.0,0.0,0.0,1.0);\n"
//위치에 회전행렬 곱해줌
" gl_Position = m1*vertices[gl_VertexID];\n"
//컬러부분
" const vec4 colors[12] = vec4[12](vec4(1.0, 0.0, 0.0, 1.0),\n"
" vec4(0.0, 1.0, 0.0, 1.0),\n"
" vec4(0.0, 0.0, 1.0, 1.0),\n"
" vec4(1.0, 0.0, 0.0, 1.0),\n"
" vec4(0.0, 1.0, 0.0, 1.0),\n"
" vec4(0.0, 0.0, 1.0, 1.0),\n"
" vec4(1.0, 0.0, 0.0, 1.0),\n"
" vec4(0.0, 1.0, 0.0, 1.0),\n"
" vec4(0.0, 0.0, 1.0, 1.0),\n"
" vec4(1.0, 0.0, 0.0, 1.0),\n"
" vec4(0.0, 1.0, 0.0, 1.0),\n"
" vec4(0.0, 0.0, 1.0, 1.0));\n"
" vs_color = colors[gl_VertexID]+offset;\n"
"}\n"
};
//프래그먼트 소스코드
const GLchar* fragment_shdaer_source_pung[] =
{
"#version 430 core\n"
"in vec4 vs_color;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = vs_color;\n"
"}\n"
};
//쉐이더 소스코드 쉐이더 객체로 전달
glShaderSource(vertex_shader_pung, 1, vertex_shader_source_pung, NULL);
glShaderSource(fragment_shader_pung, 1, fragment_shdaer_source_pung, NULL);
//쉐이더 객체의 소스 코드 컴파일 mack
glCompileShader(vertex_shader_pung);
glCompileShader(fragment_shader_pung);
//프로그램 객체 생성
GLuint program_pung;
program_pung = glCreateProgram();
//쉐이더 객체를 프로그램에 어태치 시킴
glAttachShader(program_pung, vertex_shader_pung);
glAttachShader(program_pung, fragment_shader_pung);
//프로그램 객체에 어태치 시킨 쉐이더 객채들을 링크함
glLinkProgram(program_pung);
//쉐이더 객체들을 삭제한다
glDeleteShader(vertex_shader_pung);
glDeleteShader(fragment_shader_pung);
return program_pung; //program 을 리턴해줌
}
GLuint compile_shaders_mack(void)
{
//쉐이더 객체 생성
GLuint vertex_shader_mack;
vertex_shader_mack = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader_mack;
fragment_shader_mack = glCreateShader(GL_FRAGMENT_SHADER);
//쉐이더 소스 코드
const GLchar* vertex_shader_source_mack[] =
{
"#version 430 core\n"
"\n"
"void main(void)\n"
"{\n"
" const vec4 vertices[6] = vec4[6](vec4(-0.01, 0.0, 0.5, 1.0),\n"
" vec4(-0.01, -1, 0.5, 1.0),\n"
" vec4(0.01, -1.0, 0.5, 1.0),\n"
"vec4(-0.01, 0.0, 0.5, 1.0),\n"
"vec4(0.01, 0, 0.5, 1.0),\n"
"vec4(0.01, -1.0, 0.5, 1.0));\n"
" gl_Position = vertices[gl_VertexID];\n"
"}\n"
};
//프래그먼트 소스코드
const GLchar* fragment_shdaer_source_mack[] =
{
"#version 430 core\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = vec4(0,1,0.8,1);\n"
"}\n"
};
//쉐이더 소스코드 쉐이더 객체로 전달
glShaderSource(vertex_shader_mack, 1, vertex_shader_source_mack, NULL);
glShaderSource(fragment_shader_mack, 1, fragment_shdaer_source_mack, NULL);
//쉐이더 객체의 소스 코드 컴파일 mack
glCompileShader(vertex_shader_mack);
glCompileShader(fragment_shader_mack);
//프로그램 객체 생성
GLuint program_mack;
program_mack = glCreateProgram();
//쉐이더 객체를 프로그램에 어태치 시킴
glAttachShader(program_mack, vertex_shader_mack);
glAttachShader(program_mack, fragment_shader_mack);
//프로그램 객체에 어태치 시킨 쉐이더 객채들을 링크함
glLinkProgram(program_mack);
//쉐이더 객체들을 삭제한다
glDeleteShader(vertex_shader_mack);
glDeleteShader(fragment_shader_mack);
return program_mack; //program 을 리턴해줌
}
virtual void startup() //애플리케이션 초기화 가상함수
{
rendering_program = compile_shaders();//쉐이더 및 프로그램 재 컴파일 안하도록 일련의 과정 startup에 저장//리턴값인 program 이 들어옴
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
//===================================================================
rendering_program_mack = compile_shaders_mack();
glGenVertexArrays(1, &vertex_array_object_mack);
glBindVertexArray(vertex_array_object_mack);
}
virtual void shutdown()//애플리케이션 종료시 호출되는 함수
{
glDeleteVertexArrays(1, &vertex_array_object);
glDeleteProgram(rendering_program);
//====================================================================
glDeleteVertexArrays(1, &vertex_array_object_mack);
glDeleteProgram(rendering_program_mack);
}
// 렌더링 virtual 함수를 작성해서 오버라이딩한다.
virtual void render(double currentTime) // = tick함수 무한반복 currentTime -> 1초 / render virtual 로 재정의(override)
{
//====================배경===========================
const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat red[] =
{
(float)sin(currentTime) * 0.5f + 0.5f, 1.0f, 0.5f, 1.0f
};
//배경 색깔
glClearBufferfv(GL_COLOR, 0, black);
//============================================================
GLfloat attrib[] = { (float)sin(currentTime) * 0.5f, (float)cos(currentTime) * 0.5f, 0.0f, 0.0f };
glVertexAttrib4fv(0, attrib);//vertax shader 로 넘길 값 index 는 0
GLfloat color[] = { 0.0f, 1.0f, 1.0f, 0.0f };
glVertexAttrib4fv(1, color);
//프로그램 실행 막대=================================
glUseProgram(rendering_program_mack);
glDrawArrays(GL_TRIANGLES, 0, 6);
//프로그램 실행 바람개비============================================
glUseProgram(rendering_program);
float angle = currentTime;
glVertexAttrib1f(5, angle);
glDrawArrays(GL_TRIANGLES, 0, 12); //삼각형 점이 3개 필요
} //모든 OpenGL 함수는 gl 로 시작
private:
GLuint rendering_program;
GLuint vertex_array_object;
GLuint rendering_program_mack;
GLuint vertex_array_object_mack;
};
// DECLARE_MAIN의 하나뿐인 인스턴스
DECLARE_MAIN(my_application) // int main() 대체, class명 삽입
VBO 와 uniform을 사용 안하고 버텍스쉐이더에서 하드코딩하여 바람개비를 만드는 코드는 다음과 같다.
'opengl' 카테고리의 다른 글
opengl 시점변환 원근투영 - opengl라이브러리 (0) | 2022.09.06 |
---|---|
opengl 시점변환 원근투영 - 하드코딩 (0) | 2022.09.06 |
opengl 바람개비 보간 (0) | 2022.09.06 |
opengl 삼각형 보간 (0) | 2022.08.25 |
opengl 삼각형 폴리곤 모드 - 테셀레이션, 지오메트리 쉐이더 (0) | 2022.08.24 |