Created
January 11, 2016 19:35
-
-
Save jokoon/2977c5011c80084b36af to your computer and use it in GitHub Desktop.
This file contains 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() | |
{ | |
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl; | |
// 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); | |
// 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 | |
glViewport(0, 0, WIDTH, HEIGHT); | |
// Build and compile our shader program | |
// Vertex shader | |
GLint 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 | |
GLint 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 | |
GLint 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); | |
#define INDEXEDfds | |
// Set up vertex data (and buffer(s)) and attribute pointers | |
#ifndef INDEXED | |
GLfloat vertices[] = { | |
// First triangle | |
0.5f, 0.5f, // Top Right | |
0.5f, -0.5f, // Bottom Right | |
-0.5f, 0.5f, // Top Left | |
// Second triangle | |
0.5f, -0.5f, // Bottom Right | |
-0.5f, -0.5f, // Bottom Left | |
-0.5f, 0.5f // Top Left | |
}; | |
#else | |
GLfloat vertices[] = { | |
0.5f, 0.5f, 0.0f, // Top Right | |
0.5f, -0.5f, 0.0f, // Bottom Right | |
-0.5f, -0.5f, 0.0f, // Bottom Left | |
-0.5f, 0.5f, 0.0f // Top Left | |
}; | |
#endif | |
GLuint indices[] = { // Note that we start from 0! | |
0, 1, 3, // First Triangle | |
1, 2, 3 // Second Triangle | |
}; | |
GLuint VBO, VAO, EBO; | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
#ifdef INDEXED | |
glGenBuffers(1, &EBO); | |
#endif | |
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
#ifdef INDEXED | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); | |
#endif | |
glVertexAttribPointer(0, 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), remember: do NOT unbind the EBO, keep it bound to this VAO | |
// Uncommenting this call will result in wireframe polygons. | |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | |
// 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); | |
#ifndef INDEXED | |
glDrawArrays(GL_TRIANGLES, 0, 6); | |
#else | |
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); | |
#endif | |
glBindVertexArray(0); | |
// Swap the screen buffers | |
glfwSwapBuffers(window); | |
} | |
// Properly de-allocate all resources once they've outlived their purpose | |
glDeleteVertexArrays(1, &VAO); | |
glDeleteBuffers(1, &VBO); | |
glDeleteBuffers(1, &EBO); | |
// 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_ESCAPE && 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