text: #include <iostream>
  #include <string>
  #include <glad/glad.h>
  #include <GLFW/glfw3.h>
  
  void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
  	glViewport(0, 0, width, height);
  }
  
  void processInput(GLFWwindow* window) {
  	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
  		glfwSetWindowShouldClose(window, true);
  	}
  }
  
  int main() {
  	if (!glfwInit()) {
  		std::cerr << "Can't start glfw :(\n";
  		return -1;
  	}
  	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  
  	GLFWwindow* window = glfwCreateWindow(800, 600, ":)", nullptr, nullptr);
  	if (window == nullptr) {
  		std::cerr << "Can't create window\n";
  		glfwTerminate();
  		return -1;
  	}
  
  	glfwMakeContextCurrent(window);
  	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
  		std::cerr << "Can't load GLAD\n";
  		return -1;
  	}
  
  	int ok;
  	char infoLog[512];
  
  	const char* vertexShaderSrc = R"glsl(#version 330 core
  layout (location = 0) in vec3 vertPos;
  void main() {
  	gl_Position = vec4(vertPos, 1.0);
  })glsl";
  	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
  	glShaderSource(vertexShader, 1, &vertexShaderSrc, nullptr);
  	glCompileShader(vertexShader);
  	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &ok);
  	if (!ok) {
  		glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
  		std::cerr << "Error compiling vertex shader\n"
  			<< infoLog << std::endl;
  	}
  
  	const char* fragmentShaderSrc = R"glsl(#version 330 core
  out vec4 color;
  void main() {
  	color = vec4(1.0, 0.5, 0.2, 1.0);
  })glsl";
  	unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  	glShaderSource(fragmentShader, 1, &fragmentShaderSrc, nullptr);
  	glCompileShader(fragmentShader);
  	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &ok);
  	if (!ok) {
  		glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
  		std::cerr << "Error compiling vertex shader\n"
  			<< infoLog << std::endl;
  	}
  
  	unsigned int program = glCreateProgram();
  	glAttachShader(program, vertexShader);
  	glAttachShader(program, fragmentShader);
  	glLinkProgram(program);
  	glGetProgramiv(program, GL_LINK_STATUS, &ok);
  	if (!ok) {
  		glGetProgramInfoLog(program, 512, nullptr, infoLog);
  		std::cerr << "Can't link program\n"
  			<< infoLog << std::endl;
  	}
  	glDeleteShader(vertexShader);
  	glDeleteShader(fragmentShader);
  
  	float vertices[] = { -0.5, -0.5,  0.0,
  		0.5, -0.5,  0.0,
  		0.0,  0.5,  0.0 };
  	unsigned int vbo;
  	glGenBuffers(1, &vbo);
  	glBindBuffer(GL_ARRAY_BUFFER, vbo);
  	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  
  	unsigned int vao;
  	glGenVertexArrays(1, &vao);
  	glBindVertexArray(vao);
  
  	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
  	glEnableVertexAttribArray(0);
  
  	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  	while (!glfwWindowShouldClose(window)) {
  		processInput(window);
  		glClearColor(.1, .2, .3, 1.0);
  		glClear(GL_COLOR_BUFFER_BIT);
  
  		glUseProgram(program);
  		glBindVertexArray(vao);
  		glDrawArrays(GL_TRIANGLES, 0, 3);
  
  		glfwSwapBuffers(window);
  		glfwPollEvents();
  	}
  
  	glfwTerminate();
  	return 0;
  }
  
  /* vim: set tabstop=2:softtabstop=2:shiftwidth=2:noexpandtab */
  
  