/* * OGL01Shape3D.cpp: 3D Shapes */ #include // GLUT, include glu.h and gl.h #include #include "vector4d.h" #include "matrix4x4.h" #include using namespace std; /* Global variables */ #define PI 3.1415926535898 char title[] = "I Kolokvijum"; vector< vector > cylinder; Vector3D kooPoc = Vector3D(0.0,0.0,0.0); Vector3D xAxis = Vector3D(1.0,0.0,0.0); Vector3D yAxis = Vector3D(0.0,1.0,0.0); Vector3D zAxis = Vector3D(0.0,0.0,1.0); void Transform(vector &a, Matrix4x4 &T) { for(int i = 0; i < (int)a.size(); i++) T.Transform(a[i]); } void Transform(vector &a, Matrix4x4 &T) { for(int i = 0; i < (int)a.size(); i++) T.Transform(a[i]); } void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling } void drawCoordinates() { // glColor3f(1.0f, 0.0f, 0.0f); // Red // Matrix4x4 MT; // Vector3D arrow1; // Vector3D arrow2; // double arrowLength = 0.1; // glBegin(GL_LINES); // // X axis // glVertex3d(0.0, 0.0, 0.0); // glVertex3d(Vector3D::AxisX.X(),Vector3D::AxisX.Y(),Vector3D::AxisX.Z()); // arrow1.Set(1.0 - arrowLength, 0.0, 0.0); // MT.loadRotate(Vector3D::AxisX, Vector3D::AxisZ, PI/6.0); // MT.Transform(arrow1); // arrow2.Set(1.0 - arrowLength, 0.0, 0.0); // MT.loadRotate(Vector3D::AxisX, Vector3D::AxisZ, -PI/6.0); // MT.Transform(arrow2); // glVertex3d(Vector3D::AxisX.X(),Vector3D::AxisX.Y(),Vector3D::AxisX.Z()); // glVertex3d(arrow1.X(), arrow1.Y(), arrow1.Z()); // glVertex3d(Vector3D::AxisX.X(),Vector3D::AxisX.Y(),Vector3D::AxisX.Z()); // glVertex3d(arrow2.X(), arrow2.Y(), arrow2.Z()); // // Y axis // glVertex3d(0.0, 0.0, 0.0); // glVertex3d(Vector3D::AxisY.X(),Vector3D::AxisY.Y(),Vector3D::AxisY.Z()); // arrow1.Set(0.0, 1.0 - arrowLength, 0.0); // MT.loadRotate(Vector3D::AxisY, Vector3D::AxisX, PI/6.0); // MT.Transform(arrow1); // arrow2.Set(0.0, 1.0 - arrowLength, 0.0); // MT.loadRotate(Vector3D::AxisY, Vector3D::AxisX, -PI/6.0); // MT.Transform(arrow2); // glVertex3d(Vector3D::AxisY.X(),Vector3D::AxisY.Y(),Vector3D::AxisY.Z()); // glVertex3d(arrow1.X(), arrow1.Y(), arrow1.Z()); // glVertex3d(Vector3D::AxisY.X(),Vector3D::AxisY.Y(),Vector3D::AxisY.Z()); // glVertex3d(arrow2.X(), arrow2.Y(), arrow2.Z()); // // Z axis // glVertex3d(0.0, 0.0, 0.0); // glVertex3d(Vector3D::AxisZ.X(),Vector3D::AxisZ.Y(),Vector3D::AxisZ.Z()); // arrow1.Set(0.0, 0.0, 1.0 - arrowLength); // MT.loadRotate(Vector3D::AxisZ, Vector3D::AxisX, PI/6.0); // MT.Transform(arrow1); // arrow2.Set(0.0, 0.0, 1.0 - arrowLength); // MT.loadRotate(Vector3D::AxisZ, Vector3D::AxisX, -PI/6.0); // MT.Transform(arrow2); // glVertex3d(Vector3D::AxisZ.X(),Vector3D::AxisZ.Y(),Vector3D::AxisZ.Z()); // glVertex3d(arrow1.X(), arrow1.Y(), arrow1.Z()); // glVertex3d(Vector3D::AxisZ.X(),Vector3D::AxisZ.Y(),Vector3D::AxisZ.Z()); // glVertex3d(arrow2.X(), arrow2.Y(), arrow2.Z()); // glEnd(); //x osa glBegin(GL_LINES); glColor3d(1.0,0.0,0.0); glVertex3d(kooPoc.X(),kooPoc.Y(),kooPoc.Y()); glVertex3d(xAxis.X(),xAxis.Y(),xAxis.Z()); glEnd(); //y osa glBegin(GL_LINES); glColor3d(1.0,0.0,0.0); glVertex3d(kooPoc.X(),kooPoc.Y(),kooPoc.Y()); glVertex3d(yAxis.X(),yAxis.Y(),yAxis.Z()); glEnd(); //z osa glBegin(GL_LINES); glColor3d(1.0,0.0,0.0); glVertex3d(kooPoc.X(),kooPoc.Y(),kooPoc.Y()); glVertex3d(zAxis.X(),zAxis.Y(),zAxis.Z()); glEnd(); } void prepareFirstCylinderNodes(double r, double h, GLint circle_points) { cylinder[0].resize(2*circle_points); for (int i = 0; i < circle_points; i++) { double angle = 2*PI*i/circle_points; Vector3D v1(r*cos(angle),r*sin(angle), 0.0); Vector3D v2(r*cos(angle),r*sin(angle), h); cylinder[0][i] = v1; cylinder[0][circle_points + i] = v2; } } void drawCylinder(vector points) { int n = points.size()/2.0; glBegin(GL_POLYGON); for(int i = 0; i < n; i++) glVertex3d(points[i].X(), points[i].Y(), points[i].Z()); glEnd(); glBegin(GL_POLYGON); for(int i = n; i < 2.0*n; i++) glVertex3d(points[i].X(), points[i].Y(), points[i].Z()); glEnd(); glBegin(GL_QUAD_STRIP); for(int i = 0; i < n; i++) { glVertex3d(points[i].X(), points[i].Y(), points[i].Z()); glVertex3d(points[n+i].X(), points[n+i].Y(), points[n+i].Z()); } glEnd(); } void prepareCylinder(vector &v, double phi) { Matrix4x4 MT; MT.loadRotateY(phi); v = cylinder[0]; Transform(v, MT); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); drawCoordinates(); int n = 5; cylinder.resize(n); double angle = 2*PI / n; int cyrcle_points = 36; double r = 0.1; double h = 1.0; prepareFirstCylinderNodes(r, h, cyrcle_points); for(int i = 1; i < n; i++) { prepareCylinder(cylinder[i], i*angle); } Vector3D rotation_axis; Vector3D second; second.Set(0.0, 0.0, h); Matrix4x4 MT, M1, M2, M3; MT.loadRotateY(angle); MT.Transform(second); rotation_axis = second.Cross(Vector3D::AxisY); rotation_axis.Normalize(); M1.identity(); M2.identity(); M3.identity(); M1.loadTranslate(-second.X(), -second.Y(), -second.Z()); M3.loadTranslate(second.X(), second.Y(), second.Z()); M2.loadRotateAboutAxisThroughOrigin(rotation_axis, -PI*0.5); MT = M3 * M2 * M1; for(int i = 0; i < n; i++) Transform(cylinder[i], MT); glColor3f(1.0f, 1.0f, 1.0f); // White for(int i = 0; i < n; i++) { drawCylinder(cylinder[i]); } glutSwapBuffers(); // Swap the front and back frame buffers (double buffering) } void reshape(GLsizei width, GLsizei height) { if (height == 0) height = 1; // To prevent divide by 0 GLfloat aspect = (GLfloat)width / (GLfloat)height; glViewport(0-0.5, 0-0.5, width-0.5, height-0.5); glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix glLoadIdentity(); // Reset gluPerspective(80.0f, aspect, 0.1f, 20.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.5,2.0,3.0, 0.0,0.0,0.0, 0.0,1.0,0.0); } int main(int argc, char** argv) { glutInit(&argc, argv); // Initialize GLUT glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode glutInitWindowSize(640, 480); // Set the window's initial width & height glutInitWindowPosition(50, 50); // Position the window's initial top-left corner glutCreateWindow(title); // Create window with the given title glutDisplayFunc(display); // Register callback handler for window re-paint event glutReshapeFunc(reshape); // Register callback handler for window re-size event initGL(); // Our own OpenGL initialization glutMainLoop(); // Enter the infinite event-processing loop return 0; }