Nehe OpenGL Tutorial Lesson Nineth: Moving Images

Source: Internet
Author: User
Tags clear screen

Go from "translation" Nehe OpenGL tutorial

Objective

Statement, this Nehe OpenGL tutorial series of articles by 51 blog yarin Translation (2010-08-19), this blog for reprint and a little collation and modification. Thank you for compiling Nehe's OpenGL pipeline tutorial, as well as yarn translation finishing.

Nehe OpenGL Lesson Nineth: Moving Images

Moving an image in 3D space:

You want to know how to move an object in 3D space, you want to know how to draw an image on the screen, and make the background color of the image transparent, you want to have a simple animation. This lesson will teach you all about it. The previous course covered the underlying OpenGL, and each lesson was created on the basis of the previous lesson. This lesson is a combination of the previous lessons, and when you study this class, make sure you have mastered the knowledge of the previous lessons.

Welcome to the Nineth lesson. Until now, you should have a good understanding of OpenGL. "Cker: If not, it must be the sin of my translation ...". You have learned to set up each of the details of an OpenGL window. Learn to map and light and process color (transparent) on rotating objects. This lesson should be considered as an intermediate course in the first lesson. You will learn the following: Move a bitmap in a 3D scene and remove the black pixels on the bitmap (using process color). Then color the black and white textures, and finally you will learn to create rich colors and mix the textures of different colors to get a simple animation effect.
We modify the code based on the first lesson. First add a few variables at the beginning of the program source code. For the sake of clarity, I rewrote the whole piece of code.

#include <stdio.h>//Standard input/output library header file
#include <glaux.h>//Glaux Library header files

The following lines are newly added. Twinkle and TP are Boolean variables that indicate that they can only be set to TRUE or FALSE. The twinkle is used to track whether the flicker effect is enabled. TP is used to check that the ' T ' key has not been pressed or loosened. (Tp=true when pressed, Tp=false when released).

BOOL Twinkle; Twinkling stars.
BOOL TP; Did you press ' T '?

Num tracks the number of stars drawn on the screen. This number is defined as a constant. This means that it is not possible to modify it in future code. The reason for this is because you cannot redefine an array. Therefore, if we define an array of 50 stars and then add num to 51, we will get the error "Cker: array out of bounds". However, you can (and can only) modify this number on this line. But please don't change num's value again, unless you want to see a disaster happen.

Const NUM=50; Number of stars drawn

Now let's create a structure. The word structure sounds a bit scary, but it's not. A structure uses a set of simple types of data (and variables, and so on) to express a larger combination of data with similarity. We know we're keeping track of the stars. You can see that the seventh line below is stars, and each star has a color value of three integers. The third line of int r,g,b sets three integers. A red (R), a Green (g), and a blue (b). In addition, each star is a different distance from the center of the screen and can be an angle from any 360 degree point in the center of the screen. If you look at line fourth below, you will find that we use a floating-point number called Dist to keep track of the distance. The last line uses a floating-point number called angle to keep track of the star's angular value.
So we used a set of data to describe the color, distance, and angle of the stars on the screen. Unfortunately, we're not just tracking a star. But instead of creating 50 red values, 50 green values, 50 blue values, 50 distance values, and 50 angular values, just create an array of star. Each element of the star array is of star type and contains all the data that describes the stars. The star array is created on line eighth below. The eighth line looks like this: Stars Star[num]. The array type is the stars structure. The array can hold all the information of the stars structure. The array name is star. The array size is [num]. The elements in the array that hold the stars structure. It is much easier to track structural elements than to track their separate variables. But this is also very stupid, because we can not change the constant num to increase or decrease the number of stars.

typedef struct//Create a structure for the stars
{
int R, G, B; The color of the stars
Glfloat Dist; The distance between the stars and the center
Glfloat angle; The angle at which the current star is located
}
Stars Structure named stars
Stars Star[num]; Using ' stars ' structure to generate a ' star ' array containing ' num ' elements

Next we set up several tracking variables: the star's distance variable (zoom) from the Observer, the angle at which we see the Star (Tilt), and the variable spin that causes the blinking star to rotate around the z axis.
The loop variable is used to draw 50 stars. TEXTURE[1] is used to store a black and white texture. If you need more textures, you should increase the size of the texture array to the number of textures you decide to take.

