이번 시간에는 3차원 도형 큐브를 그려보겠다.
전체코드
| vertex.glsl
#version 330 core
layout(location=0) in vec3 vPos;
layout(location=1) in vec3 vColor;
out vec3 outColor;
uniform mat4 trans;
void main()
{
gl_Position = trans * vec4(vPos,1.0);
outColor=vColor;
}
| fragment.glsl
#version 330 core
out vec4 Fragcolor;
in vec3 outColor;
void main()
{
Fragcolor = vec4(outColor.r, outColor.g, outColor.b, 1.0);
}
| main.cpp
#include <iostream>
#include <gl/glew.h>
#include <gl/freeglut.h>
#include <gl/freeglut_ext.h>
#include <gl/glm/glm.hpp>
#include <gl/glm/ext.hpp>
#include <gl/glm/gtc/matrix_transform.hpp>
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "freeglut.lib")
#define _CRT_SECURE_NO_WARNINGS
#define WIDTH 800
#define HEIGHT 600
#define BYTE_SIZE_RECT 48
using namespace std;
// 콜벡 함수
GLvoid Render(GLvoid);
GLvoid Reshape(int w, int h);
// VAO, VBO
GLuint VAO, VBO[2], EBO;
void DrawCube();
GLchar* vertexSource, * fragmentSource; // 소스코드 저장 변수
GLuint vertexShader, fragmentShader; //세이더 객체
GLuint shaderProgramID; // 세이더 프로그램
GLint CreateShader(const char* file, int type);
GLvoid CreateShaderProgram();
GLvoid InitBuffer();
void main(int argc, char** argv)
{
// 윈도우 생성
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0, 0);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Draw Rect by using EBO");
// GLEW 초기화하기
glewExperimental = GL_TRUE;
glewInit();
InitBuffer();
CreateShaderProgram();
glutDisplayFunc(Render);
glutMainLoop();
}
GLvoid Render()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgramID);
DrawCube();
glutSwapBuffers();
}
GLvoid Reshape(int w, int h)
{
// 뷰포트 기본 WIDTH HEIGHT로 설정
glViewport(0, 0, w, h);
}
GLvoid InitBuffer()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(2, VBO);
glGenBuffers(1, &EBO);
}
char* GetBuf(const char* file)
{
FILE* fptr;
long length;
char* buf;
// 파일 읽기 형식으로 열기
fopen_s(&fptr, file, "rb");
// 예외처리
if (!fptr) return NULL;
// 파일 buf로 변환
fseek(fptr, 0, SEEK_END);
length = ftell(fptr);
buf = (char*)malloc(length + 1);
fseek(fptr, 0, SEEK_SET);
fread(buf, length, 1, fptr);
// 파일 종료
fclose(fptr);
buf[length] = 0;
return buf;
}
GLint CreateShader(const char* file, int type)
{
// glsl 파일 읽기
GLchar* source = GetBuf(file);
// 객체 생성
GLint shader = glCreateShader(type);
glShaderSource(shader, 1, (const GLchar**)&source, 0);
glCompileShader(shader);
// 컴파일 에러 체크
GLint result;
GLchar errorLog[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (!result)
{
glGetShaderInfoLog(shader, 512, NULL, errorLog);
std::cerr << "ERROR: 컴파일 실패\n" << errorLog << std::endl;
return 0;
}
return shader;
}
void CreateShaderProgram()
{
vertexShader = CreateShader("vertex.glsl", GL_VERTEX_SHADER);
fragmentShader = CreateShader("fragment.glsl", GL_FRAGMENT_SHADER);
// 세이더 프로그램 생성
shaderProgramID = glCreateProgram();
glAttachShader(shaderProgramID, vertexShader);
glAttachShader(shaderProgramID, fragmentShader);
glLinkProgram(shaderProgramID);
// 세이더 삭제
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// 세이더 프로그램 사용
glUseProgram(shaderProgramID);
}
void DrawCube()
{
GLfloat CubeVertexs[24] = {
-0.5f, 0.5f, -0.5f, //0번점
-0.5f, 0.5f, 0.5f, //1번점
0.5f, 0.5f, 0.5f, //2번점
0.5f, 0.5f, -0.5f, //3번점
-0.5f, -0.5f, -0.5f, //4번점
-0.5f, -0.5f, 0.5f, //5번점
0.5f, -0.5f, 0.5f, //6번점
0.5f, -0.5f, -0.5f, //7번점
};
GLfloat CubeColors[24] = {
0.0f, 1.0f, 0.0f, //0번점
0.0f, 1.0f, 1.0f, //1번점
0.0f, 1.0f, 0.0f, //2번점
1.0f, 1.0f, 0.0f, //3번점
1.0f, 0.0f, 1.0f, //4번점
0.0f, 0.0f, 1.0f, //5번점
0.0f, 0.0f, 0.0f, //6번점
1.0f, 0.0f, 0.0f, //7번점
};
GLint CubeIndexs[36] =
{
0,1,2,
0,2,3, //윗면
1,5,6,
1,6,2, //앞면
2,6,7,
2,7,3, //우측면
0,4,5,
0,5,1, //좌측면
5,4,6,
4,7,6,// 밑면
0,7,4, //뒷면
0,3,7
};
// VAO 바인드
glBindVertexArray(VAO);
// 큐브 위치 버퍼 바인드
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertexs), CubeVertexs, GL_STATIC_DRAW);
// 큐브 인덱스 버퍼 바인드
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(CubeIndexs), CubeIndexs, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(0);
// 큐브 색상 버퍼 바인드
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeColors), CubeColors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(1);
// 모델 location 인덱스 저장
unsigned int modelLocation = glGetUniformLocation(shaderProgramID, "trans");
// 모델 및 변환 변수 초기화
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 scale = glm::mat4(1.0f);
glm::mat4 rot = glm::mat4(1.0f);
glm::mat4 move = glm::mat4(1.0f);
// 변환
scale = glm::scale(scale, glm::vec3(0.5f, 0.6f, 0.5f));
move = glm::translate(move, glm::vec3(0.0f, 0.0f, 0.0f));
rot = glm::rotate(rot, glm::radians(30.0f), glm::vec3(1.0f, 0.0f, 0.0f));
rot = glm::rotate(rot, glm::radians(30.0f), glm::vec3(0.0f, 1.0f, 0.0f));
// 변환 과정 처리
model = model * scale * move * rot;
// 모델 변환 적용
glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(model));
// 큐브 그리기
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
// 버퍼 해제
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
'프로그래밍 > OpenGL' 카테고리의 다른 글
[OpenGL] 오픈지엘 Transform (0) | 2024.03.07 |
---|---|
[OpenGL] 오픈지엘 EBO를 이용한 3차원 도형 그리기 (0) | 2024.02.13 |
[OpenGL] 오픈지엘 EBO를 이용한 2차원 도형 그리기 및 응용 (0) | 2024.02.09 |
[OpenGL] 오픈지엘 EBO를 이용한 사각형 그리기 (0) | 2024.02.08 |
[OpenGL] 오픈지엘 VAO와 VBO를 이용한 삼각형 그리기 (0) | 2024.02.06 |