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