Glfloat zoom=-15.0f; The distance of the stars from the viewer
Glfloat tilt=90.0f; The inclination of the stars
Glfloat spin; The rotation of the twinkling stars

Gluint Loop; Global Loop variable
Gluint Texture[1]; Store a texture

The code above is the code we use to load the texture. I'm not going to explain this code in more detail. This is exactly the same code we used in the 第六、七、八 class. This once loaded bitmap is called Star.bmp. Here we use Glgentextures (1, &texture[0]) to generate a texture. The texture adopts linear filtering method.

Aux_rgbimagerec *loadbmp (char *filename)//load bitmap file
{
FILE *file=null; File handle

if (! FileName)//Confirm that the file name is given
{
return NULL; If no return NULL
}

File=fopen (Filename, "R"); Check if the file exists

Does the if (file)//files exist?
{
Fclose (File); Close file handle
Return Auxdibimageload (Filename); Load a bitmap and return a pointer
}
return NULL; NULL If load failure is returned
}

The following code (called the code above) loads the bitmap and transforms it into a texture. Variables are used to track whether a texture is loaded and created.

int loadgltextures ()//load bitmap and convert to texture
{
int status=false; Status indicator

Aux_rgbimagerec *textureimage[1]; Allocating storage space for textures

memset (textureimage,0,sizeof (void *)); Set the pointer to NULL

Load bitmap, error checking, exit if bitmap file not found
if (Textureimage[0]=loadbmp ("Data/star.bmp"))
{
Status=true; Set Status to True

Glgentextures (1, &texture[0]); Create a texture

Create a linear filter texture
Glbindtexture (gl_texture_2d, texture[0]);
Gltexparameteri (gl_texture_2d,gl_texture_mag_filter,gl_linear);
Gltexparameteri (gl_texture_2d,gl_texture_min_filter,gl_linear);
Glteximage2d (gl_texture_2d, 0, 3, Textureimage[0]->sizex, Textureimage[0]->sizey, 0, GL_RGB, GL_UNSIGNED_BYTE, Textureimage[0]->data);
}

if (textureimage[0])//If the texture exists
{
if (textureimage[0]->data)//If the texture image exists
{
Free (textureimage[0]->data); Frees the memory of the texture image
}

Free (textureimage[0]); Releasing the image structure
}

return Status; Returns the value of status
}

Now sets how OpenGL is rendered. You are not going to use the in-depth test, if you use the first lesson code, make sure you have removed the Gldepthfunc (gl_lequal); and glenable (gl_depth_test); two lines. Otherwise, the effect you see will be a mess. Here we use texture mapping, so please confirm that you have added the code that you did not have in the first lesson. You'll notice that we've enabled texture mapping by process color.  
  
int initgl (glvoid)       //here to start all settings for OpenGL
{
 if (! Loadgltextures ())      //call texture Load subroutine
 {
  return false;      //if failed to load, returns false
 }

Glenable (gl_texture_2d); Enable Texture mapping
Glshademodel (Gl_smooth); Enable Shadow Smoothing
Glclearcolor (0.0f, 0.0f, 0.0f, 0.5f); Black background
Glcleardepth (1.0f); Setting the depth cache
Glhint (Gl_perspective_correction_hint, gl_nicest); Real-Fine perspective corrections
Glblendfunc (Gl_src_alpha,gl_one); Set the process color function to get a translucent effect
Glenable (Gl_blend); Enable process color

The following is the new code. Sets the starting angle, distance, and color for each star. You'll notice how easy it is to modify the properties of the structure. All 50 stars will be set by loop. To change the angle of star[1] all we have to do is star[1].angle={a certain value}; it's that simple!

for (loop=0; loop<num; loop++)//create loop set All Stars
{
star[loop].angle=0.0f; All Stars start from the zero angle.

The distance from the center of the

You will also notice that each star's color is a random number from the 0~255. Perhaps you wonder why the color range here is not between OpenGL's usual 0.0f~1.0f. The Color setting function we use here is Glcolor4ub, not the previous glcolor4f. UB means that the parameter is unsigned byte type. The value range for a byte is 0~255. It seems to be easier to use a byte value to take a random integer than to take a floating-point random number.  
  
  star[loop].dist= (float (loop)/num) *5.0f;  //calculates the distance from the center of the star
  star[loop].r=rand ()%256;   //for Star[loop] set random red component
  star[loop].g=rand () %256;   //Star[loop] Sets the random red component
  star[loop].b=rand ()%256;   //to star[ Loop] Sets the random red component
 }
 return true;      //initialize everything OK
}

