PENGL Introductory Study (VI)

Source: Internet
Author: User

http://blog.csdn.net/sun6255028/article/details/5090067

Today is about animation--probably everyone loves it. In addition to teaching knowledge, we will let yesterday's "Sun, Earth and Moon" celestial drawing moving up. Ease the dull atmosphere.


This course, we will enter the exciting world of computer animation.

We all know how movies and animations work, right? Yes, a picture of a seemingly continuous picture is displayed in front of people quickly. Once there are more than 24 images per second, people will mistakenly assume that it is continuous.
We usually watch the TV play 25 or 30 frames per second. But for a computer, it can play more pictures to achieve smoother results. If the speed is too slow, the picture is not smooth enough. If the speed is too fast, then the human eye may not be able to respond to come over. It is more appropriate for a normal person to 60~120 a picture per second. Specific values vary from person to person.

Assuming that an animation has a total of n images, its working steps are:
Display the 1th picture and wait for a short period of time until the next 1/24 seconds
Display the 2nd picture and wait for a short period of time until the next 1/24 seconds
......
Display the nth screen and wait for a short period of time until the next 1/24 seconds
End
If you use C pseudo-code to describe this process, it is:
for (i=0; i<n; ++i)
{
Drawscene (i);
Wait ();
}


1. Double Buffering Technology
The animation on the computer is somewhat different from the actual animation: The actual animation is drawn first, and when it is played, it is displayed directly on the line. Computer animation is to draw a picture, take out a picture, and then draw the next one, and then take out. If the graphics you need to draw are simple, then that's fine. But once the graphics are complex and the drawing takes longer, the problem becomes more pronounced.
Let's think of the computer as a fast-drawing person, if he is drawing directly on the screen, and the graphic is more complex, it is possible that he only painted a picture half of the time is seen by the audience. But the back although he fill the painting, but the audience's eyes did not respond, but also stay in the original picture of the incomplete. In other words, sometimes the audience can see the complete image, and sometimes only see the incomplete image, which causes the screen to blink.
How to solve this problem? We imagine that there are two of artboards, drawing people on the side of the painting, painting, and then the drawing board in his hand and hanging on the screen to exchange the artboard. In this way, the audience will not see the incomplete painting. This technique is applied to computer graphics, called double buffering technology. That is: In the memory (most likely the memory) to open up two areas, a piece as the data sent to the display, a piece as a painting area, exchange them at the appropriate time. Since swapping two areas of memory actually only requires exchanging two pointers, this method is very efficient and is widely used.
Note: While the vast majority of platforms support dual-buffering technology, this technique is not the content of the OpenGL standard. OpenGL, in order to ensure better portability, allows the implementation without the use of double buffering technology. Of course, our commonly used PCs are supported by dual buffering technology.
The simplest way to start the double buffering function is to use the GLUT toolkit. We used to write in the main function:
Glutinitdisplaymode (Glut_rgb | Glut_single);
Where Glut_single represents a single buffer, if changed to Glut_double is double buffering.
And of course there's a need to change--each time we draw, we need to swap two buffers and use the information we've drawn to display it on the screen (otherwise, no matter how it's drawn or what we can't see). If you use the GLUT Toolkit, you can easily do this, as long as you simply call the Glutswapbuffers function when the drawing is complete.


2. Achieve Continuous animation
There seems to be no doubt that we should write the code for the animation as follows:
for (i=0; i<n; ++i)
{
Drawscene (i);
Glutswapbuffers ();
Wait ();
}
But in fact, this does not conform to the window System program design ideas. Remember our first OpenGL program? We write in the main function: Glutdisplayfunc (&mydisplay);
It means to say to the system: if you need to draw a window, call the Mydisplay function. Why don't we just call Mydisplay and use this seemingly "Shejinqiuyuan" approach? The reason is--our own program doesn't know when to draw the window. Because of the general window System--to get familiar with the--windows and X Window System, it is supported to display multiple windows at the same time. If your program window happens to be obscured by another window, then the user then removes the window that was originally obscured, and your window needs to be redrawn. Unfortunately, you have no way of knowing exactly when the event happened. So all this had to be commissioned by the operating system.
Now let's look at the cycle above. Since Drawscene can be handed over to the operating system to agent, that the whole cycle of work can also be given to the operating system? The answer is yes. Our previous train of thought was: Draw, then wait for a while, draw again, and wait for some time. But if the waiting time is removed, it becomes drawing, drawing, ..., drawing. --Of course, the resources are public, antivirus software always have to work? Can't my download stop? My mp3 play still can't be delayed. We can't just stop all the other work because of our animations. Therefore, we need to draw at the time the CPU is idle.
The "Draw at CPU time" and the "draw when needed" in the first lesson are some common things that are "doing XX in xx time", and the Glut Toolkit also provides a similar function: Glutidlefunc, which indicates that a function is called at the time the CPU is idle. In fact, glut also provides some other functions, such as "do something when the keyboard is pressed".

