תוכנית OpenGL לאנימציה פשוטה (מהפכה) ב-C

OpenGL הוא API חוצה פלטפורמות חוצה שפות לעיבוד גרפיקה וקטורית דו-ממדית ותלת-ממדית. באמצעות זה אנחנו יכולים לעשות הרבה עיצוב כמו גם אנימציות. להלן האנימציה הפשוטה שנעשתה באמצעות OpenGL .
גישה:  
כדי לגרום לתמונה לזוז עלינו להבין את הליך העבודה של פונקציה המשמשת להצגת כלומר glClear(GL_COLOR_BUFFER_BIT) . המשימה שלו היא לנקות מסך עם ערך ברירת מחדל לאחר זמן מסוים (בדרך כלל לאחר 1/30 שנייה או 1/60 שנייה). אז אם יתרחש שינוי כלשהו בקואורדינטה אז נראה שהוא זז מכיוון שהעין האנושית יכולה להבחין רק בתמונה שמופרדת על ידי 1/16 שנייה (התמדה של הראייה).
כעת הקואורדינטות של המעגל הן X = r*cos(?) ו-Y = r*sin(?) או עבור אליפסה X = rx*cos(?) ו-Y = ry*cos(?) כאשר rx ו-ry הם רדיוס בכיוון X- ו-Y- ו ? היא הזווית. 
אם נשתנה ? מ-0 ל-2*pi (360 מעלות) בעלייה קטנה מאוד (נניח של מעלה אחת) וצייר נקודה על הקואורדינטה הזו נוכל ליצור עיגול שלם או אליפסה. אנחנו יכולים גם ליצור חצי עיגול או כל קשת של עיגול או אליפסה על ידי שינוי ערך ההתחלה והסיום של ? (זָוִית).
מושגים אלה משמשים לצייר את ההנפשה הבאה: 
 

  • 7 חלקים אופקיים של אליפסה ו-3 אליפסות שלמות אנכיות וכן עיגול חיצוני אחד ואליפסה חיצונית אחת משמשים לדמיין מסלול שצויר על ידי כוונון ? כמו גם רדיוס.
  • קו אנכי אחד מצויר כדי ליצור את הדמות. ואז כדי לגרום לו לזוז ניתנת לולאה אחרת שבה הערך של j משתנה בכמות קטנה מאוד כדי להפוך את התנועה לחלקה יותר.
  • מכיוון שהיינו צריכים לגרום לכל הנקודה לנוע באותו סוג של תנועה כדי לשמור על הדמות יחד, כך שמשוואת התנועה היא Glyx2i(x/2 - 600*cos(j) של/2 - 100*sin(j)) ניתן בתוך כל פנימי עבור לולאה כך שניתן ליישם אותו על כל הנקודות לגמרי.


לעבודה על מערכת הפעלה אובונטו:  
 

  gcc filename.c -lGL -lGLU -lglut -lm   where filename.c is the name of the file with which this program is saved. 


 


להלן היישום ב-C.
 

C
   // C Program to illustrate    // OpenGL animation for revolution   #include      #include      #include      // global declaration   int     x       y  ;   float     i       j  ;   // Initialization function   void     myInit     (  void  )   {      // Reset background color with black (since all three argument is 0.0)      glClearColor  (  0.0       0.0       0.0       1.0  );          // Set picture color to green (in RGB model)      // as only argument corresponding to G (Green) is 1.0 and rest are 0.0      glColor3f  (  0.0       1.0       0.0  );          // Set width of point to one unit      glPointSize  (  1.0  );      glMatrixMode  (  GL_PROJECTION  );      glLoadIdentity  ();          // Set window size in X- and Y- direction      gluOrtho2D  (  -780       780       -420       420  );   }   // Function to display animation   void     display     (  void  )   {      // Outer loop to make figure moving      // loop variable j iterated up to 10000      // indicating that figure will be in motion for large amount of time      // around 10000/6.29 = 1590 time it will revolve      // j is incremented by small value to make motion smoother      for     (  j     =     0  ;     j      <     10000  ;     j     +=     0.01  )      {      glClear  (  GL_COLOR_BUFFER_BIT  );      glBegin  (  GL_POINTS  );          // Iterate i up to 2*pi i.e. 360 degree      // plot point with slight increment in angle      // so it will look like a continuous figure      // Loop is to draw outer circle      for     (  i     =     0  ;  i      <     6.29  ;  i     +=     0.001  )      {      x     =     200     *     cos  (  i  );      y     =     200     *     sin  (  i  );      glVertex2i  (  x       y  );          // For every loop 2nd glVertex function is      // to make smaller figure in motion      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          // 7 loops to draw parallel latitude      for     (  i     =     1.17  ;     i      <     1.97  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -150     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.07  ;     i      <     2.07  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -200     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.05  ;     i      <     2.09  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -250     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.06  ;     i      <     2.08  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -300     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.10  ;     i      <     2.04  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -350     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.16  ;     i      <     1.98  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -400     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     1.27  ;     i      <     1.87  ;     i     +=     0.001  )      {      x     =     400     *     cos  (  i  );      y     =     -450     +     300     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          // Loop is to draw vertical line      for     (  i     =     200  ;     i     >=-     200  ;     i  --  )      {      glVertex2i  (  0       i  );      glVertex2i  (  -600     *     cos  (  j  )     i     /     2     -     100     *     sin  (  j  ));      }          // 3 loops to draw vertical ellipse (similar to longitude)      for     (  i     =     0  ;  i      <     6.29  ;     i     +=     0.001  )      {      x     =     70     *     cos  (  i  );      y     =     200     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     0  ;     i      <     6.29  ;     i     +=     0.001  )      {      x     =     120     *     cos  (  i  );      y     =     200     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          for     (  i     =     0  ;     i      <     6.29  ;     i     +=     0.001  )      {      x     =     160     *     cos  (  i  );      y     =     200     *     sin  (  i  );      glVertex2i  (  x       y  );      glVertex2i  (  x     /     2     -     600     *     cos  (  j  )     y     /     2     -     100     *     sin  (  j  ));      }          // Loop to make orbit of revolution      for     (  i     =     0  ;     i      <     6.29  ;     i     +=     0.001  )      {      x     =     600     *     cos  (  i  );      y     =     100     *     sin  (  i  );      glVertex2i  (  x       y  );      }      glEnd  ();      glFlush  ();      }   }   // Driver Program   int     main     (  int     argc       char  **     argv  )   {      glutInit  (  &  argc       argv  );          // Display mode which is of RGB (Red Green Blue) type      glutInitDisplayMode  (  GLUT_SINGLE     |     GLUT_RGB  );          // Declares window size      glutInitWindowSize  (  1360       768  );          // Declares window position which is (0 0)      // means lower left corner will indicate position (0 0)      glutInitWindowPosition  (  0       0  );      // Name to window      glutCreateWindow  (  'Revolution'  );      // Call to myInit()      myInit  ();      glutDisplayFunc  (  display  );      glutMainLoop  ();   }   


 

צור חידון