Created
November 6, 2014 22:36
-
-
Save mortennobel/0e2d92e232f3d3c14e40 to your computer and use it in GitHub Desktop.
Hello Modern OpenGL World (OSX, OGL3.2, GLUT, C++11)
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
// | |
// Single file OpenGL example | |
// | |
// Created by Morten Nobel-Jørgensen on 06/11/14. | |
// Copyright (c) 2014 morten. All rights reserved. | |
// | |
#include <OpenGL/gl3.h> | |
#include <GLUT/glut.h> | |
#include <string> | |
#include <iostream> | |
#include <cmath> | |
using namespace std; | |
int WINDOW_WIDTH = 800; | |
int WINDOW_HEIGHT = 800; | |
string vertexShader = R"(#version 150 | |
uniform vec2 p; | |
in vec4 position; | |
in vec4 color; | |
out vec4 colorV; | |
void main (void) | |
{ | |
colorV = color; | |
gl_Position = vec4(p, 0.0, 0.0) + position; | |
} | |
)"; | |
string fragmentShader = R"(#version 150 | |
in vec4 colorV; | |
out vec4 fragColor; | |
void main(void) | |
{ | |
fragColor = colorV; | |
} | |
)"; | |
GLuint shaderProgram; | |
GLuint positionUniform; | |
GLuint colorAttribute, positionAttribute; | |
GLuint vertexArrayObject, | |
vertexBuffer; | |
struct vec4 | |
{ | |
float x; | |
float y; | |
float z; | |
float w; | |
}; | |
typedef struct | |
{ | |
vec4 position; | |
vec4 color; | |
} Vertex; | |
void loadShader(); | |
void display(); | |
void loadBufferData(){ | |
Vertex vertexData[4] = { | |
{ vec4{-0.5f, -0.5f, 0.0f, 1.0f }, vec4{ 1.0f, 0.0f, 0.0f, 1.0f } }, | |
{ vec4{-0.5, 0.5, 0.0, 1.0 }, vec4{ 0.0, 1.0, 0.0, 1.0 } }, | |
{ vec4{ 0.5, 0.5, 0.0, 1.0 }, vec4{ 0.0, 0.0, 1.0, 1.0 } }, | |
{ vec4{ 0.5, -0.5, 0.0, 1.0 }, vec4{ 1.0, 1.0, 1.0, 1.0 } } | |
}; | |
glGenVertexArrays(1, &vertexArrayObject); | |
glBindVertexArray(vertexArrayObject); | |
glGenBuffers(1, &vertexBuffer); | |
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); | |
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), vertexData, GL_STATIC_DRAW); | |
glEnableVertexAttribArray(positionAttribute); | |
glEnableVertexAttribArray(colorAttribute); | |
glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0); | |
glVertexAttribPointer(colorAttribute , 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec4)); | |
} | |
GLuint initShader(string vertexShader, string fragmentShader){ | |
struct Shader { | |
GLenum type; | |
const GLchar* source; | |
} shaders[2] = { | |
{ GL_VERTEX_SHADER, vertexShader.c_str() }, | |
{ GL_FRAGMENT_SHADER, fragmentShader.c_str() } | |
}; | |
GLuint program = glCreateProgram(); | |
for ( int i = 0; i < 2; ++i ) { | |
Shader& s = shaders[i]; | |
GLuint shader = glCreateShader( s.type ); | |
glShaderSource( shader, 1, (const GLchar**) &s.source, NULL ); | |
glCompileShader( shader ); | |
GLint compiled; | |
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); | |
if ( !compiled ) { | |
std::cerr << "Shader compile error" << std::endl; | |
exit( EXIT_FAILURE ); | |
} | |
glAttachShader( program, shader ); | |
} | |
glLinkProgram(program); | |
GLint linked; | |
glGetProgramiv( program, GL_LINK_STATUS, &linked ); | |
if ( !linked ) { | |
std::cerr << "Shader link error" << std::endl; | |
exit( EXIT_FAILURE ); | |
} | |
glUseProgram(program); | |
return program; | |
} | |
void loadShader(){ | |
shaderProgram = initShader(vertexShader, fragmentShader); | |
positionUniform = glGetUniformLocation(shaderProgram, "p"); | |
if (positionUniform < 0) { | |
cerr << "Shader did not contain the 'p' uniform."<<endl; | |
} | |
colorAttribute = glGetAttribLocation(shaderProgram, "color"); | |
if (colorAttribute < 0) { | |
cerr << "Shader did not contain the 'color' attribute." << endl; | |
} | |
positionAttribute = glGetAttribLocation(shaderProgram, "position"); | |
if (positionAttribute < 0) { | |
cerr << "Shader did not contain the 'position' attribute." << endl; | |
} | |
} | |
void display() { | |
glClearColor(0.0, 0.0, 0.0, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); | |
const float timeScale = 0.008f; | |
glUseProgram(shaderProgram); | |
GLfloat timeValue = glutGet(GLUT_ELAPSED_TIME)*timeScale; | |
float p[2]{ 0.5f * sinf(timeValue), 0.5f * cosf(timeValue) }; | |
glUniform2fv(positionUniform, 1, (const GLfloat *)&p); | |
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
glutSwapBuffers(); | |
} | |
void reshape(int W, int H) { | |
WINDOW_WIDTH = W; | |
WINDOW_HEIGHT = H; | |
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); | |
} | |
void animate() { | |
glutPostRedisplay(); | |
} | |
void visible(int vis) { | |
if (vis == GLUT_VISIBLE) | |
glutIdleFunc(animate); | |
else | |
glutIdleFunc(0); | |
} | |
int main(int argc, char* argv[]) { | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_3_2_CORE_PROFILE); | |
glutCreateWindow("OpenGL"); | |
glutDisplayFunc(display); | |
glutReshapeFunc(reshape); | |
glutVisibilityFunc(visible); | |
glutIdleFunc(animate); | |
glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT); | |
loadShader(); | |
loadBufferData(); | |
glutMainLoop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment