Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GL/glew.h>
- #include <GL/glut.h>
- /* Using the standard output for fprintf */
- #include <iostream>
- #include <functional>
- #include <memory>
- #include "Shader.hpp"
- #include "Program.hpp"
- #include <map>
- #include <vector>
- #include <cmath>
- #include <algorithm>
- #include <iterator>
- #include <time.h>
- GLint attribute_coord3d, attribute_v_color;
- GLuint vbo_triangle, vbo_triangle_colors;
- std::shared_ptr<cs5400::Program> 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->getHandle());
- 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 */
- glGenBuffers(1, &vbo_triangle);
- glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle);
- glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_verts), triangle_verts, GL_STATIC_DRAW);
- 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 */
- glGenBuffers(1, &vbo_triangle_colors);
- glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle_colors);
- glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_colors), triangle_colors, GL_STATIC_DRAW);
- char* attribute_name = "v_color";
- auto attribute_v_color = glGetAttribLocation(program->getHandle(), attribute_name);
- if (attribute_v_color == -1)
- fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
- glEnableVertexAttribArray(attribute_v_color);
- glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle_colors);
- 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_v_color);
- glDisableVertexAttribArray(attribute_coord3d);
- /* 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();
- }
- 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 = cs5400::make_program
- (
- cs5400::make_vertexShader("vertex.glsl")
- ,cs5400::make_fragmentShader("fragment.glsl")
- );
- glutDisplayFunc(onDisplay);
- //glutIdleFunc( idle );
- glutTimerFunc(10, rotate,1);
- glutMainLoop();
- }
- catch(std::exception& e)
- {
- std::cerr << e.what();
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement