Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // g++ -std=c++11 main.cpp -lglut -lGLEW
- #include <GL/glew.h>
- #include <GL/glut.h>
- /* Using the standard output for fprintf */
- #include <iostream>
- #include <functional>
- #include <memory>
- #include <vector>
- #include <stdexcept>
- #include <map>
- #include <vector>
- #include <cmath>
- #include <algorithm>
- #include <iterator>
- #include <time.h>
- using namespace std;
- GLint attribute_coord3d, attribute_v_color;
- GLuint vbo_triangle, vbo_triangle_colors;
- GLuint program;
- const int NUM_ITERATIONS = 5;
- const int NUM_TRIANGLES = pow( 4.0, NUM_ITERATIONS );
- int modelDrawn = 0;
- struct vec3
- {
- float x;
- float y;
- float z;
- vec3( float x1, float y1, float z1 ) : x( x1 ), y( y1 ), z( z1 )
- {
- }
- vec3( ) : x( 0 ), y( 0 ), z( 0 )
- {
- }
- vec3& operator+=(const vec3 & other )
- {
- x += other.x;
- y += other.y;
- z += other.z;
- }
- vec3 operator/=(const float)
- {
- }
- vec3 operator+(const vec3 & other ) const
- {
- return vec3( x + other.x, y + other.y, z + other.z );
- }
- vec3 operator/(const float &denom ) const
- {
- return vec3( x / denom, y / denom, z / denom );
- }
- vec3 operator*(const float mult)
- {
- return vec3( x*mult, y*mult, z * mult );
- }
- bool operator<(const vec3 & n ) const
- {
- if( x != n.x )
- return x < n.x;
- else if( y != n.y )
- return y < n.y;
- else if( z != n.z )
- return z < n.z;
- return length( ) < n.length( );
- }
- bool operator==(const vec3 & n ) const
- {
- return x == n.x && y == n.y && z == n.z;
- }
- float length( ) const
- {
- return sqrt( pow( x, 2 ) + pow( y, 2 ) + pow( z, 2 ) );
- }
- void Print( ) const
- {
- std::cout << "(" << x << "," << y << "," << z << ")" << std::endl;
- }
- };
- //container for gasket verts
- std::vector<vec3> triangle_vertices;
- std::vector<vec3> triangle_colors_vec;
- float getRandom( float max, float min )
- {
- return ((float(rand( ) ) / float(RAND_MAX ) ) * ( max - ( min ) ) ) + ( min );
- }
- float getVectorDistance( vec3 a, vec3 b )
- {
- return sqrt( pow( ( a.x - b.x ), 2 ) + pow( ( a.y - b.y ), 2 ) + pow( ( a.z - b.z ), 2 ) );
- }
- vec3 randVector( );
- struct Triangle
- {
- vec3 a;
- vec3 b;
- vec3 c;
- Triangle( vec3 a1, vec3 b1, vec3 c1 ) : a( a1 ), b( b1 ), c( c1 )
- {
- }
- };
- vec3 getMidpoint( const vec3& a, const vec3& b )
- {
- const float SCALE = 0.1;
- static std::map<std::pair<vec3, vec3>, vec3> memo;
- auto foundResult = memo.find( std::make_pair( a, b ) );
- if( foundResult != memo.end( ) )
- {
- return foundResult->second;
- }
- auto result = ( a + b ) / 2;
- auto variance = 0.1 * getVectorDistance( a, b );
- auto randX = getRandom( result.x + variance, result.x - variance );
- auto randY = getRandom( result.y + variance, result.y - variance );
- auto randZ = getRandom( result.z + variance, result.z - variance );
- result = vec3( randX, randY, randZ );
- memo.insert( std::make_pair( std::make_pair( a, b ), result ) );
- memo.insert( std::make_pair( std::make_pair( b, a ), result ) );
- return result;
- }
- void makeGasket( Triangle t, int count )
- {
- if( count > 0 )
- {
- auto d = getMidpoint( t.a, t.b );
- auto e = getMidpoint( t.b, t.c );
- auto f = getMidpoint( t.a, t.c );
- makeGasket( Triangle( t.a, d, f ), count - 1 );
- makeGasket( Triangle( d, t.b, e ), count - 1 );
- makeGasket( Triangle( f, d, e ), count - 1 );
- makeGasket( Triangle( f, e, t.c ), count - 1 );
- }
- else
- {
- triangle_vertices.push_back( t.a );
- triangle_vertices.push_back( t.b );
- triangle_vertices.push_back( t.c );
- }
- }
- void createColors( )
- {
- for( int i = 0; i < triangle_vertices.size( ); i++ )
- {
- float random = getRandom( 0.5, 1.0 );
- static std::map<vec3, float> randColor;
- auto foundResult = randColor.find( triangle_vertices[i] );
- if( foundResult != randColor.end( ) )
- {
- random = foundResult->second;
- }
- else
- randColor.insert( std::make_pair( triangle_vertices[i], random ) );
- triangle_colors_vec.push_back( vec3( random, random, random ) );
- }
- }
- vec3 triangle_verts[15000];
- vec3 triangle_colors[15000];
- void onDisplay( )
- {
- srand( time( NULL ) );
- /* Clear the background as white */
- glClearColor( 0.0, 0.0, 0.0, 0.0 );
- glEnable( GL_DEPTH_TEST );
- glDepthFunc( GL_LESS );
- glCullFace( GL_FRONT );
- glEnable( GL_CULL_FACE );
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- /* Tell OpenGL which program to use*/
- glUseProgram( program );
- if( modelDrawn == 0 )
- {
- modelDrawn = 1;
- vec3 verts[] ={
- vec3( 0.0, 1.0, 0.0 ),
- vec3( 0.943, -0.333, 0.0 ),
- vec3( -0.471, -0.333, 0.816 ),
- vec3( -0.471, -0.333, -0.816 )
- };
- Triangle initialTri = Triangle(
- verts[0],
- verts[2],
- verts[1]
- );
- Triangle initialTri2 = Triangle(
- verts[0],
- verts[1],
- verts[3]
- );
- Triangle initialTri3 = Triangle(
- verts[0],
- verts[3],
- verts[2]
- );
- Triangle initialTri4 = Triangle(
- verts[1],
- verts[2],
- verts[3]
- );
- makeGasket( initialTri, NUM_ITERATIONS );
- makeGasket( initialTri2, NUM_ITERATIONS );
- makeGasket( initialTri3, NUM_ITERATIONS );
- makeGasket( initialTri4, NUM_ITERATIONS );
- std::copy( triangle_vertices.begin( ), triangle_vertices.end( ), triangle_verts );
- createColors( );
- std::copy( triangle_colors_vec.begin( ), triangle_colors_vec.end( ), triangle_colors );
- }
- /* Setup vertex data */
- glBindBuffer( GL_ARRAY_BUFFER, vbo_triangle );
- glBufferData( GL_ARRAY_BUFFER, sizeof (triangle_verts ), triangle_verts, GL_STATIC_DRAW );
- auto attribute_coord3d = glGetAttribLocation( program, "coord3d" );
- glEnableVertexAttribArray( attribute_coord3d );
- /* Describe our vertices array to OpenGL (it can't guess its format automatically) */
- glVertexAttribPointer(
- attribute_coord3d, // attribute
- 3, // number of elements per vertex, here (x,y,z)
- GL_FLOAT, // the type of each element
- GL_FALSE, // take our values as-is
- 0, // no extra data between each position
- 0 // vec3er to the C array
- );
- /* Push each element in buffer_vertices to the vertex shader */
- glBindBuffer( GL_ARRAY_BUFFER, vbo_triangle_colors );
- glBufferData( GL_ARRAY_BUFFER, sizeof (triangle_colors ), triangle_colors, GL_STATIC_DRAW );
- auto attribute_v_color = glGetAttribLocation( program, "v_color" );
- glEnableVertexAttribArray( attribute_v_color );
- glVertexAttribPointer(
- attribute_v_color, // attribute
- 3, // number of elements per vertex, here (r,g,b)
- GL_FLOAT, // the type of each element
- GL_FALSE, // take our values as-is
- 0, // no extra data between each position
- 0 // offset of first element
- );
- glDrawArrays( GL_TRIANGLES, 0, NUM_TRIANGLES * 3 * 4 );
- glDisableVertexAttribArray( attribute_coord3d );
- glDisableVertexAttribArray( attribute_v_color );
- /* Display the result */
- glutSwapBuffers( );
- }
- void rotate( int value )
- {
- float angle = 0.0175; // 1 degree
- //float angle = glutGet(GLUT_ELAPSED_TIME) / 1000.0 * 0.001;
- float rotation_matrix[] ={
- cosf( angle ), 0, sinf( angle ),
- 0, 1, 0,
- -1.0 * sinf( angle ), 0, cosf( angle ),
- };
- float rotation_matrix_x[] ={
- 1, 0, 0,
- 0, cosf( angle ), -1.0 * sinf( angle ),
- 0, sinf( angle ), cosf( angle ),
- };
- float rotation_matrix_z[] ={
- cosf( angle ), -1.0 * sin( angle ), 0,
- sinf( angle ), cosf( angle ), 0,
- 0, 0, 1,
- };
- vec3 tempVec;
- for( int i = 0; i < triangle_vertices.size( ); i++ )
- {
- tempVec.x = rotation_matrix[0] * triangle_verts[i].x + rotation_matrix[1] * triangle_verts[i].y + rotation_matrix[2] * triangle_verts[i].z;
- tempVec.y = rotation_matrix[3] * triangle_verts[i].x + rotation_matrix[4] * triangle_verts[i].y + rotation_matrix[5] * triangle_verts[i].z;
- tempVec.z = rotation_matrix[6] * triangle_verts[i].x + rotation_matrix[7] * triangle_verts[i].y + rotation_matrix[8] * triangle_verts[i].z;
- triangle_verts[i] = tempVec;
- }
- glutTimerFunc( 10, rotate, 1 );
- glutPostRedisplay( );
- }
- void CheckStatus( GLuint obj )
- {
- GLint status = 0;
- if( glIsShader( obj ) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
- if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
- if( status == GL_TRUE ) return;
- GLint len = 0;
- if( glIsShader( obj ) ) glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
- if( glIsProgram( obj ) ) glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
- vector< char > log( len );
- if( glIsShader( obj ) ) glGetShaderInfoLog( obj, len, NULL, &log[0] );
- if( glIsProgram( obj ) ) glGetProgramInfoLog( obj, len, NULL, &log[0] );
- if( glIsShader( obj ) ) glDeleteShader( obj );
- if( glIsProgram( obj ) ) glDeleteProgram( obj );
- throw runtime_error( string( log.begin( ), log.end( ) ) );
- }
- GLuint LoadShader( GLenum type, const string& aShaderSrc )
- {
- GLuint shader = glCreateShader( type );
- const char* srcPtr = aShaderSrc.c_str( );
- glShaderSource( shader, 1, &srcPtr, NULL );
- glCompileShader( shader );
- CheckStatus( shader );
- return shader;
- }
- GLuint LoadProgram( const string& aVertSrc, const string& aFragSrc )
- {
- GLuint vert = LoadShader( GL_VERTEX_SHADER, aVertSrc );
- GLuint frag = LoadShader( GL_FRAGMENT_SHADER, aFragSrc );
- GLuint program = glCreateProgram( );
- glAttachShader( program, vert );
- glAttachShader( program, frag );
- glLinkProgram( program );
- CheckStatus( program );
- return program;
- }
- #define GLSL(version, shader) "#version " #version "\n" #shader
- const GLchar* vert = GLSL
- (
- 120,
- attribute vec3 coord3d;
- attribute vec3 v_color;
- varying vec3 f_color;
- void main( void )
- {
- gl_Position = vec4( coord3d, 1.0 );
- f_color = v_color;
- }
- );
- const GLchar* frag = GLSL
- (
- 120,
- varying vec3 f_color;
- void main( void )
- {
- gl_FragColor = vec4( f_color.x, f_color.y, f_color.z, 1.0 );
- }
- );
- int main( int argc, char* argv[] )
- {
- /* Glut-related initialising functions */
- glutInit( &argc, argv );
- glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
- glutInitWindowSize( 640, 480 );
- glutCreateWindow( "Hello Triangle!" );
- /* Extension wrangler initialising */
- GLenum glew_status = glewInit( );
- if( glew_status != GLEW_OK )
- {
- fprintf( stderr, "Error: %s\n", glewGetErrorString( glew_status ) );
- return EXIT_FAILURE;
- }
- /* When all init functions runs without errors,
- the program can initialise the resources */
- try
- {
- program = LoadProgram( vert, frag );
- glGenBuffers( 1, &vbo_triangle );
- glGenBuffers( 1, &vbo_triangle_colors );
- glutDisplayFunc( onDisplay );
- //glutIdleFunc( idle );
- glutTimerFunc( 10, rotate, 1 );
- glutMainLoop( );
- }
- catch( std::exception& e )
- {
- std::cerr << e.what( );
- }
- return EXIT_SUCCESS;
- }
Add Comment
Please, Sign In to add comment