Created
October 12, 2016 18:44
-
-
Save shkesar/f342b7016e24611ddaa3c63606790e25 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
// GLEW | |
#define GLEW_STATIC | |
#include <GL/glew.h> | |
// GLFW | |
#include <GLFW/glfw3.h> | |
// Function prototypes | |
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); | |
// Window dimensions | |
const GLuint WIDTH = 800, HEIGHT = 600; | |
// Shaders | |
const GLchar* vertexShaderSource = "#version 330 core\n" | |
"layout (location = 0) in vec3 position;\n" | |
"void main()\n" | |
"{\n" | |
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n" | |
"}\0"; | |
const GLchar* fragmentShaderSource = "#version 330 core\n" | |
"out vec4 color;\n" | |
"void main()\n" | |
"{\n" | |
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" | |
"}\n\0"; | |
// The MAIN function, from here we start the application and run the game loop | |
int main() | |
{ | |
// Init GLFW | |
glfwInit(); | |
// Set all the required options for GLFW | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
// Create a GLFWwindow object that we can use for GLFW's functions | |
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); | |
glfwMakeContextCurrent(window); | |
// Set the required callback functions | |
glfwSetKeyCallback(window, key_callback); | |
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions | |
glewExperimental = GL_TRUE; | |
// Initialize GLEW to setup the OpenGL Function pointers | |
glewInit(); | |
// Define the viewport dimensions | |
int width, height; | |
glfwGetFramebufferSize(window, &width, &height); | |
glViewport(0, 0, width, height); | |
// Build and compile our shader program | |
// Vertex shader | |
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | |
glCompileShader(vertexShader); | |
// Check for compile time errors | |
GLint success; | |
GLchar infoLog[512]; | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; | |
} | |
// Fragment shader | |
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | |
glCompileShader(fragmentShader); | |
// Check for compile time errors | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; | |
} | |
// Link shaders | |
GLuint shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
glLinkProgram(shaderProgram); | |
// Check for linking errors | |
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
if (!success) { | |
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
// Set up vertex data (and buffer(s)) and attribute pointers | |
GLfloat vertices1[] = { | |
-0.75f, -0.25f, 0.0f, // Left | |
-0.25f, -0.25f, 0.0f, // Right | |
-0.5f, 0.25f, 0.0f // Top | |
}; | |
GLfloat vertices2[] = { | |
0.25f, -0.25f, 0.0f, // Left | |
0.75f, -0.25f, 0.0f, // Right | |
0.5f, 0.25f, 0.0f // Top | |
}; | |
GLuint VBO1, VBO2, VAO; | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO1); | |
glGenBuffers(1, &VBO2); | |
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO1); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); | |
glEnableVertexAttribArray(0); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO2); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW); | |
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); | |
glEnableVertexAttribArray(0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind | |
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs) | |
// Game loop | |
while (!glfwWindowShouldClose(window)) | |
{ | |
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions | |
glfwPollEvents(); | |
// Render | |
// Clear the colorbuffer | |
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
// Draw our first triangle | |
glUseProgram(shaderProgram); | |
glBindVertexArray(VAO); | |
glDrawArrays(GL_TRIANGLES, 0, 3); | |
glBindVertexArray(0); | |
// Swap the screen buffers | |
glfwSwapBuffers(window); | |
} | |
// Properly de-allocate all resources once they've outlived their purpose | |
glDeleteVertexArrays(1, &VAO); | |
glDeleteBuffers(1, &VBO1); | |
glDeleteBuffers(1, &VBO2); | |
// Terminate GLFW, clearing any resources allocated by GLFW. | |
glfwTerminate(); | |
return 0; | |
} | |
// Is called whenever a key is pressed/released via GLFW | |
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) | |
{ | |
if (key == GLFW_KEY_Q && action == GLFW_PRESS) | |
glfwSetWindowShouldClose(window, GL_TRUE); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment