Skip to content
Snippets Groups Projects
Skeleton.cpp 11.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Cseh Viktor's avatar
    Cseh Viktor committed
    //=============================================================================================
    // Mintaprogram: Zld hromszg. Ervenyes 2019. osztol.
    //
    // A beadott program csak ebben a fajlban lehet, a fajl 1 byte-os ASCII karaktereket tartalmazhat, BOM kihuzando.
    // Tilos:
    // - mast "beincludolni", illetve mas konyvtarat hasznalni
    // - faljmuveleteket vegezni a printf-et kiveve
    // - Mashonnan atvett programresszleteket forrasmegjeloles nelkul felhasznalni es
    // - felesleges programsorokat a beadott programban hagyni!!!!!!! 
    // - felesleges kommenteket a beadott programba irni a forrasmegjelolest kommentjeit kiveve
    // ---------------------------------------------------------------------------------------------
    // A feladatot ANSI C++ nyelvu forditoprogrammal ellenorizzuk, a Visual Studio-hoz kepesti elteresekrol
    // es a leggyakoribb hibakrol (pl. ideiglenes objektumot nem lehet referencia tipusnak ertekul adni)
    // a hazibeado portal ad egy osszefoglalot.
    // ---------------------------------------------------------------------------------------------
    // A feladatmegoldasokban csak olyan OpenGL fuggvenyek hasznalhatok, amelyek az oran a feladatkiadasig elhangzottak 
    // A keretben nem szereplo GLUT fuggvenyek tiltottak.
    //
    // NYILATKOZAT
    // ---------------------------------------------------------------------------------------------
    // Nev    : Cseh Viktor
    // Neptun : GG2DP5
    // ---------------------------------------------------------------------------------------------
    // ezennel kijelentem, hogy a feladatot magam keszitettem, es ha barmilyen segitseget igenybe vettem vagy
    // mas szellemi termeket felhasznaltam, akkor a forrast es az atvett reszt kommentekben egyertelmuen jeloltem.
    // A forrasmegjeloles kotelme vonatkozik az eloadas foliakat es a targy oktatoi, illetve a
    // grafhazi doktor tanacsait kiveve barmilyen csatornan (szoban, irasban, Interneten, stb.) erkezo minden egyeb
    // informaciora (keplet, program, algoritmus, stb.). Kijelentem, hogy a forrasmegjelolessel atvett reszeket is ertem,
    // azok helyessegere matematikai bizonyitast tudok adni. Tisztaban vagyok azzal, hogy az atvett reszek nem szamitanak
    // a sajat kontribucioba, igy a feladat elfogadasarol a tobbi resz mennyisege es minosege alapjan szuletik dontes.
    // Tudomasul veszem, hogy a forrasmegjeloles kotelmenek megsertese eseten a hazifeladatra adhato pontokat
    // negativ elojellel szamoljak el es ezzel parhuzamosan eljaras is indul velem szemben.
    //=============================================================================================
    #include "framework.h"
    
    
    // vertex shader in GLSL: It is a Raw string (C++11) since it contains new line characters
    const char* const vertexSource = R"(
    	#version 330				// Shader 3.3
    	precision highp float;		// normal floats, makes no difference on desktop computers
    
    	uniform mat4 MVP;			// uniform variable, the Model-View-Projection transformation matrix
    	layout(location = 0) in vec2 vp;	// Varying input: vp = vertex position is expected in attrib array 0
    
    	void main() {
    		gl_Position = vec4(vp.x, vp.y, 0, 1) * MVP;		// transform vp from modeling space to normalized device space
    	}
    )";
    
    // fragment shader in GLSL
    const char* const fragmentSource = R"(
    	#version 330			// Shader 3.3
    	precision highp float;	// normal floats, makes no difference on desktop computers
    	
    	uniform vec3 color;		// uniform variable, the color of the primitive
    	out vec4 outColor;		// computed color of the current pixel
    
    	void main() {
    		outColor = vec4(color, 1);	// computed color is the color of the primitive
    	}
    )";
    
    const int BASECIRCLESEG = 100;  //how many triangle the base stands from
    
    GPUProgram gpuProgram; // vertex and fragment shaders
    
    void MVPInit() {
    	float MVPtransf[4][4] = { 1, 0, 0, 0,    // MVP matrix,
    							 0, 1, 0, 0,    // row-major!
    							 0, 0, 1, 0,
    							 0, 0, 0, 1 };
    
    	int location = glGetUniformLocation(gpuProgram.getId(), "MVP");    // Get the GPU location of uniform variable MVP
    	glUniformMatrix4fv(location, 1, GL_TRUE,
    		&MVPtransf[0][0]);    // Load a 4x4 row-major float matrix to the specified location
    }
    
    
    struct Color {
    	float r, g, b;
    	Color(int _r = 255, int _g = 179, int _b = 0) {
    		r = (float)_r / 255;
    		g = (float)_g / 255;
    		b = (float)_b / 255;
    	}
    	Color(float _r, float _g, float _b) {
    		r = _r; g = _g; b = _b;
    	}
    };
    
    void setBackgroundColor(Color color) {
    	glClearColor(color.r, color.g, color.b, 1);     // background color
    	glClear(GL_COLOR_BUFFER_BIT); // clear frame buffer
    }
    
    unsigned int vao;
    
    class drawableBase {
    protected:
    	
    	unsigned int vbo; //vertex buffer obj
    	std::vector<vec2> points;
    	Color color;
    public:
    
    	virtual void draw()  = 0;
    
    	virtual void setColor(Color newColor) = 0;
    
    	void init() {
    		glGenVertexArrays(1, &vao); // get 1 vao id
    		glBindVertexArray(vao);     // make it active
    
    		glGenBuffers(1, &vbo); // Generate 1 buffer
    		glBindBuffer(GL_ARRAY_BUFFER, vbo);
    		glBufferData(GL_ARRAY_BUFFER,  // Copy to GPU target
    			points.size() * sizeof(vec2), // # bytes
    			points.data(),         // address
    			GL_DYNAMIC_DRAW);  // we do not change later
    
    		glEnableVertexAttribArray(0); // AttribArray 0
    		glVertexAttribPointer(0,      // vbo -> AttribArray 0
    			2, GL_FLOAT,
    			GL_FALSE, // two floats/attrib, not fixed-point
    			0, NULL); // stride, offset: tightly packed
    	}
    };
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    float degToRad(float courrentTriangleAngle){
    	return (courrentTriangleAngle * M_PI / 180.0);
    }
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    
    class GraphPoint : drawableBase {
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	vec3 p3D; //center of the point in hyperbolic splace
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	vec2 p; // center on the base disk
    public:
    	
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	GraphPoint() {
    		p = vec2((((float)rand() / (float)(RAND_MAX))*2)-1, (((float)rand() / (float)(RAND_MAX)) * 2) - 1);
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		p3D = Vec2ToVec3(p);
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		placeCircleToNewCoordinates();
    		setColor(Color(244, 164, 96));
    	}
    
    	vec2 getPoint() {
    		return p;
    	}
    
    	void setCoordinates(vec2 _p) {
    		p = _p;
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		p3D = Vec2ToVec3(p);
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		placeCircleToNewCoordinates();
    	}
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	vec3 Vec2ToVec3(vec2 p) {
    		return vec3(p.x, p.y, sqrt(p.x * p.x + p.y * p.y + 1));
    	}
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    	void placeCircleToNewCoordinates() {
    		points.clear();
    		float piece = 360.0 / BASECIRCLESEG;
    		float courrentTriangleAngle = 0;
    
    		for (int i = 0; i < BASECIRCLESEG; i++) {
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    			points.push_back(vec2(p.x / p3D.z, p.y / p3D.z));
    
    			
    			//points.push_back(vec2(
    			//	p3D.x + (cos(degToRad(courrentTriangleAngle)) / 30) * (cos((abs(p3D.x) * abs(p3D.x) * abs(p3D.x)) / 3 + (abs(p3D.x) * abs(p3D.y) * abs(p3D.y)) + abs(p3D.x) * abs(p3D.z) * abs(p3D.z) + abs(p3D.x)) /30 ),
    			//	p3D.y + (sin(degToRad(courrentTriangleAngle)) / 30) * (sin((abs(p3D.y) * abs(p3D.y) * abs(p3D.y)) / 3 + (abs(p3D.y) * abs(p3D.x) * abs(p3D.x)) + abs(p3D.y) * abs(p3D.z) * abs(p3D.z) + abs(p3D.y)) /30 )));
    
    			//points.push_back(vec2(
    			//	p3D.x + (cos(degToRad(courrentTriangleAngle)) / 20) * (cos(degToRad(90 - abs(1/tan(8 * p3D.x + 8 * p3D.y - 8 * p3D.z))))),
    			//	p3D.y + (sin(degToRad(courrentTriangleAngle)) / 20) * (sin(degToRad(90 - abs(1/tan(8 * p3D.x + 8 * p3D.y - 8 * p3D.z)))))));
    
    			points.push_back(vec2(
    				p3D.x / p3D.z + (cos(degToRad(courrentTriangleAngle)) / 20) / p3D.z,
    				p3D.y / p3D.z + (sin(degToRad(courrentTriangleAngle)) / 20) / p3D.z));
    
    
    			//printf("%f \n", abs(1 / tan(2 * p3D.x + 2 * p3D.y - 2 * p3D.z)));
    			// points.push_back(vec2(p.x +(cos(courrentTriangleAngle * M_PI / 180.0) /30),p.y + (sin(courrentTriangleAngle * M_PI / 180.0) /30))); alap volt ami kort rajzolt a pontokba
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    
    			courrentTriangleAngle += piece;
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    			
    			points.push_back(vec2(
    				p3D.x / p3D.z + (cos(degToRad(courrentTriangleAngle)) / 20) / p3D.z,
    				p3D.y / p3D.z + (sin(degToRad(courrentTriangleAngle)) / 20) / p3D.z));
    			
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		}
    	}
    
    	vec2 vec3tovec2(vec3 c) {
    		vec2 temp;
    		temp.x = c.x;
    		temp.y = c.y;
    		return temp;
    	}
    
    	void reColor() const {
    		int location = glGetUniformLocation(gpuProgram.getId(), "color");
    		glUniform3f(location, color.r, color.g, color.b); // 3 floats
    	}
    
    	void setColor(Color newColor) override{
    		color = newColor;
    	}
    
    	void draw() override
    	{
    		init();
    		reColor();
    		MVPInit();
    		glBindVertexArray(vao);  // Draw call
    		glDrawArrays(GL_TRIANGLES, 0, points.size() /*# Elements*/);
    
    	}
    };
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    struct pairs {
    	GraphPoint p1;
    	GraphPoint p2;
    };
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    class Line : drawableBase {
    	
    
    public:
    	Line(vec2 _p1, vec2 _p2) {
    		setColor(Color(254, 254, 0));
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		points.push_back(_p1 / sqrt(_p1.x * _p1.x + _p1.y * _p1.y + 1));
    		points.push_back(_p2 / sqrt(_p2.x * _p2.x + _p2.y * _p2.y + 1));
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	}
    
    	void reColor() const {
    		int location = glGetUniformLocation(gpuProgram.getId(), "color");
    		glUniform3f(location, color.r, color.g, color.b); // 3 floats
    	}
    	void setColor(Color newColor) override {
    		color = newColor;
    	}
    
    	void draw() override {
    		init();
    		reColor();
    		glBindVertexArray(vao);  // Draw call
    		glDrawArrays(GL_LINES, 0, points.size() /*# Elements*/);
    	}
    };
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    class graphManager {
    
    	GraphPoint* gps = new GraphPoint[50];
    	std::vector<pairs> pair;
    	std::vector<Line> line;
    public:
    
    	graphManager() {
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    		for (int i = 0; i < 50; i++) {
    			for (int j = i+1; j < 50; j++) {
    				int rndm = rand() % 100;
    				if (rndm < 5) {
    					pairs p; p.p1 = gps[i]; p.p2 = gps[j];
    					pair.push_back(p);
    				}
    			}
    		}
    	}
    
    	void draw() {
    		for (int i = 0; i < 50; i++) {
    			gps[i].draw();
    		}
    
    		for (int i = 0; i < pair.size(); i++) {
    			Line temp(pair[i].p1.getPoint(), pair[i].p2.getPoint());
    			temp.draw();
    			line.push_back(temp);
    		}
    	}
    };
    
    graphManager gm;
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    // Initialization, create an OpenGL context
    void onInitialization() {
    	glViewport(0, 0, windowWidth, windowHeight);
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	// create program for the GPU
    	gpuProgram.create(vertexSource, fragmentSource, "outColor");
    }
    
    // Window has become invalid: Redraw
    void onDisplay() {
    	MVPInit();
    	setBackgroundColor(Color(0,0,0)); //set the background color to black
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    	gm.draw();
    
    Cseh Viktor's avatar
    Cseh Viktor committed
    
    	glutSwapBuffers(); // exchange buffers for double buffering
    }
    
    // Key of ASCII code pressed
    void onKeyboard(unsigned char key, int pX, int pY) {
    	if (key == 'd') glutPostRedisplay();         // if d, invalidate display, i.e. redraw
    }
    
    // Key of ASCII code released
    void onKeyboardUp(unsigned char key, int pX, int pY) {
    }
    
    // Move mouse with key pressed
    void onMouseMotion(int pX, int pY) {	// pX, pY are the pixel coordinates of the cursor in the coordinate system of the operation system
    	// Convert to normalized device space
    	float cX = 2.0f * pX / windowWidth - 1;	// flip y axis
    	float cY = 1.0f - 2.0f * pY / windowHeight;
    	printf("Mouse moved to (%3.2f, %3.2f)\n", cX, cY);
    }
    
    // Mouse click event
    void onMouse(int button, int state, int pX, int pY) { // pX, pY are the pixel coordinates of the cursor in the coordinate system of the operation system
    	// Convert to normalized device space
    	float cX = 2.0f * pX / windowWidth - 1;	// flip y axis
    	float cY = 1.0f - 2.0f * pY / windowHeight;
    
    	char* buttonStat;
    	switch (state) {
    	case GLUT_DOWN: buttonStat = "pressed"; break;
    	case GLUT_UP:   buttonStat = "released"; break;
    	}
    
    	switch (button) {
    	case GLUT_LEFT_BUTTON:   printf("Left button %s at (%3.2f, %3.2f)\n", buttonStat, cX, cY);   break;
    	case GLUT_MIDDLE_BUTTON: printf("Middle button %s at (%3.2f, %3.2f)\n", buttonStat, cX, cY); break;
    	case GLUT_RIGHT_BUTTON:  printf("Right button %s at (%3.2f, %3.2f)\n", buttonStat, cX, cY);  break;
    	}
    }
    
    // Idle event indicating that some time elapsed: do animation here
    void onIdle() {
    	long time = glutGet(GLUT_ELAPSED_TIME); // elapsed time since the start of the program
    }