Resize code is the same, now we go into the drawing code. If you use the code from the first lesson to delete the old Drawglscene code, just copy the following code in the past. In fact, the first lesson has two lines of code, so there's not much to erase.

int Drawglscene (glvoid)//This procedure includes all drawing codes
{
Glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit); Clear screen and depth cache
Glbindtexture (gl_texture_2d, texture[0]); Select Textures

for (loop=0; loop<num; loop++)//Loop set all the stars
{
Glloadidentity (); Reset the model observation matrix before plotting each star
Gltranslatef (0.0f,0.0f,zoom); Deep inside the screen
Glrotatef (tilt,1.0f,0.0f,0.0f); Tilt angle of view

Now let's move the stars. The star starts at the center of the screen. The first thing we want to do is to rotate the scene along the y axis. If we rotate 90 degrees, the x-axis is no longer from left to right, he will be out of the screen from the inside out. To make things clearer, let's take an example. Imagine you stand in the middle of the house. Then imagine you on the left side of the wall is written on-X, the front wall is written on-Z, the right wall is +x, the wall behind you is +z. Join the whole House to the right 90 degrees, but you don't move, then the front wall will be-X instead of-Z. All the other walls are moving along. -Z appears on the right, +z appears on the left and +x appears behind you. Are you insane? By rotating the scene, we change the direction of the X and Z planes.
The second line of code moves a positive value along the x-axis. A positive value on the x-axis is usually shifted to the right side of the screen (that is, the normal x-axis), but because we rotate the coordinate system around the y axis, the x-axis forward can be in any direction. If we turn 180 degrees, the left and right side of the screen is mirrored backwards. So, as we move forward along the x-axis, it may be left, right, forward, or backward.  
  
  glrotatef (star[loop].angle,0.0f,1.0f,0.0f)  //rotate to the angle of the currently painted star
  gltranslatef (star[loop].dist,0.0f,0.0f);  //move forward along the x-axis

The next code is a little bit tricky. The star is actually a flat texture. Now you're drawing a flat quadrilateral in the center of the screen and then pasting the texture, which looks good. Everything is as you think. But when you go 90 degrees along the y-axis, the texture on the screen is left only on the right and two sides of the left side toward you. Looks like a thin line. It's not what we want. We want the stars to face us forever, regardless of how the screen rotates or tilts.
We achieve this by offsetting any rotation of the stars before drawing the stars. You can use reverse order to counteract rotation. When we tilt the screen, we actually rotate the stars at the current angle. In reverse order, we "spin" the stars at the current angle. That is, rotate the stars with negative values from the current angle. That is, if we rotate the star 10 degrees, then rotate it-10 degrees so that the stars face the screen again on that axis. The first line below offsets the rotation along the y-axis. Then we also need to offset the screen skew along the x-axis. To do this, we just need to rotate the screen-tilt tilt. After offsetting the rotation of the X and Y axes, the stars are completely in our face.

Glrotatef (-star[loop].angle,0.0f,1.0f,0.0f); Cancels the angle of the current star
Glrotatef (-tilt,1.0f,0.0f,0.0f); Cancel Screen Tilt

If Twinkle is TRUE, we will first draw a non-rotating star on the screen: the total number of stars (NUM) minus the current number of stars (loop) minus 1, to extract the different colors of each star (this is done because the loop range is from 0 to num-1). For example, when the result is 10, we use the color of star number 10th. So the color of the neighboring stars is always different. It's not a good way, but it works. The last value is the alpha channel component. The smaller the value, the darker the star will become.
With Twinkle enabled, each star will be drawn two times at the end. The program will run slower, which depends on how your machine performs. But two times the color of the stars that are drawn together will have a great effect. And since the first time the stars are not rotated, the stars after enabling Twinkle appear to have an animated effect. (If you don't know what to say here, you can see how the program works.) )
It is important to note that coloring a texture is an easy thing to do. Although the texture itself is black and white, the texture becomes any color that we select before we draw it. Also, it is worth noting that the color values we use here are of type byte rather than the usual floating-point number. Even the alpha channel component is true.

if (twinkle)//enable flicker effect
{
Specify a color by using a byte type value
Glcolor4ub (star[(Num-loop) -1].r,star[(num-loop) -1].g,star[(num-loop) -1].b,255);
Glbegin (gl_quads); Start drawing a texture-mapped quadrilateral
GLTEXCOORD2F (0.0f, 0.0f); glvertex3f ( -1.0f,-1.0f, 0.0f);
GLTEXCOORD2F (1.0f, 0.0f); glvertex3f (1.0f,-1.0f, 0.0f);
GLTEXCOORD2F (1.0f, 1.0f); glvertex3f (1.0f, 1.0f, 0.0f);
GLTEXCOORD2F (0.0f, 1.0f); glvertex3f ( -1.0f, 1.0f, 0.0f);
Glend (); End of quadrilateral drawing
}

Now draw the stars twice over. The only thing that is different from the previous code is that the stars will certainly be drawn, and this time the stars rotate around the z axis.

Glrotatef (spin,0.0f,0.0f,1.0f); Rotate stars around the z axis
Specify a color by using a byte type value
Glcolor4ub (star[loop].r,star[loop].g,star[loop].b,255);
Glbegin (gl_quads); Start drawing a texture-mapped quadrilateral
GLTEXCOORD2F (0.0f, 0.0f); glvertex3f ( -1.0f,-1.0f, 0.0f);
GLTEXCOORD2F (1.0f, 0.0f); glvertex3f (1.0f,-1.0f, 0.0f);
GLTEXCOORD2F (1.0f, 1.0f); glvertex3f (1.0f, 1.0f, 0.0f);
GLTEXCOORD2F (0.0f, 1.0f); glvertex3f ( -1.0f, 1.0f, 0.0f);
Glend (); End of quadrilateral drawing

  
  spin+=0.01f;     //star's revolution
  star[ Loop].angle+=float (Loop)/num;  //change the angle of rotation of the stars
  star[loop].dist-=0.01f;     //change the distance of the star from the center

  
  if (star[loop].dist<0.0f)    //the star is at the center?
  {
   star[loop].dist+=5.0f;   //5 units Outward
   star[loop].r=rand ()%256;  //assigns a new red component
   star[loop].g=rand ()%256;  //assigns a new green component
    star[loop].b=rand ()%256;  //assigns a new blue component
  }
 }
 return TRUE;       //everything OK
}

