OpenGL Getting Started Tutorial 5

Source: Internet
Author: User

Do you think the scope of our drawing is too narrow when we draw the geometry in front of us? Coordinates can only be from 1 to 1, and can only be X
Axis to the right, Y axis up, vertical Z-axis screen. These restrictions have brought a lot of inconvenience to our drawings.
We live in a three-dimensional world-if we want to observe an object, we can:
1, from a different position to observe it. (View transform)
2, move or rotate it, of course, if it is only the object inside the computer, we can also enlarge or reduce it. (Model Transformation)
3, if the object is drawn down, we can choose: whether a "near-large far small" perspective effect is required. In addition, we may only want to see
Part of an object, not all (clipping). (Projection transformation)
4. We may want to draw the entire picture, but it only occupies part of the paper, not all of it. (Viewport transform)
All of this can be achieved in OpenGL.
OpenGL transforms are actually implemented by matrix multiplication. Whether it's moving, rotating, or scaling, it's all through the base of the current matrix
A new matrix to achieve the goal. Knowledge about matrices, not detailed here, interested friends can look at linear algebra
(Most of the students ' words should have been learned).
OpenGL can operate the matrix directly at the lowest level, but as a beginner, this does not make much sense. There is no introduction here.
1. Model Transformation and view transformation
From the point of view of "relative movement", it is equivalent to change the position and direction of the observer and change the position and direction of the object itself.
In OpenGL, these two functions are implemented even using the same functions.
Since both the model and the view transform are implemented by matrix operations, the matrix of the current operation should be set to "model" before the transformation.
View Matrix. The method to set is to call the Glmatrixmode function as a gl_modelview parameter, like this:
Glmatrixmode (Gl_modelview);
In general, we need to set the current matrix to the unit matrix before making the transformation. This also requires one line of code:
Glloadidentity ();
Then, you can make model transformations and view transformations. The model and view transformations are mainly related to three functions:
gltranslate*, multiplies the current matrix and a matrix that represents the moving object. The three parameters represent the three coordinates of the
The displacement value.
glrotate*, multiplies the current matrix and a matrix that represents a rotating object. The object will go around (0,0,0) to the inverse of (x, y, z) lines
Needle rotation, the parameter angle represents the angle of rotation.
glscale*, multiplies the current matrix and a matrix that represents the scaling object. x, y, and Z indicate the scaling in that direction, respectively.
Note that I mean "multiply with XX" instead of just saying "This function is spinning" or "This function is moving", which is a
For a reason, it will be said right away.
Suppose the current matrix is a unit matrix, and then multiply by a matrix R representing rotation, multiplied by a matrix T representing the move,
The resulting matrix is then multiplied by the coordinate matrix V of each vertex. So, the vertex coordinates that are transformed are ((RT) v).
Because of the binding rate of matrix multiplication ((RT) v) = (R (Tv)), in other words, it is actually moved first and then rotated. That
The order of the actual transformations is reversed from the order in which the code is written. Results from "Move first, then rotate" and "move after first"
Probably different, you need to pay special attention to this when you are beginners.
OpenGL is designed to be more efficient. But when drawing complex three-dimensional graphics, if you go every time
It is also painful to consider how to turn the transformation upside down. Here's another way to make your code look more natural (write
The code is exactly the same, but the method used to consider the problem is different.
Let us imagine that the coordinates are not constant. When rotated, the coordinate system rotates with the object. When moving, the coordinates
The system moves with the object. This way, there is no need to consider the sequential reversal of the code.
All of these are introduced to change the position and direction of the object. If you want to change the location of the observer, in addition to working with glrotate*
And the gltranslate* function, you can also use this function: Glulookat. It has more parameters, the first three parameters indicate
The position of the observer point, the middle three parameters indicate the position of the observation target, and the last three parameters represent the straight line from (0,0,0) to (x, Y, z).
It represents the "up" direction that the Observer thinks.
2. Projection transformation
A projection transformation is defined as a visual space in which objects outside the visual space are not drawn to the screen. (Note that from now on, coordinates can be
It's no longer 1.0 to 1.0! )
OpenGL supports two types of projection transformations, perspective projection and orthographic projection. Projections are also implemented using matrices. If an operation is required
The Glmatrixmode function needs to be called with the Gl_projection parameter.
Glmatrixmode (gl_projection);
In general, we need to set the current matrix to the unit matrix before making the transformation.
Glloadidentity ();
The perspective projection produces results similar to a photo, with a near-large effect, such as a picture of a railroad track in front of the locomotive, two iron
The rails seemed to intersect in the distance.

Use the Glfrustum function to set the current visual space as a perspective projection space. The meaning of its parameters is as follows

Disclaimer: The picture is from www.opengl.org, which is the drawing of the book "OpenGL Programming Guide", due to the old version of the book (first edition,
1994) is already circulating in the network, I hope not to touch the copyright issue.

You can also use the more commonly used gluperspective function. The meaning of its parameters is as follows:


Disclaimer: The picture is from www.opengl.org, which is the drawing of the book "OpenGL Programming Guide", due to the old version of the book (first edition,
1994) is already circulating in the network, I hope not to touch the copyright issue.
The positive projection is equivalent to the result observed in an infinite distance, it is only an ideal state. For computers, however, it is possible to use a positive projection
Get a better run speed.

Use the Glortho function to set the current visual space as a positive projection space. The meaning of its parameters is as follows


Disclaimer: The picture is from www.opengl.org, which is the drawing of the book "OpenGL Programming Guide", due to the old version of the book (first edition,
1994) is already circulating in the network, I hope not to touch the copyright issue.
If the drawing space itself is two-dimensional, you can use gluortho2d. His use is similar to Glorgho.
3. Viewport transform
When everything is ready, just draw the pixel to the screen. There is one last question: The pixel should be painted
Which area of the window is to be made? Normally, the default is to fill the entire window completely, but we can just fill in half.

(That is, the entire image is filled in half of the window)


Disclaimer: The picture is from www.opengl.org, which is the drawing of the book "OpenGL Programming Guide", as the old version of the book
(The first edition, 1994) is already circulating on the Internet, and I hope it doesn't touch the copyright issue.
Use Glviewport to define viewports. The first two parameters define the left bottom of the viewport (0,0 represents the leftmost bottom), and the second two
The parameters are width and height, respectively.
4. Operation Matrix Stack
Somewhere in the beginning tutorial, let's start with a brief introduction to the stack. You can think of stacks as a stack of plates. At first, a plate was
No, you can put it on one or the other. Every time it's taken, it's the last time it's been put on.
Plate. Typically, when the computer implements the stack, the capacity of the stack is limited, and if there are too many plates, an error occurs. Of course, such as
If there is no plate, then ask for a plate, it will be wrong.
When we are doing a matrix operation, it is possible to save a matrix before recovering it over a period of time. When we need to save,
Call the Glpushmatrix function, which is equivalent to putting a matrix (equivalent to a plate) on the stack. When you need to restore the last
When stored, call the Glpopmatrix function, which is equivalent to removing the matrix from the stack. OpenGL specifies that the capacity of the stack can at least
Holds 32 matrices, and in some OpenGL implementations, the stack's capacity actually exceeds 32. So don't worry too much about matrices
Capacity issues.
Usually, it is more convenient and quicker to use this kind of recovery after saving than to change and reverse the transformation first.
Note: Both the Model View matrix and the projection matrix have a corresponding stack. Use Glmatrixmode to specify whether the current operation is a modulo
Type view matrix or a projection matrix.
5. Comprehensive examples
Well, the beginning of the view transformation is almost done. But we can't just end it like this. Because the content of this course is really
Too dull, if the separate example, may be ineffective. I have to say a comprehensive example, to give you a reference. To
In the actual grasp, but also rely on the people themselves to spend Kung fu. Gossip less, now get to the point.
We're going to make a three-dimensional scene that includes the sun, the Earth, and the moon. Suppose that there are 12 months in a year, 30 days a month.
Every year, the Earth goes round the sun. Every month the moon revolves around the Earth. That is, there are 360 days in a year. Now give the date of the
Number (0~359), which requires plotting the relative position of the sun, Earth, and Moon. (This is designed for ease of programming
Of If you need to make a more realistic case, it's just a matter of numerical processing, not with OpenGL.
First, let us assume that the three celestial bodies are spherical, and that their trajectories are in the same horizontal plane, establishing the following coordinate system:
The center of the sun is the origin, and the plane of the celestial trajectory represents the plane of the X-axis and the y-axis, and on the first day of the year, the Earth
X-Axis square upward, the moon in the Earth's positive x-axis direction.
The next step is to establish a visual space. Note: The sun's radius is much shorter than the distance from the sun to the earth. If we use the day directly
The size of the sun will be ignored when the entire window represents the size of the Earth's orbit. Therefore, we
It can only multiply the radius of several celestial bodies to suit the needs of our observation. (Baidu, get the sun, the Earth, the moon
Approximate radii are: 696000km,6378km,1738km. The distance from the Earth to the sun is about 150 million km=150000000km,
The distance between the moon and the Earth is about 380000km. )
Let's imagine some data that would "modify" the radius of three celestial bodies to: 69600000 (100 times times magnification), 15945000 (Put
2,500 times times larger), 4345000 (magnified 2,500 times times). The distance from the Earth to the moon is "modified" to 38000000 (magnified 100 times times).
The distance between the Earth and the sun remains the same.
In order for the Earth and the moon to be close to us, we still do not need to change the observation points and observe the direction to observe them, I
We put the observation point in this position: (0,-200000000, 0)--because the Earth's orbital radius is 150000000, we'll make a whole,
Take-200000000 is available. The observation target is set to the origin (i.e. the center of the Sun), and the Z axis is selected as the "Up" side. Of course
We can also move the observation point toward the "up" side to get (0,-200000000, 200000000) so that you can get a 45 degree angle
The top effect.
To get a perspective, we use Gluperspective to set the visual space. Suppose the angle of view is 60 degrees (if you are debugging
found that the angle is not appropriate, can be modified. The number I chose at the end was 75. ), the aspect ratio is 1.0. The nearest visible distance is 1.0,
The furthest visible distance is 200000000*2=400000000. namely: Gluperspective (60, 1, 1, 400000000);
Now let's take a look at how to draw these three celestial bodies.
For the sake of simplicity, we think of the three celestial bodies as a regular sphere. And in the glut utility we're using, it's just
There is a ready-made function for drawing a sphere: Glutsolidsphere, which draws a sphere at the "origin". Since coordinates are available
by gltranslate* and glrotate* two functions for arbitrary transformation, so we can draw the sphere in any position.
The function has three parameters: the first parameter represents the radius of the sphere, and the latter two represent the number of "faces", and the simple point is that the ball
The greater the accuracy of the body, the more accurate the value, of course, the slower the speed. Here we just simply set the latter two parameters
Number is 20.
The sun is at the origin of the coordinates, so you don't have to go through any transformations and draw directly.
The earth is a little more complicated and needs to transform coordinates. Since the number of days that have elapsed this year is known as Day, the Earth turns over at an angle of
day/Days of the year * 360 degrees. It has been assumed that each year is 360 days, so the earth turns around at exactly the right angle. So
The following code can be used to resolve:
Glrotatef (day, 0, 0,-1);
/* Note that the Earth's revolution is "from west to East", so it rotates counterclockwise in the negative direction of the Z axis * *
Gltranslatef (Earth orbit radius, 0, 0);
Glutsolidsphere (Earth radius, 20, 20);
The moon is the most complex. Because it not only revolves around the Earth, but also moves around the sun as the earth goes. But if we choose the earth as the reference
, the movement of the Moon is a simple circular motion. If we draw the Earth first and then draw the moon, we just
To make transformations with the Earth class:
Glrotatef (angle of rotation of the moon, 0, 0,-1);
Gltranslatef (moon orbital radius, 0, 0);
Glutsolidsphere (moon radius, 20, 20);
But this "moon rotation angle", and can not be simply understood as day/one months of the days 30*360 degrees. Because we're drawing the ground
Ball, this coordinate is already rotated. The current rotation is rotated on a previous basis, so it is also necessary to deal with this "poor
Value ". We can write: Day/30*360-day, minus the original angle that has been turned. It's just a simple deal, when
You can also save the matrix with Glpushmatrix before drawing the earth and use Glpopmatrix to restore the matrix after drawing the Earth. Then design a
A moon position formula unrelated to the Earth's position to draw the moon. The latter method is usually better than the previous one because the floating
It is imprecise, that is to say, we calculate the position of the Earth itself is imprecise. Take this imprecise number to calculate the moon's
Position, resulting in "imprecise" accumulation of ingredients, too much "imprecise" can cause errors. Our little program didn't think about it.
, but it is not that this is not a matter of importance.
Another detail to note: OpenGL draws objects in three-dimensional coordinates to a two-dimensional screen, in the order in which they are plotted
The order of the Code. The object that is drawn after it is then obscured, even if the object was first drawn
The same is true of "back". This problem can be solved by using a depth test. The method used is: 1, to Gl_depth_test
Call the Glenable function for the parameter to start the depth test. 2, when necessary (usually at the beginning of each drawing screen), clear the depth
Glclear (Gl_depth_buffer_bit), where Glclear (Gl_color_buffer_bit) and
Glclear (Gl_depth_buffer_bit) can be combined to write as:
Glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit);
and the latter may run faster than the former.
So far, we can finally get the complete code for the whole "sun, Earth and Moon" system.
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)
{
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 ();
}
Try changing the value of day to see how the picture changes.
Summary: At the beginning of this lesson, we formally entered the three-dimensional OpenGL world.
OpenGL transforms a three-dimensional object into a two-dimensional image through a matrix transformation, which is then displayed on the screen. In order to specify the current operating
What kind of matrix do we use, the function Glmatrixmode.
We can move, rotate, or move or rotate an object, using the functions gltranslate* and glrotate*.
We can scale the object, and the function used is glscale*.
We can define the visual space, which can be a "positive projection" (using Glortho or gluortho2d), or a "transparent
(using Glfrustum or gluperspective).
We can define the scope of the drawing to the window, and the function used is glviewport.
The matrix has its own "stack" for easy saving and recovery. This is useful when drawing complex graphics. The function used is
Glpushmatrix and Glpopmatrix.
Well, the hard lesson is finally over. I know that the content of this lesson is very dull, even the last example is. But neither did I.
Better way, I hope you can stick to the past. Do not worry, familiar with the course content, after a period of time, will be
It's easier and more enjoyable.

OpenGL Getting Started Tutorial 5

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.