NEHE OpenGL Tutorial Delphi Edition (9) ---- Star

zhaozj2021-02-16  54

{Welcome to the ninth lesson. Up to now, you should understand OpenGL very well. "CKER: If not, it must be the sin of my translation ...". (Myling added: My sin is more sinful, huh, huh) you have learned to set up every detail of an OpenGL window. Learn to map on the rotating object and put the light and mix colored (transparent). This lesson should be an intermediate tutorial. You will learn the following: Move bitmap in 3D scenes and remove black pixels on the bitmap (mixed with color). Then it is black and white texture, and finally you will learn to create rich colors, and mix the textures of different colors to each other to get a simple animation effect. We have modified on the code of the first lesson. First add a few variables at the beginning of the program source code. I have rewritten the whole code for the clear start. }

Var h_rc: hglrc; // rendering context (Color Description Table). H_dc: hdc; // device context h_wnd: hwnd; // window handle h_instance: hinst; // program instance (instance). Keys: array [0..255] of boolean; // An array of keyboard routines

{The following lines are new. Twinkle and TP are Boolean variables that they can only be set to TRUE or FALSE. Twinkle is used to track if the flicker effect is enabled. TP is used to check the 't' button is not pressed or released. (Tp = True, loosen Tp = false).} twinkle: boolean; // Flashing stars (new) TP: boolean ; // 't' Press? (Add) {Now let's create a structure. Structure This word sounds a little terrible, but it is actually not the case. (The type of Delphi record) A structure uses a simple type of data (and variables, etc.) to express larger data combinations with similarity. We know that we are keeping track of stars. You can see the following is stars; each star has three integer color values. A red (R), a green (G), and a blue (B). In addition, each star is different from the center of the screen, and can be an angle in any 360 degree of the origin of the screen. The floating point of DIST keeps the distance to the distance. Angle's floating point is kept tracking to the angle value of the stars. So we used a set of data to describe the color, distance, and angle of the stars on the screen. Unfortunately, we don't just track a stars. But there is no need to create 50 red values, 50 green values, 50 blue values, 50 distance values, and 50 angle values, just create an array star. } Type Stars = Record // Create a structure for the stars, the structure is named Stars R, G, B: Integer; // Star's color dist: glfloat; // Star distance center distance angle: GLFLOAT; // Current Star At the angle end; var star: array [0..49] of stars; // Generate a 'Star' array containing 50 elements using the 'Stars' structure

{Next We set a few tracking variables: the distance of the Stars off the observer (zoom), the angle of the star we see, and the variable spin Spin rotated around the Z-axis. Loop variables are used to draw 50 stars. Texture [1] used to store a black and white texture. If you need more textures, you should increase the size of the Texture array to you determine the number of textures. } ZOOM: GLFLOAT = -15.0; // Star from the observer's distance TILT: GLFLOAT = 90.0; // Star's inclination Spin: GLFLOAT; / / flashing Star's rotation loop: gluint; // Global L loop variable Texture: array [0..1] 0 gluint; // Store a texture

Procedure Glgentextures (N: Glsizei; Var Textures: gluint); stdcall; external opengl32;

Procedure Glbindtexture (Target: Glenum; Texture: gluint); stdcall; External OpenGL32;

