Skip to content

Instantly share code, notes, and snippets.

@mortennobel
Created March 14, 2017 13:32
Show Gist options
  • Save mortennobel/b10a3220e1431b565011424d666adf42 to your computer and use it in GitHub Desktop.
Save mortennobel/b10a3220e1431b565011424d666adf42 to your computer and use it in GitHub Desktop.
Single file geometryshader
#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[48] = {
-1, 0, 0.0, 1.0 , 0.0, 1.0, 0.0, 1.0 ,
-1, -1, 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0 ,
0, 0, 0.0, 1.0 , 0.0, 0.0, 1.0, 1.0 ,
0, -1, 0.0, 1.0 , 1.0, 1.0, 1.0, 1.0 ,
1, 0, 0.0, 1.0 , 1.0, 1.0, 1.0, 1.0 ,
1, -1, 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, 48 * 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* gShader, const char* fShader, const char* outputAttributeName) {
struct Shader {
GLenum type;
const char* source;
} shaders[3] = {
{ GL_VERTEX_SHADER, vShader },
{ GL_GEOMETRY_SHADER, gShader},
{ GL_FRAGMENT_SHADER, fShader }
};
GLuint program = glCreateProgram();
for ( int i = 0; i < 3; ++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;
void main (void)
{
gl_Position = position;
})";
const char * frag = R"(#version 150
in vec4 fColor;
out vec4 fragColor;
void main(void)
{
fragColor = fColor;
})";
// Geometry shader
const GLchar* geom = R"glsl(
#version 150
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
out vec4 fColor;
const float PI = 3.1415926;
void main()
{
for (int i=0;i<3;i++){
gl_Position = gl_in[i].gl_Position ;
if (i==0){
fColor = vec4(1.0,0.0,0.0,1.0);
} else if (i==1){
fColor = vec4(0.0,1.0,0.0,1.0);
} else {
fColor = vec4(0.0,0.0,1.0,1.0);
}
EmitVertex();
}
EndPrimitive();
}
)glsl";
shaderProgram = initShader(vert, geom, 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_STRIP, 0, 6);
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