Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

http://www.reddit.com/r/opengl/comments/179xcl/glsl_shader_w

By: a guest on Jan 25th, 2013  |  syntax: C++  |  size: 11.71 KB  |  views: 68  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // g++ -std=c++11 main.cpp -lglut -lGLEW
  2.  
  3. #include <GL/glew.h>
  4. #include <GL/glut.h>
  5.  
  6. /* Using the standard output for fprintf */
  7. #include <iostream>
  8. #include <functional>
  9. #include <memory>
  10. #include <vector>
  11. #include <stdexcept>
  12.  
  13. #include <map>
  14. #include <vector>
  15. #include <cmath>
  16. #include <algorithm>
  17. #include <iterator>
  18. #include <time.h>
  19.  
  20. using namespace std;
  21.  
  22. GLint attribute_coord3d, attribute_v_color;
  23. GLuint vbo_triangle, vbo_triangle_colors;
  24. GLuint program;
  25. const int NUM_ITERATIONS = 5;
  26. const int NUM_TRIANGLES = pow( 4.0, NUM_ITERATIONS );
  27. int modelDrawn = 0;
  28.  
  29.  
  30. struct vec3
  31. {
  32.     float x;
  33.     float y;
  34.     float z;
  35.  
  36.     vec3( float x1, float y1, float z1 ) : x( x1 ), y( y1 ), z( z1 )
  37.     {
  38.     }
  39.  
  40.     vec3( ) : x( 0 ), y( 0 ), z( 0 )
  41.     {
  42.     }
  43.  
  44.     vec3& operator+=(const vec3 & other )
  45.     {
  46.         x += other.x;
  47.         y += other.y;
  48.         z += other.z;
  49.     }
  50.  
  51.     vec3 operator/=(const float)
  52.     {
  53.  
  54.     }
  55.  
  56.     vec3 operator+(const vec3 & other ) const
  57.     {
  58.         return vec3( x + other.x, y + other.y, z + other.z );
  59.     }
  60.  
  61.     vec3 operator/(const float &denom ) const
  62.     {
  63.         return vec3( x / denom, y / denom, z / denom );
  64.     }
  65.  
  66.     vec3 operator*(const float mult)
  67.     {
  68.         return vec3( x*mult, y*mult, z * mult );
  69.     }
  70.  
  71.     bool operator<(const vec3 & n ) const
  72.     {
  73.         if( x != n.x )
  74.             return x < n.x;
  75.         else if( y != n.y )
  76.             return y < n.y;
  77.         else if( z != n.z )
  78.             return z < n.z;
  79.         return length( ) < n.length( );
  80.     }
  81.  
  82.     bool operator==(const vec3 & n ) const
  83.     {
  84.         return x == n.x && y == n.y && z == n.z;
  85.     }
  86.  
  87.     float length( ) const
  88.     {
  89.         return sqrt( pow( x, 2 ) + pow( y, 2 ) + pow( z, 2 ) );
  90.     }
  91.  
  92.     void Print( ) const
  93.     {
  94.         std::cout << "(" << x << "," << y << "," << z << ")" << std::endl;
  95.     }
  96. };
  97.  
  98. //container for gasket verts
  99. std::vector<vec3> triangle_vertices;
  100. std::vector<vec3> triangle_colors_vec;
  101.  
  102. float getRandom( float max, float min )
  103. {
  104.     return ((float(rand( ) ) / float(RAND_MAX ) ) * ( max - ( min ) ) ) + ( min );
  105. }
  106.  
  107. float getVectorDistance( vec3 a, vec3 b )
  108. {
  109.     return sqrt( pow( ( a.x - b.x ), 2 ) + pow( ( a.y - b.y ), 2 ) + pow( ( a.z - b.z ), 2 ) );
  110. }
  111.  
  112. vec3 randVector( );
  113.  
  114.  
  115. struct Triangle
  116. {
  117.     vec3 a;
  118.     vec3 b;
  119.     vec3 c;
  120.  
  121.     Triangle( vec3 a1, vec3 b1, vec3 c1 ) : a( a1 ), b( b1 ), c( c1 )
  122.     {
  123.     }
  124. };
  125.  
  126. vec3 getMidpoint( const vec3& a, const vec3& b )
  127. {
  128.     const float SCALE = 0.1;
  129.  
  130.     static std::map<std::pair<vec3, vec3>, vec3> memo;
  131.  
  132.  
  133.     auto foundResult = memo.find( std::make_pair( a, b ) );
  134.     if( foundResult != memo.end( ) )
  135.     {
  136.         return foundResult->second;
  137.     }
  138.  
  139.     auto result = ( a + b ) / 2;
  140.     auto variance = 0.1 * getVectorDistance( a, b );
  141.     auto randX = getRandom( result.x + variance, result.x - variance );
  142.     auto randY = getRandom( result.y + variance, result.y - variance );
  143.     auto randZ = getRandom( result.z + variance, result.z - variance );
  144.  
  145.     result = vec3( randX, randY, randZ );
  146.     memo.insert( std::make_pair( std::make_pair( a, b ), result ) );
  147.     memo.insert( std::make_pair( std::make_pair( b, a ), result ) );
  148.     return result;
  149.  
  150. }
  151.  
  152. void makeGasket( Triangle t, int count )
  153. {
  154.     if( count > 0 )
  155.     {
  156.         auto d = getMidpoint( t.a, t.b );
  157.         auto e = getMidpoint( t.b, t.c );
  158.         auto f = getMidpoint( t.a, t.c );
  159.  
  160.  
  161.         makeGasket( Triangle( t.a, d, f ), count - 1 );
  162.         makeGasket( Triangle( d, t.b, e ), count - 1 );
  163.         makeGasket( Triangle( f, d, e ), count - 1 );
  164.         makeGasket( Triangle( f, e, t.c ), count - 1 );
  165.     }
  166.     else
  167.     {
  168.         triangle_vertices.push_back( t.a );
  169.         triangle_vertices.push_back( t.b );
  170.         triangle_vertices.push_back( t.c );
  171.  
  172.     }
  173.  
  174. }
  175.  
  176. void createColors( )
  177. {
  178.     for( int i = 0; i < triangle_vertices.size( ); i++ )
  179.     {
  180.         float random = getRandom( 0.5, 1.0 );
  181.         static std::map<vec3, float> randColor;
  182.         auto foundResult = randColor.find( triangle_vertices[i] );
  183.         if( foundResult != randColor.end( ) )
  184.         {
  185.             random = foundResult->second;
  186.         }
  187.         else
  188.             randColor.insert( std::make_pair( triangle_vertices[i], random ) );
  189.  
  190.         triangle_colors_vec.push_back( vec3( random, random, random ) );
  191.     }
  192.  
  193. }
  194.  
  195. vec3 triangle_verts[15000];
  196. vec3 triangle_colors[15000];
  197.  
  198. void onDisplay( )
  199. {
  200.     srand( time( NULL ) );
  201.     /* Clear the background as white */
  202.     glClearColor( 0.0, 0.0, 0.0, 0.0 );
  203.     glEnable( GL_DEPTH_TEST );
  204.     glDepthFunc( GL_LESS );
  205.     glCullFace( GL_FRONT );
  206.     glEnable( GL_CULL_FACE );
  207.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  208.     /* Tell OpenGL which program to use*/
  209.     glUseProgram( program );
  210.  
  211.     if( modelDrawn == 0 )
  212.     {
  213.         modelDrawn = 1;
  214.         vec3 verts[] ={
  215.             vec3( 0.0, 1.0, 0.0 ),
  216.             vec3( 0.943, -0.333, 0.0 ),
  217.             vec3( -0.471, -0.333, 0.816 ),
  218.             vec3( -0.471, -0.333, -0.816 )
  219.         };
  220.  
  221.         Triangle initialTri = Triangle(
  222.             verts[0],
  223.             verts[2],
  224.             verts[1]
  225.             );
  226.         Triangle initialTri2 = Triangle(
  227.             verts[0],
  228.             verts[1],
  229.             verts[3]
  230.             );
  231.         Triangle initialTri3 = Triangle(
  232.             verts[0],
  233.             verts[3],
  234.             verts[2]
  235.             );
  236.         Triangle initialTri4 = Triangle(
  237.             verts[1],
  238.             verts[2],
  239.             verts[3]
  240.             );
  241.  
  242.         makeGasket( initialTri, NUM_ITERATIONS );
  243.         makeGasket( initialTri2, NUM_ITERATIONS );
  244.         makeGasket( initialTri3, NUM_ITERATIONS );
  245.         makeGasket( initialTri4, NUM_ITERATIONS );
  246.  
  247.         std::copy( triangle_vertices.begin( ), triangle_vertices.end( ), triangle_verts );
  248.  
  249.         createColors( );
  250.  
  251.         std::copy( triangle_colors_vec.begin( ), triangle_colors_vec.end( ), triangle_colors );
  252.     }
  253.  
  254.     /* Setup vertex data */
  255.     glBindBuffer( GL_ARRAY_BUFFER, vbo_triangle );
  256.     glBufferData( GL_ARRAY_BUFFER, sizeof (triangle_verts ), triangle_verts, GL_STATIC_DRAW );
  257.  
  258.     auto attribute_coord3d = glGetAttribLocation( program, "coord3d" );
  259.     glEnableVertexAttribArray( attribute_coord3d );
  260.  
  261.     /* Describe our vertices array to OpenGL (it can't guess its format automatically) */
  262.     glVertexAttribPointer(
  263.         attribute_coord3d, // attribute
  264.         3, // number of elements per vertex, here (x,y,z)
  265.         GL_FLOAT, // the type of each element
  266.         GL_FALSE, // take our values as-is
  267.         0, // no extra data between each position
  268.         0 // vec3er to the C array
  269.         );
  270.  
  271.     /* Push each element in buffer_vertices to the vertex shader */
  272.     glBindBuffer( GL_ARRAY_BUFFER, vbo_triangle_colors );
  273.     glBufferData( GL_ARRAY_BUFFER, sizeof (triangle_colors ), triangle_colors, GL_STATIC_DRAW );
  274.  
  275.     auto attribute_v_color = glGetAttribLocation( program, "v_color" );
  276.     glEnableVertexAttribArray( attribute_v_color );
  277.  
  278.     glVertexAttribPointer(
  279.         attribute_v_color, // attribute
  280.         3, // number of elements per vertex, here (r,g,b)
  281.         GL_FLOAT, // the type of each element
  282.         GL_FALSE, // take our values as-is
  283.         0, // no extra data between each position
  284.         0 // offset of first element
  285.         );
  286.  
  287.     glDrawArrays( GL_TRIANGLES, 0, NUM_TRIANGLES * 3 * 4 );
  288.     glDisableVertexAttribArray( attribute_coord3d );
  289.     glDisableVertexAttribArray( attribute_v_color );
  290.  
  291.     /* Display the result */
  292.     glutSwapBuffers( );
  293. }
  294.  
  295. void rotate( int value )
  296. {
  297.     float angle = 0.0175; // 1 degree
  298.     //float angle = glutGet(GLUT_ELAPSED_TIME) / 1000.0 * 0.001;
  299.  
  300.     float rotation_matrix[] ={
  301.         cosf( angle ), 0, sinf( angle ),
  302.         0, 1, 0,
  303.         -1.0 * sinf( angle ), 0, cosf( angle ),
  304.  
  305.     };
  306.     float rotation_matrix_x[] ={
  307.         1, 0, 0,
  308.         0, cosf( angle ), -1.0 * sinf( angle ),
  309.         0, sinf( angle ), cosf( angle ),
  310.  
  311.     };
  312.     float rotation_matrix_z[] ={
  313.         cosf( angle ), -1.0 * sin( angle ), 0,
  314.         sinf( angle ), cosf( angle ), 0,
  315.         0, 0, 1,
  316.     };
  317.  
  318.     vec3 tempVec;
  319.     for( int i = 0; i < triangle_vertices.size( ); i++ )
  320.     {
  321.         tempVec.x = rotation_matrix[0] * triangle_verts[i].x + rotation_matrix[1] * triangle_verts[i].y + rotation_matrix[2] * triangle_verts[i].z;
  322.         tempVec.y = rotation_matrix[3] * triangle_verts[i].x + rotation_matrix[4] * triangle_verts[i].y + rotation_matrix[5] * triangle_verts[i].z;
  323.         tempVec.z = rotation_matrix[6] * triangle_verts[i].x + rotation_matrix[7] * triangle_verts[i].y + rotation_matrix[8] * triangle_verts[i].z;
  324.         triangle_verts[i] = tempVec;
  325.     }
  326.     glutTimerFunc( 10, rotate, 1 );
  327.     glutPostRedisplay( );
  328. }
  329.  
  330. void CheckStatus( GLuint obj )
  331. {
  332.     GLint status = 0;
  333.     if( glIsShader( obj ) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
  334.     if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
  335.     if( status == GL_TRUE ) return;
  336.  
  337.     GLint len = 0;
  338.     if( glIsShader( obj ) ) glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
  339.     if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
  340.  
  341.     vector< char > log( len );
  342.     if( glIsShader( obj ) ) glGetShaderInfoLog( obj, len, NULL, &log[0] );
  343.     if( glIsProgram( obj ) ) glGetProgramInfoLog( obj, len, NULL, &log[0] );
  344.     if( glIsShader( obj ) ) glDeleteShader( obj );
  345.     if( glIsProgram( obj ) ) glDeleteProgram( obj );
  346.     throw runtime_error( string( log.begin( ), log.end( ) ) );
  347. }
  348.  
  349. GLuint LoadShader( GLenum type, const string& aShaderSrc )
  350. {
  351.     GLuint shader = glCreateShader( type );
  352.     const char* srcPtr = aShaderSrc.c_str( );
  353.     glShaderSource( shader, 1, &srcPtr, NULL );
  354.     glCompileShader( shader );
  355.     CheckStatus( shader );
  356.     return shader;
  357. }
  358.  
  359. GLuint LoadProgram( const string& aVertSrc, const string& aFragSrc )
  360. {
  361.     GLuint vert = LoadShader( GL_VERTEX_SHADER, aVertSrc );
  362.     GLuint frag = LoadShader( GL_FRAGMENT_SHADER, aFragSrc );
  363.     GLuint program = glCreateProgram( );
  364.     glAttachShader( program, vert );
  365.     glAttachShader( program, frag );
  366.     glLinkProgram( program );
  367.     CheckStatus( program );
  368.     return program;
  369. }
  370.  
  371. #define GLSL(version, shader)  "#version " #version "\n" #shader
  372.  
  373. const GLchar* vert = GLSL
  374.     (
  375.     120,
  376.     attribute vec3 coord3d;
  377.     attribute vec3 v_color;
  378.     varying vec3 f_color;
  379.     void main( void )
  380.     {
  381.         gl_Position = vec4( coord3d, 1.0 );
  382.         f_color = v_color;
  383.     }
  384. );
  385.  
  386. const GLchar* frag = GLSL
  387.     (
  388.     120,
  389.     varying vec3 f_color;
  390.     void main( void )
  391.     {
  392.         gl_FragColor = vec4( f_color.x, f_color.y, f_color.z, 1.0 );
  393.     }
  394. );
  395.  
  396. int main( int argc, char* argv[] )
  397. {
  398.     /* Glut-related initialising functions */
  399.     glutInit( &argc, argv );
  400.     glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  401.     glutInitWindowSize( 640, 480 );
  402.     glutCreateWindow( "Hello Triangle!" );
  403.  
  404.     /* Extension wrangler initialising */
  405.     GLenum glew_status = glewInit( );
  406.     if( glew_status != GLEW_OK )
  407.     {
  408.         fprintf( stderr, "Error: %s\n", glewGetErrorString( glew_status ) );
  409.         return EXIT_FAILURE;
  410.     }
  411.  
  412.     /* When all init functions runs without errors,
  413.     the program can initialise the resources */
  414.     try
  415.     {
  416.         program = LoadProgram( vert, frag );
  417.  
  418.         glGenBuffers( 1, &vbo_triangle );
  419.         glGenBuffers( 1, &vbo_triangle_colors );
  420.  
  421.         glutDisplayFunc( onDisplay );
  422.         //glutIdleFunc( idle );
  423.  
  424.         glutTimerFunc( 10, rotate, 1 );
  425.         glutMainLoop( );
  426.     }
  427.     catch( std::exception& e )
  428.     {
  429.         std::cerr << e.what( );
  430.     }
  431.     return EXIT_SUCCESS;
  432. }