{The code that follows the above is the code we use to load the texture. I don't intend to explain this code in detail. This is the same as our code used in sixth, seventh, and eight classes. This loaded bitmap is called Star.BMP. Here we use GLGENTEXTURES (1, & Texture [0]) to generate a texture. Texture uses a linear filtering method. }

Function loadtexture: boolean; // Load bitmap and convert to texture var status: boolean; // status indicator TextureImage: array [0..1] of ptaux_rgbimagerec; // Create texture storage STATUS: = false; ZeromeMory (@TextureImage); // Set the pointer to null textureiMage [0]: = loadingBMP ('star.bmp'); if TextureImage [0] <> nil dam status: = true; // the Status is set to TRUE glGenTextures (1, texture [0]); // // Create creates a texture map filtering Nearest glBindTexture (GL_TEXTURE_2D, texture [0]); // generate texture glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // (Add) Gltexparameteri (GL_Texture_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); / / (new)

glTexImage2D (GL_TEXTURE_2D, 0, 3, TextureImage [0] .sizeX, TextureImage [0] .sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage [0] .data); End; If assigned (TextureImage [0]) Then // Texture Whether IF assigned (TextureImage [0] .data) the // texture image exists with TextureImage [0] .data: = nil; // Release Texture Image Occupation [0]: = NIL; // Release Image Structure Result: = status; // Returns statusend; {Set OpenGL rendering mode in Glinit (). Not planning to use depth testing,

If you use the code of the first lesson,

Please confirm if GldepThFunc (GL_LEQUAL) and GLENABLE have been removed.

Otherwise, what you see will be a mess.

Here we use textured mappings.

So please confirm that you have added the code not in these first lessons.

You will notice that we enable texture mapping by mixing.

}

Procedure glinit (); begin if (not loadtexture) THEN // Call texture load subroutine (new) exit; // If it is not loaded, exit (new)

glEnable (GL_TEXTURE_2D); // enable texture mapping glShadeModel (GL_SMOOTH); // enable smooth shading glClearColor (0.0, 0.0, 0.0, 0.5); // black background glClearDepth (1.0); // Set the depth buffer glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Really fine perspective correction GLBLENDFUNC (GL_SRC_ALPHA, GL_ONE); // Setting the mixing function Glenable (gl_blend); // Enable mixing color

{The following is a new code. Set the start angle, distance, and color of each star. You will notice that the properties of the modified structure are easier. All 50 stars will be set cycled. To change Star [1], what we have to do is just star [1] .angle = a value; it is as simple! } For loop: = 0 to 49 do // Creating a loop setting All Stars Begin Star [loop] .angle: = 0.0; // All stars start from zero angle {Distance to the center of the center is the value of Loop In addition to the total number of stars, then take 5.0. Basically, the latter stars are more far more than the previous stars. This is when the LOOP is 50 (last stars), the LOOP divided by NUM is 1.0. It is necessary to multiply by 5.0 because 1.0 * 5.0 is 5.0. "Cker: nonsense, nonsense! How do this foreigner with Kong B! :) "5.0 is already close to the edge of the screen. I don't want the Star to fly out of the screen, 5.0 is the best choice. Of course, if you use the scene settings inside the screen, you may use a value greater than 5.0, but the stars look smaller (all the perspective). You will also notice that the colors of each star are a random number between 0 to 255. Maybe you will be strange why the color is worth 0.0 to 1.0 here. Here we use the color setting function is GLCOLOR4UB, not the previous GLColor4f. UB means that the parameters are unsigned byte. A Byte value range is 0 ~ 255. This is easier to use byte value to take the random integer to take a floating point. } Star [loop] .dist: = (Trunc (loop) / 50) * 5.0; // Calculate the distance of the star STAR [loop] .r: = random (256); // Setting random for star [loop] Red component star [loop] .g: = random (256); // Setting a random red component star [loop] .b: = random (256); // for star [loop] Set random red component END;

{Now we transfer to GLDRAW () draw code. If you use the code of the first lesson, delete the old DrawGlscene code, just copy the following code to the past. In fact, the code of the first lesson is only two lines, so there is not much thing to delete. }

Procedure gldraw (); begin glclear (gl_color_buffer_bit or gl_depth_buffer_bit); // Clear screen and depth cache

