//============================================================================================= // Mintaprogram: Z�ld h�romsz�g. 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 } }; float degToRad(float courrentTriangleAngle){ return (courrentTriangleAngle * M_PI / 180.0); } class GraphPoint : drawableBase { vec3 p3D; //center of the point in hyperbolic splace vec2 p; // center on the base disk public: GraphPoint() { p = vec2((((float)rand() / (float)(RAND_MAX))*2)-1, (((float)rand() / (float)(RAND_MAX)) * 2) - 1); p3D = Vec2ToVec3(p); placeCircleToNewCoordinates(); setColor(Color(244, 164, 96)); } vec2 getPoint() { return p; } void setCoordinates(vec2 _p) { p = _p; p3D = Vec2ToVec3(p); placeCircleToNewCoordinates(); } vec3 Vec2ToVec3(vec2 p) { return vec3(p.x, p.y, sqrt(p.x * p.x + p.y * p.y + 1)); } void placeCircleToNewCoordinates() { points.clear(); float piece = 360.0 / BASECIRCLESEG; float courrentTriangleAngle = 0; for (int i = 0; i < BASECIRCLESEG; i++) { 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 courrentTriangleAngle += piece; points.push_back(vec2( p3D.x / p3D.z + (cos(degToRad(courrentTriangleAngle)) / 20) / p3D.z, p3D.y / p3D.z + (sin(degToRad(courrentTriangleAngle)) / 20) / p3D.z)); } } 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*/); } }; struct pairs { GraphPoint p1; GraphPoint p2; }; class Line : drawableBase { public: Line(vec2 _p1, vec2 _p2) { setColor(Color(254, 254, 0)); 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)); } 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*/); } }; class graphManager { GraphPoint* gps = new GraphPoint[50]; std::vector<pairs> pair; std::vector<Line> line; public: graphManager() { 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; // Initialization, create an OpenGL context void onInitialization() { glViewport(0, 0, windowWidth, windowHeight); // 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 gm.draw(); 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 }