Now we add the code to monitor the keyboard. Move down to WinMain (). Locate the Swapbuffers (HDC) row. We'll add the keyboard monitoring code behind this line.
The code checks if the T key is pressed. If the T key is pressed and released again, the code inside the If block is executed. If Twinkle is false, he will become true. Vice versa. The TP becomes true as long as the T key is pressed. This will prevent the code inside the block from being executed repeatedly if you keep pressing the T key.

Swapbuffers (HDC); Toggle Buffering
if (keys[' t '] &&!TP)//Whether the T key is pressed and the TP value is FALSE
{
Tp=true; If yes, set TP to True
Twinkle=!twinkle; Flip the value of Twinkle
}

The following code checks to see if the T key is released. If so, make tp=false. Unless the value of TP is false, nothing happens when you press the T key. So this line of code is important.

if (!keys[' t ')//T key has been released?
{
Tp=false; If yes, TP is FALSE
}

The rest of the code checks the upper and lower arrow keys, the PAGE UP key or the PAGE DOWN key is pressed.

if (keys[vk_up])//Up ARROW key pressed?
{
tilt-=0.5f; Screen tilt up
}

if (Keys[vk_down])//DOWN ARROW key pressed?
{
tilt+=0.5f; Tilt down the screen
}

if (Keys[vk_prior])//PAGE UP key press down
{
zoom-=0.2f; Narrow
}

if (Keys[vk_next])//PAGE DOWN key press down?
{
zoom+=0.2f; Amplification
}

As before, verify that the title of the window is correct.

if (keys[vk_f1])//F1 button pressed?
{
Keys[vk_f1]=false; If so, the value in the corresponding key array is FALSE
Killglwindow (); Destroys the current window
Fullscreen=!fullscreen; Toggle Fullscreen/Windowed Mode
Rebuilding the OpenGL window
if (! Createglwindow ("Nehe ' s transparent texture instance", 640,480,16,fullscreen))
{
return 0; If the window fails to create, the program exits
}
}
}
}
Original source code and version of the download:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=09

Nehe OpenGL Tutorial Lesson Nineth: Moving Images

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.