

location은 여기서 쉐이더를 각각 연결하도록 하는 것임을 기억하도록

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <string>
GLuint VBO, VAO, EBO, shaderProgram;
// Read shader file
std::string ReadFile(const char* filePath) {
std::ifstream file(filePath, std::ios::in);
if (!file.is_open()) {
std::cerr << "Failed to open file: " << filePath << std::endl;
return "";
}
std::string content, line;
while (std::getline(file, line)) {
content += line + "\\n";
}
file.close();
return content;
}
// Compile and link shader program
GLuint CreateShaderProgram(const char* vertexPath, const char* fragmentPath) {
std::string vsCode = ReadFile(vertexPath);
std::string fsCode = ReadFile(fragmentPath);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* vsSource = vsCode.c_str();
glShaderSource(vertexShader, 1, &vsSource, NULL);
glCompileShader(vertexShader);
GLint success;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cerr << "Error compiling vertex shader: " << infoLog << std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fsSource = fsCode.c_str();
glShaderSource(fragmentShader, 1, &fsSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cerr << "Error compiling fragment shader: " << infoLog << std::endl;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(program, 512, NULL, infoLog);
std::cerr << "Error linking program: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
// Cube data -> 이렇게 하면 앞(x,y,z), 뒤(r,g,b) 가능한데 이때 가능한 이유가 어차피 glVertextAttriibpointer를 사용해서 각 속성 정의 가능
void CreateCube() {
GLfloat vertices[] = {
// Positions // Colors
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
};
GLuint indices[] = {
// Front face
0, 1, 2, 2, 3, 0, // 예를 들어서 삼각형 0,1,2 이어서 한개, 2,3,0 이어서 한개로 총 삼각형 2개로 사각형 1개인 면 생성
// Back face
4, 5, 6, 6, 7, 4,
// Left face
4, 5, 3, 3, 0, 4,
// Right face
1, 2, 6, 6, 7, 1,
// Top face
3, 2, 6, 6, 5, 3,
// Bottom face
4, 7, 1, 1, 0, 4,
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &EBO); //인덱스 버퍼로 만들어서 데이터 사용
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0); //여기서 처음에 0은 location을 의미하고 이후 쉐이더로 입력하도록 하는 것
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); //(여기서 아까 위에서 앞,뒤 나눴던 것을 3개씩 끊어서 가져가도록 하는 것) 분할이 가능하다는 것을 알아두면 될 듯
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int main() {
if (!glfwInit()) return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Cube Example", NULL, NULL);
if (!window) return -1;
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) return -1;
shaderProgram = CreateShaderProgram("shader.vert", "shader.frag");
CreateCube();
glEnable(GL_DEPTH_TEST);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(
glm::vec3(3.0f, 3.0f, 3.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)
);
glm::mat4 projection = glm::perspective(
glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f
);
glm::mat4 mvp = projection * view * model;
GLuint mvpLoc = glGetUniformLocation(shaderProgram, "MVP");
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
메인코드
#version 460
in vec3 fragmentColor;
out vec4 color;
void main() {
color = vec4(fragmentColor, 1.0);
}
shader.frag
#version 460
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 vertexColor;
out vec3 fragmentColor;
uniform mat4 MVP;
void main() {
gl_Position = MVP * vec4(pos, 1.0);
fragmentColor = vertexColor;
}
shader.vert
예외로 알아서 회전하는 방식으로 설정
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <chrono> // 시간 측정을 위해 사용
GLuint VBO, VAO, EBO, shaderProgram;
// Read shader file
std::string ReadFile(const char* filePath) {
std::ifstream file(filePath, std::ios::in);
if (!file.is_open()) {
std::cerr << "Failed to open file: " << filePath << std::endl;
return "";
}
std::string content, line;
while (std::getline(file, line)) {
content += line + "\\n";
}
file.close();
return content;
}
// Compile and link shader program
GLuint CreateShaderProgram(const char* vertexPath, const char* fragmentPath) {
std::string vsCode = ReadFile(vertexPath);
std::string fsCode = ReadFile(fragmentPath);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* vsSource = vsCode.c_str();
glShaderSource(vertexShader, 1, &vsSource, NULL);
glCompileShader(vertexShader);
GLint success;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cerr << "Error compiling vertex shader: " << infoLog << std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fsSource = fsCode.c_str();
glShaderSource(fragmentShader, 1, &fsSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cerr << "Error compiling fragment shader: " << infoLog << std::endl;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(program, 512, NULL, infoLog);
std::cerr << "Error linking program: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return program;
}
// Cube data
void CreateCube() {
GLfloat vertices[] = {
// Positions // Colors
-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.5f,
};
GLuint indices[] = {
// Front face
0, 1, 2, 2, 3, 0,
// Back face
4, 5, 6, 6, 7, 4,
// Left face
4, 5, 3, 3, 0, 4,
// Right face
1, 2, 6, 6, 7, 1,
// Top face
3, 2, 6, 6, 5, 3,
// Bottom face
4, 7, 1, 1, 0, 4,
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int main() {
if (!glfwInit()) return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Rotating Cube", NULL, NULL);
if (!window) return -1;
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) return -1;
shaderProgram = CreateShaderProgram("shader.vert", "shader.frag");
CreateCube();
glEnable(GL_DEPTH_TEST);
// 시간 측정 초기화
auto lastTime = std::chrono::high_resolution_clock::now();
float rotationAngle = 0.0f; // 초기 회전 각도
while (!glfwWindowShouldClose(window)) {
auto currentTime = std::chrono::high_resolution_clock::now();
float deltaTime = std::chrono::duration<float>(currentTime - lastTime).count();
lastTime = currentTime;
// 회전 각도 업데이트
rotationAngle += 50.0f * deltaTime; // 초당 50도 회전
if (rotationAngle > 360.0f) rotationAngle -= 360.0f;
// 화면 클리어
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(rotationAngle), glm::vec3(1.0f, 1.0f, 0.0f));
glm::mat4 view = glm::lookAt(
glm::vec3(3.0f, 3.0f, 3.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)
);
glm::mat4 projection = glm::perspective(
glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f
);
glm::mat4 mvp = projection * view * model;
GLuint mvpLoc = glGetUniformLocation(shaderProgram, "MVP");
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
이제 texture를 입혀서 확인해 볼 생각
→ 2d 이미지에 texture 입히는 것 6번 or CubeMap확인 해서 하는 방법