text: #include <glad/glad.h>
  #include <GLFW/glfw3.h>
  #include <iostream>
  
  void framebuffer_size_callback(GLFWwindow* window,int width,int height);
  void processInput(GLFWwindow* window);
  
  const unsigned int SRC_WIDTH = 800;
  const unsigned int SRC_HEIGHT = 600;
  
  const char* vertexShaderSource = 
  	"#version 330 core\n"
  	"layout (location = 0) in vec3 aPos;\n"
  	"void main(){\n"
  	"	gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);\n"
  	"}\n";
  
  const char* fragmentShaderSource = 
  	"#version 330 core\n"
  	"out vec4 FragColor;\n"
  	"void main(){\n"
  	"	FragColor = vec4(0.0f,1.0f,0.0f,1.0f);\n"
  	"}\n";
  
  const char* fragmentShaderSource2 = 
  	"#version 330 core\n"
  	"out vec4 FragColor;\n"
  	"void main(){\n"
  	"	FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n"
  	"}\n";
  
  int main(){
  	glfwInit();
  	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
  	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
  	glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
  
  	GLFWwindow* window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT,"LearnOpenGL",NULL,NULL);
  	if(window == NULL){
  		std::cout << "Failed to create GLFW window\n" << std::endl;
  		glfwTerminate();
  		return -1;
  	}
  	glfwMakeContextCurrent(window);
  	glfwSetFramebufferSizeCallback(window,framebuffer_size_callback);
  	
  	if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
  		std::cout << "Failed to initialize GLAD\n" << std::endl;
  		return -1;
  	}
  	 
  	//build and compile shader program
  	//vertex shader
  	int vertexShader = glCreateShader(GL_VERTEX_SHADER);
  	glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
  	glCompileShader(vertexShader);
  	//check for shader compile errors
  	int success;
  	char infoLog[512];
  	glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success);
  	if(!success){
  		glGetShaderInfoLog(vertexShader,512,NULL,infoLog);
  		std::cout << "error::shader::vertex::compile action failed\n" << infoLog << std::endl;
  	}
  	//fragment shader
  	int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  	glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
  	glCompileShader(fragmentShader);
  	//check for shader compile error
  	glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&success);
  	if(!success){
  		glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);
  		std::cout << "error::shader::fragment::copile action faied\n" << infoLog << std::endl;
  	}
  	//link shaders
  	int shaderProgram = glCreateProgram();
  	glAttachShader(shaderProgram,vertexShader);
  	glAttachShader(shaderProgram,fragmentShader);
  	glLinkProgram(shaderProgram);
  	//check for link errors
  	glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
  	if(!success){
  		glGetProgramInfoLog(shaderProgram,512,NULL,infoLog);
  		std::cout << "error::shader::program::link failed\n" << infoLog << std::endl;
  	}
  
  	int fragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER);
  	int shaderProgram2 = glCreateProgram();
  	glShaderSource(fragmentShader2,1,&fragmentShaderSource2,NULL);
  	glCompileShader(fragmentShader2);
  	glAttachShader(shaderProgram2,vertexShader);
  	glAttachShader(shaderProgram2,fragmentShader2);
  	glLinkProgram(shaderProgram2);
  	
  	glDeleteShader(vertexShader);
  	glDeleteShader(fragmentShader);
  	glDeleteShader(fragmentShader2);
  
  	//set up vertex data and configure vertex attributes
  
     	float firstTriangle[] = {
     	     -0.9f, -0.5f, 0.0f,  // left
     	     -0.0f, -0.5f, 0.0f,  // right
     	     -0.45f, 0.5f, 0.0f,  // top
     	 };
       	 float secondTriangle[] = {
       	     0.0f, -0.5f, 0.0f,  // left
       	     0.9f, -0.5f, 0.0f,  // right
       	     0.45f, 0.5f, 0.0f   // top
       	 };	
  
  	unsigned int VBO[2],VAO[2];
  	glGenVertexArrays(2,VAO);
  	glGenBuffers(2,VBO);
  	
  	//bind the vertex array object
  	glBindVertexArray(VAO[0]);
  	glBindBuffer(GL_ARRAY_BUFFER,VBO[0]);
  	glBufferData(GL_ARRAY_BUFFER,sizeof(firstTriangle),firstTriangle,GL_STATIC_DRAW);
  	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);
  	glEnableVertexAttribArray(0);
  	glBindBuffer(GL_ARRAY_BUFFER,0);
  	glBindVertexArray(0);
  
  	//bind the vertex array object
  	glBindVertexArray(VAO[1]);
  	glBindBuffer(GL_ARRAY_BUFFER,VBO[1]);
  	glBufferData(GL_ARRAY_BUFFER,sizeof(secondTriangle),secondTriangle,GL_STATIC_DRAW);
  	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0);
  	glEnableVertexAttribArray(0);
  	glBindBuffer(GL_ARRAY_BUFFER,0);
  	glBindVertexArray(0);
  
  	while(!glfwWindowShouldClose(window)){
  		//input
  		processInput(window);
  		//render
  		glClearColor(0.2f,0.3f,0.3f,1.0f);
  		glClear(GL_COLOR_BUFFER_BIT);
  
  		//draw triangle
  		glUseProgram(shaderProgram);
  		glBindVertexArray(VAO[0]);
  		glDrawArrays(GL_TRIANGLES,0,3);
  
  		glUseProgram(shaderProgram2);
  		glBindVertexArray(VAO[1]);
  		glDrawArrays(GL_TRIANGLES,0,3);
  
  		glfwSwapBuffers(window);
  		glfwPollEvents();
  	}
  	
  	glDeleteVertexArrays(2,VAO);
  	glDeleteBuffers(2,VBO);
  	glDeleteProgram(shaderProgram);
  
  	glfwTerminate();
  	return 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);
  }
  
  
  
  	
  
  
  
  