Skip to content

Instantly share code, notes, and snippets.

@mortennobel
Created November 6, 2014 22:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mortennobel/0e2d92e232f3d3c14e40 to your computer and use it in GitHub Desktop.
Save mortennobel/0e2d92e232f3d3c14e40 to your computer and use it in GitHub Desktop.
Hello Modern OpenGL World (OSX, OGL3.2, GLUT, C++11)
//
// 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