Skip to content

Instantly share code, notes, and snippets.

@mortennobel
Last active November 7, 2016 11:46
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/2e6d02d9729fa4e4a19496a415e92b4e to your computer and use it in GitHub Desktop.
Save mortennobel/2e6d02d9729fa4e4a19496a415e92b4e to your computer and use it in GitHub Desktop.
OpenGL 3.x example in a single file (SDL2.x)
#include "SDL.h"
// OSX only - change on other platforms
#include <OpenGL/gl3.h>
#include <stdlib.h> //rand()
#include <iostream>
#include <string>
static bool quitting = false;
static SDL_Window *window = NULL;
static SDL_GLContext gl_context;
GLuint vertexBuffer, vertexArrayObject, shaderProgram;
GLint positionAttribute, colorAttribute;
void loadBufferData(){
// vertex position, color
float vertexData[32] = {
-0.5, -0.5, 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0 ,
-0.5, 0.5, 0.0, 1.0 , 0.0, 1.0, 0.0, 1.0 ,
0.5, 0.5, 0.0, 1.0 , 0.0, 0.0, 1.0, 1.0 ,
0.5, -0.5, 0.0, 1.0 , 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, 32 * sizeof(float), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(positionAttribute);
glEnableVertexAttribArray(colorAttribute);
int vertexSize =sizeof(float)*8;
glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE,vertexSize , (const GLvoid *)0);
glVertexAttribPointer(colorAttribute , 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid *)(sizeof(float)*4));
}
GLuint initShader(const char* vShader, const char* fShader, const char* outputAttributeName) {
struct Shader {
GLenum type;
const char* source;
} shaders[2] = {
{ GL_VERTEX_SHADER, vShader },
{ GL_FRAGMENT_SHADER, fShader }
};
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 << " failed to compile:" << std::endl;
GLint logSize;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
char* logMsg = new char[logSize];
glGetShaderInfoLog( shader, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
glAttachShader( program, shader );
}
/* Link output */
glBindFragDataLocation(program, 0, outputAttributeName);
/* link and error check */
glLinkProgram(program);
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
std::cerr << "Shader program failed to link" << std::endl;
GLint logSize;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog( program, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
/* use program object */
glUseProgram(program);
return program;
}
void loadShader(){
const char * vert = R"(#version 150
in vec4 position;
in vec4 color;
out vec4 colorV;
void main (void)
{
colorV = color;
gl_Position = position;
})";
const char * frag = R"(#version 150
in vec4 colorV;
out vec4 fragColor;
void main(void)
{
fragColor = colorV;
})";
shaderProgram = initShader(vert, frag, "fragColor");
colorAttribute = glGetAttribLocation(shaderProgram, "color");
if (colorAttribute < 0) {
std::cerr << "Shader did not contain the 'color' attribute." << std::endl;
}
positionAttribute = glGetAttribLocation(shaderProgram, "position");
if (positionAttribute < 0) {
std::cerr << "Shader did not contain the 'position' attribute." << std::endl;
}
}
void setup() {
std::cout << "OpenGL version "<<glGetString(GL_VERSION)<<std::endl;
loadShader();
loadBufferData();
glEnable(GL_DEPTH_TEST);
}
void render() {
SDL_GL_MakeCurrent(window, gl_context);
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
glUseProgram(shaderProgram);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
SDL_GL_SwapWindow(window);
}
int main(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS) != 0) {
SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
return 1;
}
// Use a core profile setup.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
window = SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 512, 512, SDL_WINDOW_OPENGL);
gl_context = SDL_GL_CreateContext(window);
setup();
while(!quitting) {
SDL_Event event;
while( SDL_PollEvent(&event) ) {
if(event.type == SDL_QUIT) {
quitting = true;
}
}
render();
SDL_Delay(2);
}
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
exit(0);
} //main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment