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