Glbindtexture (GL_Texture_2D, Texture [0]); // Select Texture for loop: = 0 to 49 DO // Cycle All Stars Begin GLLoadIdentity (); // Draw a Model Observing Matrix GltranslateF (0.0 , 0.0, ZOOM); // Inside the screen (using the value of 'zoom') GLROTATEF (TILT, 1.0, 0.0, 0.0); // Tilt the angle of view (using 'Tilt') {Now let's move the stars. The stars are at the center of the screen. The first thing we have 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, and he will pass the screen outward. In order to make everyone more clear, take an example. Imagine you standing in the middle of the house. Then I envisage the wall on the left side of your left, write -z, the front wall is x, the right wall is x, and the wall behind you is z. Join the entire house to turn 90 degrees, but you are not moving, then the front wall will be -x and no longer -z. All other walls are also moving. -z appears on the right, z appears on the left, x appears behind you. The nerve is disorderly? By rotating the scene, we changed the direction of the X and Z planes. The second line of code moves a positive value along the X axis. Typically, the positive value on the X-axis is moved toward the right side of the screen (that is, the normal X-axis of the X-axis), but here we rotate the coordinate system around the Y-axis, the positive direction of the X-axis can be any direction. If we turn 180 degrees, the image is reversed on the left and right side of the screen. Therefore, when we move forward in the X axis, it may be left, right, forward or backward. } GLROTATEF (Star [loop] .angle, 0.0, 1.0, 0.0); // Rotate to the currently painted star GLTRANSLATEF (Star [loop] .dist, 0.0, 0.0); // Positive movement along the X-axis { Then the code takes a little tip. The stars are actually a flat texture. Now you have drawn a flat quadrilateral shape on the center of the screen, then post the texture, this looks very good. Everything is as you think. But when you turn around 90 degrees along the Y axis, the texture is only left on the right side and the two sides of the left side toward you. It seems to be a thin line. This is not what we want. We hope that the stars will always face us, regardless of how the screen is rotated or tilted. We have achieved this by offset any rotation made to the stars before drawing the stars. You can use an inverse ordered to offset rotation. When we tilted the screen, we actually rotate the stars in the current angle. By reverse order, we "reverse rotate" stars in the current angle. That is to rotate the stars in a negative value of the current angle. That is to say, if we rotate the stars 10 degrees, we rotate the -10 degree to make the stars back to the screen on that axis. The first line below offset the rotation along the Y axis. We also need to cancel the screen tilt along the X axis. To do this, we only need to turn the screen again - TILT inclination.

After the rotation of the X and Y axes, the stars are completely facing us. } Glrotatef (-star [loop] .angle, 0.0, 1.0, 0.0); // Cancel the current star's angle GLROTATEF (-tilt, 1.0, 0.0); // Cancel screen tilt {If Twinkle is True, we are Prace the Star that does not rotate on the screen: subtract the total number of stars (NUM) to minus 1, to extract different colors of each star (this is because the cycle ranges from 0 to Num- 1). For example, the result is 10, we use the color of the No. 10 star. This is always different in the color of the neighboring star. This is not a good way, but it is very effective. The last value is the Alpha channel component. The smaller this value, the darken this star. Since Twinkle is enabled, each stars will finally draw twice. The program is running slowly, it depends on how your machine performance is. But the two-way color of the stars are integrated with each other, and it will produce a great effect. At the same time, because the first round of the stars do not rotate, the stars after the Twinkle after the stars have appeared to have an animation effect. (If you don't know what you know here, you can see the running effect of the program.) It is worth noting that it is easy to give texture color. Although the texture itself is black and white, the texture will turn into any of the selected colors before drawing it. In addition, it is also worth noting that the color value we used here is Byte type, not the usual floating point. Even Alpha channel components are also true. } IF (twinkle) THEN / / Enable flashing effect Begin // Specifies a color Glcolor4ub using Byte type (Star [(50 - loop) - 1] .r, star [(50 - loop) - 1] .g, star [(50 - loop) - 1] .b, 255; glbegin (gl_quads); // Start drawing textured quadrilateral gltexcoord2f (0.0, 0.0); GlvertEX3F (-1.0, -1.0, 0.0); GLTEXCOORD2F (1.0 , 0.0); GlvertEX3F (1.0, -1.0, 0.0); Gltexco 3f (1.0, 1.0); Glvertex3f (1.0, 1.0, 0.0); Gltexco 3F (0.0, 1.0); GlvertEX3F (-1.0, 1.0, 0.0); glend () ; // quadrilateral drawing ends END;

