/* Dragan Miljkovic */ #define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include using namespace glm; using namespace std; #define MOVING_CONST 0.1 #define ROTATION_CONST 3.14f / 180.f #define LOOK_MOVEMENT_CONST 0.1f /*--------------------------------------------------*/ char title[] = "Prozor"; int FPS = 60; vec3 CameraPosition(1.0, 1.5, 1.0); vec3 LookAt_vector(0.0, 1, 0.0); vec3 LookUp_vector(0.0, 1.0, 0.0); vector coordinateSystem; const int circle_dots = 50; const float height = 480; const float ratio = 16.f / 9.f; double upDownAngle = 0; int currentSpeed = 1; float arrowRotate = 0.f; vec3 operator* (mat4x4 mat, vec3 vec) { vec4 v(vec.x, vec.y, vec.z, 1.f); v = mat * v; return vec3(v.x, v.y, v.z); } vector operator* (mat4x4 mat, vector vectors) { for (int i = 0; i < vectors.size(); i++) vectors[i] = mat * vectors[i]; return vectors; } //o GLUT_BITMAP_TIMES_ROMAN_24 //o GLUT_BITMAP_TIMES_ROMAN_10 //o GLUT_BITMAP_HELVETICA_18 void RenderString(float x, float y, void* font, double r, double g, double b) { glColor3f(r, g, b); glRasterPos2f(x, y); char s[100]; sprintf(s, "x = %.2lf\ny = %.2lf\nz = %.2lf", CameraPosition.x, CameraPosition.y, CameraPosition.z); glutBitmapString(font, (const unsigned char*)s); } /*--------------------------------------------------*/ void createCoordinates() { coordinateSystem.resize(4); coordinateSystem[0] = vec3(0.0, 0.0, 0.0); coordinateSystem[1] = vec3(1.0, 0.0, 0.0); coordinateSystem[2] = vec3(0.0, 1.0, 0.0); coordinateSystem[3] = vec3(0.0, 0.0, 1.0); } void drawCoordinates() { glLineWidth(2.0); glBegin(GL_LINES); // X axis glColor3f(1.0f, 0.0f, 0.0f); // Red glVertex3d(coordinateSystem[0].x, coordinateSystem[0].y, coordinateSystem[0].z); glVertex3d(coordinateSystem[1].x, coordinateSystem[1].y, coordinateSystem[1].z); // Y axis glColor3f(0.0f, 1.0f, 0.0f); // Green glVertex3d(coordinateSystem[0].x, coordinateSystem[0].y, coordinateSystem[0].z); glVertex3d(coordinateSystem[2].x, coordinateSystem[2].y, coordinateSystem[2].z); // Z axis glColor3f(0.0f, 0.0f, 1.0f); // Blue glVertex3d(coordinateSystem[0].x, coordinateSystem[0].y, coordinateSystem[0].z); glVertex3d(coordinateSystem[3].x, coordinateSystem[3].y, coordinateSystem[3].z); glEnd(); } /*--------------------------------------------------*/ int numPoints = 70; float visinaDrske = 0.2; float angle = 0.0f; float angleZakrivi = 2*M_PI/20; float radiusCentra = 0.15f; void draw(GLenum mode, vector points) { glBegin(mode); for (int i = 0; i < points.size(); i++) { glVertex3f(points[i].x, points[i].y, points[i].z); } glEnd(); } void draw(GLenum mode, vector> points,vec3 color) { float r = color.x; float g = color.y; float b = color.z; float r1 = 1.2 * color.x / points[0].size(); float g1 = 1.2 * color.y / points[0].size(); float b1 = 1.2*color.z / points[0].size(); glBegin(mode); for (int i = 0; i < points[0].size(); i++) { if (i <= points[0].size() / 2) { r -= r1; g -= g1; b -= b1; } else { r += r1; g += g1; b += b1; } glColor3f(r, g, b); glVertex3f(points[0][i].x, points[0][i].y, points[0][i].z); glVertex3f(points[1][i].x, points[1][i].y, points[1][i].z); } glEnd(); } void draw(GLenum mode, vector> points) { glBegin(mode); for (int i = 0; i < points[0].size(); i++) { glVertex3f(points[0][i].x, points[0][i].y, points[0][i].z); glVertex3f(points[1][i].x, points[1][i].y, points[1][i].z); } glEnd(); } void draw(GLenum mode, vector points, vector points1,vec3 color) { float r = color.x; float g = color.y; float b = color.z; float r1 = 1.2 * color.x / points.size(); float g1 = 1.2 * color.y / points.size(); float b1 = 1.2 * color.z / points.size(); glBegin(mode); for (int i = 0; i < points1.size(); i++) { if (i < points1.size() / 2) { r -= r1; g -= g1; b -= b1; } else { r += r1; g += g1; b += b1; } glColor3f(r, g, b); glVertex3f(points[i].x, points[i].y, points[i].z); glVertex3f(points1[i].x, points1[i].y, points1[i].z); } glEnd(); } void draw(GLenum mode, vector points, vector points1) { glBegin(mode); for (int i = 0; i < points1.size(); i++) { glVertex3f(points[i].x, points[i].y, points[i].z); glVertex3f(points1[i].x, points1[i].y, points1[i].z); } glEnd(); } void colindarSociva(vec3 position, float radius, float height, vec3 color) { vec3 a(0, radius, 0); vector> points; points.resize(2); float ang = 2 * M_PI / numPoints; mat4 rotacija = rotate(ang, vec3(1, 0, 0)); for (int i = 0; i <= numPoints; i++) { points[0].push_back(vec3(a)); points[1].push_back(vec3(a.x+height,a.y,a.z)); a = rotacija * a; } mat4 rot = rotate(angle, vec3(0, 1, 0)); mat4 rotZak = rotate(angleZakrivi, vec3(0, 0, 1)); mat4 pos = translate(vec3(position.x, 0, position.z)); mat4 podigni = translate(vec3(0, position.y+ visinaDrske + radiusCentra - 0.05, 0)); points[0] = podigni*rot*rotZak*pos*points[0]; points[1] = podigni * rot*rotZak*pos*points[1]; glColor3f(color.x, color.y, color.z); draw(GL_POLYGON, points[0]); draw(GL_QUAD_STRIP, points,color); glColor3f(0, 0, 1); draw(GL_POLYGON, points[1]); } void colindarSocivaBusno(vec3 position, float radius, float radius1, float height, vec3 color) { vec3 a(0, radius, 0); vec3 b(0, radius1, 0); vector> points; points.resize(4); float ang = 2 * M_PI / numPoints; mat4 rotacija = rotate(ang, vec3(1, 0, 0)); for (int i = 0; i <= numPoints; i++) { points[0].push_back(vec3(a)); points[1].push_back(vec3(a.x + height, a.y, a.z)); points[2].push_back(vec3(b)); points[3].push_back(vec3(b.x + height, b.y, b.z)); a = rotacija * a; b = rotacija * b; } mat4 rot = rotate(angle, vec3(0, 1, 0)); mat4 rotZak = rotate(angleZakrivi, vec3(0, 0, 1)); mat4 pos = translate(vec3(position.x, 0, position.z)); mat4 podigni = translate(vec3(0, position.y + visinaDrske + radiusCentra - 0.05, 0)); points[0] = podigni * rot*rotZak*pos*points[0]; points[1] = podigni * rot*rotZak*pos*points[1]; points[2] = podigni * rot*rotZak*pos*points[2]; points[3] = podigni * rot*rotZak*pos*points[3]; glColor3f(color.x, color.y, color.z); draw(GL_QUAD_STRIP, points[0],points[1],color); draw(GL_QUAD_STRIP, points[2], points[3]); draw(GL_QUAD_STRIP, points[0], points[2]); glColor3f(0, 0, 1); draw(GL_QUAD_STRIP, points[1], points[3]); } void colindarDrska(vec3 position, float radius, float height, vec3 color) { vec3 a(radius, 0, 0); vector> points; points.resize(2); float ang = 2 * M_PI / numPoints; mat4 rotacija = rotate(ang, vec3(0, 1, 0)); for (int i = 0; i <= numPoints; i++) { points[0].push_back(vec3(a)); points[1].push_back(vec3(a.x, a.y+height, a.z)); a = rotacija * a; } mat4 pos = translate(position); points[0] = pos*points[0]; points[1] = pos*points[1]; glColor3f(color.x, color.y, color.z); draw(GL_POLYGON, points[0]); draw(GL_QUAD_STRIP, points); glColor3f(0, 0, 1); draw(GL_POLYGON, points[1]); } void tripod(vec3 position) { vec3 a(0.02, 0.1, 0); vector> nogar; nogar.resize(2); float ang = 2 * M_PI / numPoints; mat4 rotacija = rotate(ang, vec3(0, 1, 0)); for (int i = 0; i <= numPoints; i++) { nogar[0].push_back(vec3(a)); nogar[1].push_back(vec3(a.x, a.y + 0.9, a.z)); a = rotacija * a; } mat4 gornje = translate(vec3(0.05, 0, 0)); mat4 donje = translate(vec3(0.28, 0, 0)); float trecina = 2 * M_PI / 3; mat4 zaokreni = rotate(trecina, vec3(0, 1, 0)); nogar[0] = donje * nogar[0]; nogar[1] = gornje * nogar[1]; glColor3f(0.7, 0.7, 0.7); draw(GL_QUAD_STRIP, nogar); nogar[0] = zaokreni * nogar[0]; nogar[1] = zaokreni * nogar[1]; draw(GL_QUAD_STRIP, nogar); nogar[0] = zaokreni * nogar[0]; nogar[1] = zaokreni * nogar[1]; draw(GL_QUAD_STRIP, nogar); vec3 b(0.03, 0, 0); vector> dno; dno.resize(2); for (int i = 0; i <= numPoints; i++) { dno[0].push_back(vec3(b)); dno[1].push_back(vec3(b.x, b.y + 0.105, b.z)); b = rotacija * b; } float ngb = M_PI / 12; mat4 nagib = rotate(ngb, vec3(0, 0, 1)); mat4 pom = translate(vec3(0.26, 0, 0)); dno[0] = gornje*pom*nagib * dno[0]; dno[1] = gornje*pom*nagib * dno[1]; glColor3f(0, 0, 0); draw(GL_QUAD_STRIP, dno); draw(GL_POLYGON, dno[0]); draw(GL_POLYGON, dno[1]); dno[0] = zaokreni * dno[0]; dno[1] = zaokreni * dno[1]; draw(GL_QUAD_STRIP, dno); draw(GL_POLYGON, dno[0]); draw(GL_POLYGON, dno[1]); dno[0] = zaokreni * dno[0]; dno[1] = zaokreni * dno[1]; draw(GL_QUAD_STRIP, dno); draw(GL_POLYGON, dno[0]); draw(GL_POLYGON, dno[1]); colindarDrska(vec3(position.x, position.y + 0.9, position.z), 0.13, 0.1, vec3(0.4, 0.4, 1)); } /*--------------------------------------------------*/ void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80.f, 16.f / 9.f, 0.1f, 50.f); gluLookAt( CameraPosition.x, CameraPosition.y, CameraPosition.z, LookAt_vector.x, LookAt_vector.y, LookAt_vector.z, LookUp_vector.x, LookUp_vector.y, LookUp_vector.z ); //drawCoordinates(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); colindarSociva(vec3(-0.65, 1, 0), radiusCentra - 0.12,0.05, vec3(0.7, 0.7, 0.7)); colindarSocivaBusno(vec3(-0.65, 1, 0), radiusCentra-0.1,radiusCentra-0.12, 0.1, vec3(0.4, 0.4, 1)); colindarSociva(vec3(-0.55, 1, 0), radiusCentra-0.05, 0.15, vec3(0, 0, 1)); colindarSociva(vec3(-0.4, 1, 0), radiusCentra, 0.2, vec3(0.4, 0.4, 1)); colindarSociva(vec3(-0.2, 1, 0), radiusCentra, 0.6, vec3(0, 0, 1)); colindarSocivaBusno(vec3(0.4, 1, 0), radiusCentra+0.03,radiusCentra-0.02, 0.2, vec3(0.4, 0.4, 1)); colindarSociva(vec3(0.6, 1, 0), radiusCentra-0.02, -0.1, vec3(0.7, 0.7, 0.7)); colindarDrska(vec3(0, 1, 0), 0.05, visinaDrske, vec3(0.7, 0.7, 0.7)); tripod(vec3(0, 0, 0)); glutSwapBuffers(); } void timer(int v) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( CameraPosition.x, CameraPosition.y, CameraPosition.z, LookAt_vector.x, LookAt_vector.y, LookAt_vector.z, LookUp_vector.x, LookUp_vector.y, LookUp_vector.z ); glutTimerFunc(1000 / FPS, timer, v); glutPostRedisplay(); } void reshape(GLsizei width, GLsizei height) { if (height * ratio <= width) width = ratio * height; else height = width / ratio; glViewport(0, 0, width, height); } void PrintVector(vec3 vec) { printf("%.2f %.2f %.2f\n", vec.x, vec.y, vec.z); } void MoveForward() { mat4x4 mt; vec3 v = LookAt_vector - CameraPosition; v = normalize(v); v.y = 0.f; v = v * (currentSpeed * (float)MOVING_CONST); mt = translate(mat4x4(1.f), v); LookAt_vector = mt * LookAt_vector; CameraPosition = mt * CameraPosition; } void MoveBackward() { mat4x4 mt; vec3 v = LookAt_vector - CameraPosition; v.y = 0.f; v = normalize(v); v = -v * (currentSpeed * (float)MOVING_CONST); mt = translate(mat4x4(1.f), v); LookAt_vector = mt * LookAt_vector; CameraPosition = mt * CameraPosition; } void MoveLeft() { mat4x4 mt; vec3 f = LookAt_vector - CameraPosition; vec3 w = cross(LookUp_vector, f); w = normalize(w); w = w * (currentSpeed * (float)MOVING_CONST); mt = translate(mat4x4(1.f), w); CameraPosition = mt * CameraPosition; LookAt_vector = mt * LookAt_vector; } void MoveRight() { mat4x4 mt; vec3 f = LookAt_vector - CameraPosition; vec3 w = cross(LookUp_vector, f); w = normalize(w); w = -w * (currentSpeed * (float)MOVING_CONST); mt = translate(mat4x4(1.f), w); CameraPosition = mt * CameraPosition; LookAt_vector = mt * LookAt_vector; } void TurnLeft() { mat4x4 mt, identityMat, mt1, mt2, mtr; identityMat = mat4x4(1.f); mt1 = translate(identityMat, vec3(CameraPosition.x, CameraPosition.y, CameraPosition.z)); mtr = rotate(identityMat, ROTATION_CONST, vec3(0.f, 1.f, 0.f)); mt2 = translate(identityMat, vec3(-CameraPosition.x, -CameraPosition.y, -CameraPosition.z)); mt = mt1 * mtr * mt2; LookAt_vector = mt * LookAt_vector; arrowRotate += ROTATION_CONST; } void TurnRight() { mat4x4 mt, identityMat, mt1, mt2, mtr; identityMat = mat4x4(1.f); mt1 = translate(identityMat, vec3(CameraPosition.x, CameraPosition.y, CameraPosition.z)); mtr = rotate(identityMat, -ROTATION_CONST, vec3(0.f, 1.f, 0.f)); mt2 = translate(identityMat, vec3(-CameraPosition.x, -CameraPosition.y, -CameraPosition.z)); mt = mt1 * mtr * mt2; LookAt_vector = mt * LookAt_vector; arrowRotate -= ROTATION_CONST; } void TurnUp() { mat4x4 mt, mt1, mt2, mtr; vec3 f = LookAt_vector - CameraPosition; vec3 w = cross(f, LookUp_vector); w = normalize(w); if (upDownAngle + ROTATION_CONST < (float)M_PI_2) { mt1 = translate(mat4x4(1.f), vec3(-CameraPosition.x, -CameraPosition.y, -CameraPosition.z)); mtr = rotate(mat4x4(1.f), ROTATION_CONST, w); mt2 = translate(mat4x4(1.f), vec3(CameraPosition.x, CameraPosition.y, CameraPosition.z)); mt = mt2 * mtr * mt1; LookAt_vector = mt * LookAt_vector; upDownAngle += ROTATION_CONST; } } void TurnDown() { mat4x4 mt, mt1, mt2, mtr; vec3 f = LookAt_vector - CameraPosition; vec3 w = cross(f, LookUp_vector); w = normalize(w); if (upDownAngle - ROTATION_CONST > (float)-M_PI_2) { mt1 = translate(mat4x4(1.f), vec3(-CameraPosition.x, -CameraPosition.y, -CameraPosition.z)); mtr = rotate(mat4x4(1.f), -ROTATION_CONST, w); mt2 = translate(mat4x4(1.f), vec3(CameraPosition.x, CameraPosition.y, CameraPosition.z)); mt = mt2 * mtr * mt1; LookAt_vector = mt * LookAt_vector; // LookUp_vector = mt * LookUp_vector; upDownAngle -= ROTATION_CONST; } } void SpeedUp() { if (currentSpeed < 5) ++currentSpeed; } void SpeedDown() { if (currentSpeed > 0) --currentSpeed; } void initGL(void) { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); } void mousePress(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { //FUNKCIJA } break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) { //FUNKCIJA } break; default: break; } } void keyPress(unsigned char key, int x, int y) { switch (key) { case 27: //ESC key exit(0); break; case 'w': if (angleZakrivi < M_PI / 7) { angleZakrivi += M_PI / 20; } break; case 's': if (angleZakrivi > -M_PI / 7) { angleZakrivi -= M_PI / 20; } break; case 'a': angle += M_PI / 20; break; case 'd': angle -= M_PI / 20; break; } } /*--------------------------------------------------*/ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(height * ratio, height); glutInitWindowPosition(150, 50); glutCreateWindow(title); createCoordinates(); glutDisplayFunc(display); glutTimerFunc(100, timer, 0); glutReshapeFunc(reshape); glutMouseFunc(mousePress); glutKeyboardFunc(keyPress); initGL(); glutMainLoop(); return 0; }