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 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(); }