#include <iostream>
#define STBI_NO_SIMD
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <fstream>
#include <sstream>#include "glm/glm.hpp"class MyShader {
public:unsigned int ID; MyShader(const char* vertexPath, const char* fragmentPath);void use();void setBool(const std::string& name, bool value) const;void setInt(const std::string& name, int value) const;void setFloat(const std::string& name, float value) const;void setVec4(const std::string& name, const glm::vec4& value) const;};MyShader::MyShader(const char* vertexPath, const char* fragmentPath)
{std::string vertexCode, fragmentCode;std::ifstream vShaderFile, fShaderFile;vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try{vShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);std::stringstream vShaderStream, fShaderStream;vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();vShaderFile.close();fShaderFile.close();vertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (const std::ifstream::failure e){std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();unsigned int vertexShader, fragmentShader;int success;char infoLog[512];vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vShaderCode, nullptr);glCompileShader(vertexShader);glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fShaderCode, nullptr);glCompileShader(fragmentShader);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}ID = glCreateProgram();glAttachShader(ID, vertexShader);glAttachShader(ID, fragmentShader);glLinkProgram(ID);glGetProgramiv(ID, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(ID, 512, nullptr, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);}void MyShader::use()
{glUseProgram(ID);
}void MyShader::setBool(const std::string& name, bool value) const
{glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}void MyShader::setInt(const std::string& name, int value) const
{glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}void MyShader::setFloat(const std::string& name, float value) const
{glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}void MyShader::setVec4(const std::string& name, const glm::vec4& value) const
{glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){glfwSetWindowShouldClose(window, true);}
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}int main()
{float vertices[] = {0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };unsigned int indices[] = {0, 1, 3,1, 2, 3,};const unsigned int SCR_WIDTH = 800;const unsigned int SCR_HEIGHT = 600;glfwInit();if (!glfwInit()){std::cerr << "Failed to initialize GLFW" << std::endl;return -1;}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nullptr, nullptr);if (window == nullptr){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}MyShader shader("shader/shader.vs", "shader/shader.fs");unsigned int VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glBindVertexArray(VAO); glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));glEnableVertexAttribArray(2);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);int width, height, channels;unsigned char* data = stbi_load("lena.jpg", &width, &height, &channels, 0);if (data){glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);glGenerateMipmap(GL_TEXTURE_2D);}else{std::cout << "Failed to load texture" << std::endl;}stbi_image_free(data);while (!glfwWindowShouldClose(window)){processInput(window);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);shader.use(); float timeValue = glfwGetTime();float greenValue = sin(timeValue) / 2.0f + 0.5f;glm::vec4 color = glm::vec4(0.0f, greenValue, 0.0f, 1.0f);shader.setVec4("ourColor", color);glBindVertexArray(VAO);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate();glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);glDeleteProgram(shader.ID);return 0;}