#include <glad/glad.hpp>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
int main()
{
std::cout<<"*** Init GLFW ***"<<std::endl;
const int glfw_init_value = glfwInit();
if( glfw_init_value != GLFW_TRUE ) {
std::cerr<<"Failed to Init GLFW"<<std::endl;
abort();
}
std::cout<<"*** Create window ***"<<std::endl;
const int window_width = 500;
const int window_height = 500;
const std::string title = "My Window";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(window_width, window_height, title.c_str(), /*monitor*/ nullptr, /*share*/ nullptr);
if( window==nullptr ) {
std::cerr<<"Failed to create GLFW Window"<<std::endl;
abort();
}
glfwMakeContextCurrent(window);
std::cout<<"*** Init GLAD ***"<<std::endl;
const int glad_init_value = gladLoadGL();
if( glad_init_value == 0 ) {
std::cerr<<"Failed to Init GLAD"<<std::endl;
abort();
}
std::cout<<"OpenGL information: VENDOR : "<<glGetString(GL_VENDOR)<<std::endl;
std::cout<<" RENDERDER : "<<glGetString(GL_RENDERER)<<std::endl;
std::cout<<" VERSION : "<<glGetString(GL_VERSION)<<std::endl;
std::cout<<" GLSL VERSION: "<<glGetString(GL_SHADING_LANGUAGE_VERSION)<<std::endl;
// tag::shaders[]
// ************************************************* //
// 1 - Setup Shaders //
// ************************************************* //
std::cout<<"*** Setup Shader ***"<<std::endl;
// ******************************** //
// 1.1 Define vertex and fragment shader
// ******************************** //
// Here GLSL code is hard-coded inline as strings
const char* vertex_shader_txt = " \n \
#version 330 core \n \
layout (location = 0) in vec4 position; \n \
void main() \n \
{ \n \
gl_Position = position; \n \
}";
const char* fragment_shader_txt = " \n \
#version 330 core \n \
out vec4 FragColor; \n \
void main() \n \
{ \n \
FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n \
}";
// ******************************** //
// 1.2 Create shader program
// ******************************** //
// (Warning: the following code doesn't perform error checking)
// A. Compile each shader separately
// ******************************************* //
// Create identifiant for vertex and fragment shaders
const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
// Set source from the shader
glShaderSource(vertex_shader, 1, &vertex_shader_txt, nullptr);
// Compile the current shader (here vertex shader)
glCompileShader(vertex_shader);
// Set source from the shader
glShaderSource(fragment_shader, 1, &fragment_shader_txt, nullptr);
// Compile the current shader (here fragment shader)
glCompileShader(fragment_shader);
// B. Link shaders into shader program
// ******************************************* //
// Create identifiant for shader program
const GLuint shader = glCreateProgram();
// Attach vertex and fragment shader before linking
glAttachShader(shader, vertex_shader);
glAttachShader(shader, fragment_shader);
// Perform the link of the two shaders into a program
glLinkProgram(shader);
// Compiled shaders can be safely deleted
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
// end::shaders[]
// tag::send_gpu_data[]
// ************************************************* //
// 2 - Sending data to GPU //
// ************************************************* //
std::cout<<"*** Setup Data ***"<<std::endl;
// 2.1 Setup contiguous array of floating point value
// ******************************************* //
// Here the coordinates of the vertices position
const std::vector<GLfloat> position = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// 2.2 Create VBO - Send data to GPU
// ******************************************* //
GLuint vbo = 0;
// Create an empty VBO identifiant
glGenBuffers(1, &vbo);
// Setup the current VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Send data to GPU: Fill the currently designated VBO with the buffer of data passed as parameter
glBufferData(GL_ARRAY_BUFFER, position.size()*sizeof(GLfloat), &position[0], GL_STATIC_DRAW );
// Good practice to set the current VBO to 0 (=disable VBO) after its use
glBindBuffer(GL_ARRAY_BUFFER, 0);
// 2.3 Create VAO - Relation between VBO organization and input variables of shaders
// ******************************************* //
GLuint vao = 0;
// Create an empty VBO identifiant
glGenVertexArrays(1,&vao);
// Setup the current VAO
glBindVertexArray(vao);
// Indicate the VBO we will refer to in the next lines
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Activate the use of the variable at index layout=0 in the shader
glEnableVertexAttribArray( 0 );
// Define the memory model of this VBO: here contiguous triplet of floating values (x y z) at index layout=0 in the shader
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, nullptr );
// As a good practice, disable VBO and VAO after their use
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// end::send_gpu_data[]
// ******************************** //
// Main loop
// ******************************** //
std::cout<<"*** Start GLFW loop ***"<<std::endl;
while( !glfwWindowShouldClose(window) ) {
// tag::displaying_data[]
// ************************************************* //
// 3 - Displaying Data //
// ************************************************* //
glUseProgram(shader); // Activate shader program
glBindVertexArray(vao); // Activate attributes for the drawing
glDrawArrays(GL_TRIANGLES, 0, 3); // Draw 3 vertices
glBindVertexArray(0);
glUseProgram(0);
// end::displaying_data[]
glfwSwapBuffers(window);
glfwPollEvents();
}
std::cout<<"*** Terminate GLFW loop ***"<<std::endl;
glfwTerminate();
return 0;
}
>