# 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 ; }