{Now draw a second round of stars. The only and the previous code is that this round of the stars will definitely be drawn, and this star is rotated around the Z axis. } GLROTATEF (Spin, 0.0, 0.0, 1.0); // Rotating the Star // with the Byte type value specifies a color Glcolor4ub (Star [loop] .r, star [loop] .g, star [loop] .b , 255); Glbegin (GL_QUADS); // Start drawing textured quadrilateral gltexcoord2f (0.0, 0.0); GlvertEX3F (-1.0, -1.0, 0.0); Gltexco 3F (1.0, 0.0); GlvertEx3f (1.0, -1.0, 0.0); gltexcoord2f (1.0, 1.0); GlvertEX3F (1.0, 1.0, 0.0); GLTEXCOORD2F (0.0, 1.0); GLVERTEX3F (-1.0, 1.0, 0.0); glend (); // quadrilateral drawback {The following code representative The sport of the stars. We increase the value of Spin to rotate all stars (public turn). Then, the rotation angle of each star is then increased LOOP / NUM. This makes a faster stars that are further away from the center. Finally reduce the distance of each star away from the screen. This looks like this, the stars seem to have been in the center of the screen. } Spin: = spin 0.01; // Star's public turn star [loop] .angle: = star [loop] .angle trunc (loop) / 50; // change the rotation angle of the stars Star [loop] .dist: = Star [loop] .dist - 0.01; // Changing the distance from the center

{Next, check whether the stars have encountered the center of the screen. When the stars encounter the screen center, we assign a new color, then move 5 units, this stars will embark on the journey of its return to the screen. }

IF (Star [loop] .dist <0.0) THEN / / Star arrived in the center? Begin Star [loop] .dist: = star [loop] .dist 5.0; // Move 5 units Star [loop] .R : = Random (256); // Assign a new red component star [loop] .g: = Random (256); // assign a new green component star [loop] .b: = random (256); // A new blue component end; end; end;

{Now we add the code that monitors the keyboard. Move down to WinMain (). Find a row of SwapBuffers (HDC). We will add keyboard monitoring code after this line. The code will check if the T key is pressed. If the T key is pressed, it is released, the code within the IF block will be executed. If twinkle is false, he will become true. vice versa. As long as the T key is pressed, the TP changes to true. This will prevent the code within the block from being executed if you have been pressing the T key. } IF (Keys [ORD ('T')] and not tp) THEN / / Whether the T key has been pressed and the TP value is false begin tp: = true; // is set to True Twinkle: = NOT Twinkle ; // flip the value of the Twinkle End; {The following code checks if the T key is released. If so, make TP = false. Unless the value of TP is false, what will not happen when you press T. So this line code is very important. } F (not keys [ORD ('T')]) Then // T button is released? Begin TP: = false; // If the TP is false end; {the remaining code check, the down direction button, the upward page button, or the down button is pressed. }} (Keys [vk_up]) THEN / / upper point button? TILT: = TILT - 0.5; / / The screen is tilted upward IF (Keys [vk_down]) THEN / / lower direction button presses? Tilt: = TILT 0.5; // Screen Tilt IF (Keys [VK_PRIOR]) THEN / / Page button Page button to press ZOOM: = ZOOM - 0.2; / / Reduce IF (Keys [VK_NEXT]) THEN / / Turn the page button to press? ZOOM: = zoom 0.2; // Zoom {This lesson I can do my best how to load an grayscale bitmap texture, (using a mixed color) After the background colors, give it color, let it Move in a 3D scene. I have already show you how to create beautiful colors and animation. The principle of realization is to overlap a bitmap copy on the original bitmap. Up to now, as long as you understand everything I teach you, you should already make your own 3D Demo without any problem. All basic knowledge is included! } // ======== myLing:

// 1-9 The class has been translated, just like Nehe, basic knowledge has been basically finished.

// I looked at the tutorial below, it seems to be from the hands of others. If there is a good example, I will selectively

// Continued, tired, sleep for a while :), next time

转载请注明原文地址:https://www.9cbs.com/read-25036.html

New Post(0)