By now, we have been able to start making animations initially. OK, take the last time the "Sun, Earth and Moon" procedure, let the Earth and the moon to move themselves.

Code:

#include <GL/glut.h>

The Sun, the Earth and the moon
Let's say every month is 30 days.
12 months a year, a total of 360 days
static int day = 200; Day change: from 0 to 359
void Mydisplay (void)
{
/****************************************************
The contents of this copy of the previous lesson, only because of the use of double buffering, to fill the last sentence
*****************************************************/
Glutswapbuffers ();
}

void Myidle (void)
{
/* New function, called at idle time, to move the date back one day and redraw it to animate the effect */
++day;
if (Day >= 360)
Day = 0;
Mydisplay ();
}

int main (int argc, char *argv[])
{
Glutinit (&AMP;ARGC, argv);
Glutinitdisplaymode (Glut_rgb | glut_double); Modified the parameter to Glut_double
Glutinitwindowposition (100, 100);
Glutinitwindowsize (400, 400);
Glutcreatewindow ("The Sun, the Earth and the Moon"); Change the window title
Glutdisplayfunc (&mydisplay);
Glutidlefunc (&myidle); New addition to this sentence
Glutmainloop ();
return 0;
}


3, about vertical synchronization
The code is written, but I believe you have questions. Some friends may find out at run time that although the CPU is almost all used, but the speed of movement is very fast, it is not clear at all, other friends at run time found that the CPU usage is very low, there is no idle time fully utilized. But for the above code, these phenomena are reasonable. This involves the problem of vertical synchronization.

We know that the display refresh rate is relatively limited, generally 60~120hz, that is, a second refresh 60~120 times. But if you call a computer to draw a simple picture, such as only one triangle, you can draw thousands of times a second. Therefore, if the maximum use of computer processing power to draw a lot of pictures, but the display does not refresh the speed, which not only caused the performance of the waste, but also may bring some negative impact (for example, the display is only half-refreshed, the need to draw the content has changed, because the display is progressive refresh, So the upper and lower parts of the monitor are actually from two images. The use of vertical synchronization technology can solve this problem. That is, only when the display is refreshed, the painted image is transmitted out for display. In this way, the computer does not have to draw a large number of images that are not used at all. If the display has a refresh rate of 85Hz, it is sufficient for the computer to draw only 85 images a second, and if the scene is simple enough, it will result in more CPU idle.
Almost all graphics cards support the "Vertical sync" feature.
Vertical synchronization also has its problems. If the refresh rate is 60Hz, when drawing a relatively simple scene, it takes a long time to draw a picture, and the frame rate can be constant at 60FPS (i.e. 60 frames per second). If the scene becomes complex, drawing a picture takes more than 1/60 seconds, the frame rate will drop sharply.
If the time to draw a picture is 1/50, the display needs to be refreshed at the first 1/60 seconds, but because the new drawing is not drawn, only the original picture can be displayed, and the new picture will be displayed until the next 1/60 seconds. So a picture was actually used for 1/30 seconds, with a frame rate of 30FPS. (The frame rate should be 50FPS if you don't use vertical sync)
If you draw a picture longer, the downward trend is a ladder: 60fps,30fps,20fps, ... (60/1,60/2,60/3, ...) )
If the complexity of each picture is inconsistent, and the time it takes to draw them is up to 1/60. Then in 1/60 time finished painting, the frame rate is 60FPS, in 1/60 time is not completed, the frame rate is 30FPS, which caused the frame rate beat. This is a very troublesome thing to avoid--either to simplify the drawing time for each picture or to delay a short period of time for unification.

Look back at the previous question. If you are using a large number of CPUs and are quickly unable to see them, turning on vertical synchronization will solve the problem. Of course, if you think that vertical synchronization has such a disadvantage, you can also turn it off. -As for how to turn on and off, it varies depending on the operating system. Please search for the specific steps yourself.

Of course, there are other ways to control the animation's frame rate, or try to make the animation as fast as possible regardless of frame rate. However, many of these things are closely related to the operating system, and they are not too much of a relationship with OpenGL. There is no introduction here.


4. Calculate frame rate
I don't know if you've ever played 3D mark. This software does not, it can run a variety of scenes, measured frame rate, and for your system to give a rating. Here I also introduce a method for calculating frame rate.
By definition, the frame rate is the number of frames (FPS) that are played in a second. We can first measure the time t between two pictures and then ask for its reciprocal. If t=0.05s, then the value of FPS is 1/0.05=20.
Theoretically so, but how to get this time? Usually the time function of the C language is typically only one second in time, and it must be out of the ordinary. The clock function is about 10 milliseconds or less. Because FPS is 60 and FPS is 100, the value of T is more than 10 milliseconds.
Do you know how to measure the thickness of a piece of paper? A rough way is: use a lot of sheets of paper stacked together to measure the thickness, the average can be calculated. We can do it here, too. Measurement of the time required to draw 50 images (including vertical synchronization and other factors such as wait time) T ', by T ' =t*50 very easy to get fps=1/t=50/t '
The following code can count the call frequency of the function itself (as the theory says), the program is not complicated, and it's not part of OpenGL, so I'm not going to tell it in detail.

Code : #include <time.h>
Double calfrequency ()
{
&NBSP;&N bsp;   static int count;
     static double save;
     Static clock_t last, current;
     double timegap;

     ++count;
     if (count <=)
         return save;
     count = 0;
     last = current;
     current = Clock ();
     timegap = (current-last)/(double) clk_tck;
     save = 50.0/timegap;
     return save;
}


Finally, we want to show the frame rate of the calculation, but we didn't learn how to use OpenGL to display the text on the screen. --but don't forget, behind our graphics window, there is a command-line window ~ You can easily output text using the printf function.
#include <stdio.h>

Double FPS = calfrequency ();
printf ("fps =%f/n", fps);
The final step, also solved by US-although the practice is not very elegant, it doesn't matter, we will improve it later.


Time too long, each time the program is only a small paragraph, some friends will inevitably have problems.
Now, I give a more complete procedure for your reference.

Code: #include <GL/glut.h>
#include <stdio.h>
#include <time.h>

The Sun, the Earth and the moon
Let's say every month is 12 days.
12 months a year, a total of 360 days
static int day = 200; Day change: from 0 to 359

Double Calfrequency ()
{
static int count;
static double save;
Static clock_t last, current;
Double Timegap;

++count;
if (Count <= 50)
return save;
Count = 0;
last = current;
current = Clock ();
Timegap = (current-last)/(double) clk_tck;
Save = 50.0/timegap;
return save;
}

void Mydisplay (void)
{
Double FPS = calfrequency ();
printf ("fps =%f/n", fps);

Glenable (gl_depth_test);
Glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit);

Glmatrixmode (gl_projection);
Glloadidentity ();
Gluperspective (75, 1, 1, 400000000);
Glmatrixmode (Gl_modelview);
Glloadidentity ();
Glulookat (0,-200000000, 200000000, 0, 0, 0, 0, 0, 1);

Draw the Red "sun"
glcolor3f (1.0f, 0.0f, 0.0f);
Glutsolidsphere (69600000, 20, 20);
Draw the Blue "Earth"
glcolor3f (0.0f, 0.0f, 1.0f);
Glrotatef (day/360.0*360.0, 0.0f, 0.0f, -1.0f);
Gltranslatef (150000000, 0.0f, 0.0f);
Glutsolidsphere (15945000, 20, 20);
Draw a yellow "moon"
glcolor3f (1.0f, 1.0f, 0.0f);
Glrotatef (day/30.0*360.0-day/360.0*360.0, 0.0f, 0.0f, -1.0f);
Gltranslatef (38000000, 0.0f, 0.0f);
Glutsolidsphere (4345000, 20, 20);

Glflush ();
Glutswapbuffers ();
}

void Myidle (void)
{
++day;
if (Day >= 360)
Day = 0;
Mydisplay ();
}

int main (int argc, char *argv[])
{
Glutinit (&AMP;ARGC, argv);
Glutinitdisplaymode (Glut_rgb | glut_double);
Glutinitwindowposition (100, 100);
Glutinitwindowsize (400, 400);
Glutcreatewindow ("The Sun, the Earth and the Moon");
Glutdisplayfunc (&mydisplay);
Glutidlefunc (&myidle);
Glutmainloop ();
return 0;
}


Summary:
OpenGL animations are similar to traditional animations in that they present a picture in front of the audience. Once the screen changes quickly, viewers will think the picture is continuous.
Double buffering technology is a widely used technology in computer graphics, and most OpenGL implementations support dual buffering technology.
Animations are usually drawn with the CPU idle, but other options are available.
The related knowledge of vertical synchronization is introduced.
A simple method for calculating frame rate (fps) is introduced.
Finally, we list a complete list of celestial animation programs.

PENGL Introductory Study (VI)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.