NEHE's OpenGL Tutorial Delphi version (8) ---- Simple transparency

zhaozj2021-02-16  46

{

Oh, this two lessons have long been translated, have not posted, everyone has been waiting (someone will wait?)

Most special effects in simple transparent OpenGL are related to certain types of (color) mixing. The definition of mixing is, combined with the color of a pixel and the plotted pixel color corresponding to its corresponding pixel colors. As for how to combine these two colors, depending on the component value of the Alpha channel, and / or the mixing function used. Alpha is typically the amount of 4th color group located at the end of the color value. In the previous lesson, we all use GL_RGB to specify the three components of the color. The corresponding GL_RGBA can specify the value of the Alpha component. Further, we can use Glcolor4f () to replace GLCOLOR3F ().

Most people think that Alpha components represent the transparency of materials. That is to say, the materials represented by the alpha value of 0.0 are completely transparent. The materials represented by the Alpha value of 1.0 are completely opaque.

Mixed formula If you don't catch a cold in mathematics, just want to see how to achieve transparency, please skip this section. If you want to understand (color) mixed working principle, this section should suit you. "Supplement of CKER: It is not difficult to ^ - ^. The formula in the original text is as follows, and CKer is more embracing. In fact, the basic principle of mixing is to separate the color and background color of the image that will be divided into, according to the RGB rule, according to the RGB color component * alpha value background RGB color components * (1-alpha value) ) - After a simple formula is mixed, the mixed RGB component will be reconfigured. "

The formula is as follows: (RS SR RD DR, GS SG GD DG, BS SB BD DB, AS SA AD DA) OpenGL calculates the color mixing results of these two pixels in accordance with the above formula. Small-written S and R represent the source pixels and target pixels, respectively. Uprising s and d are corresponding mixing factors. These determine how you mix these pixels. In most cases, the alpha mixing color value of each color channel is the same, so that there is (AS, AS, AS, AS), and the target pixels are 1, 1, 1, 1) - (AS, AS, AS, AS). The above formula becomes the following appearance: (RS AS RD (1 - As), GS AS GD (1 - As), BS AS BS (1 - As), AS AD (1 - as) This formula generates a transparent / translucent effect.

The steps in OpenGL implementation in OpenGL are similar to the OpenGL process we mentioned earlier. The formula is then set and the write depth cache is turned off when drawing a transparent object. Because we want to draw objects behind translucent graphics. This is not the correct mixing method, but most of this approach works very well in a simple project.

Rui Martins Supplement: The correct mixing process should be a transparent graphic after drawing all scenes. And to draw (the farthest object) in the opposite order of the depth cache. Consider mixing two polygons (1 and 2) Alpha mix, different drawings will be different results. (Here, it is assumed that the polygon 1 is recently, then the correct process should first draw polygon 2, then draw polygon 1. As you see it again, from these two The light behind the two "polygons Always pass through the polygon 2, then pass through the polygon 1, finally arrive at the eye of the observer.) When the depth cache is enabled, you should sort the transparent graphics according to the depth, and draw these transparenches after all the scene plots object. Otherwise you will get an incorrect result. I know that something is very painful, but this is the right way.

We will use the code of the seventh lesson. At first, first add two new variables at the beginning of the 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; // The array of keyboard routines Light: boolean; // light source on / off

Blend: boolean; // Blending OFF / ON? (Add)

LP: boolean; // L button Press? FP: boolean; // f button presses?

BP: boolean; // b button presses? (Add)

XROT: GLFLOAT; // X Rotate Yrot: GLFLOAT; // Y Rotate XSpeed: GLFLOAT; // X Rotation Speed ​​YSPEED: GLFLOAT; // Y Rotation Speed

Z: GLFLOAT = -5.0 f; // Deepen the distance Lightambient: array [0..3] of glfloat = (0.5, 0.5, 0.5, 1.0); // Environmental light parameters (new) Lightdiffuse: array [0 ..3] of glfloat = (1.0, 1.0, 1.0, 1.0); // diffuse light parameters (new) LightPosition: array [0..3] of glfloat = (0.0, 0.0, 2.0, 1.0); ///// Light source position (new) filter: gluint; // filter type texture: array [0..2] of gluint; // 3 storage space

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

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

Function Glubuild2dmipmaps (Target: Glenum; Components, Width, Height: Glint; Format, Atype: Glenum; Data: Pointer: Integer; stdcall; external glu32 name 'glubuild2dmipmaps';

{Move down to loadgltextures () here. Live IF (TextureImage [0] = LoadBMP ('data / crate.bmp')). We are now using a colored glass texture to replace the wooden box texture in the previous lesson. IF (TextureImage [0]); // Load the glass bitmap (modified)}

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 ('Walls.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); glBindTexture (GL_TEXTURE_2D, texture [1]); // use from bitmap texture data generated typically generate texture // glTexImage2D (GL_TEXTURE_2D, 0, 3, TextureImage [0] .sizeX, TextureImage [0] .sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage [0] .data); glTexParameteri (GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER, GL_LINEAR); // linear filter glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // // Create MipMapped linear filtered texture glBindTexture (GL_TEXTURE_2D, texture [2]); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); // (new) gluBuild2DMipmaps (GL_TEXTURE_2D, 3, TextureImage [0] .sizeX, TextureImage [0] .sizey, GL_RGB, GL_UNSIGNED_BYTE, TextureImage [0] .data); // ( New)} END; if Assigned (TextureImage [0]) THEN // Whether IF Assigned (TextureImage [0] .data) THEN // Texture Image is TEXTUREIMAGE [0] .data: = nil; // Release Texture Image Occupation [0]: = nil; // Release Image Structure Result: = Status; // Returns Statusend; {{The following two lines are added to the GLINIT () code section. The first line draws this object with full brightness and 50% Alpha mixed (translucent). When the mixing option is turned on, this object will generate a 50% transparent effect. The second line setting is used in the mixing type.

RUI Martins Supplement: The value of the Alpha channel is 0.0 means that the material material is completely transparent. 1.0 means completely opaque. }

Procedure Glinit (); // Start all settings of OpenGL for OpenGL (Not LoadTexture) Then // Call texture load subroutines exit; // If it is not loaded, exit

Glenable (GL_TEXTURE_2D); // Enable texture map GLShademodel (GL_SMOOTH); // Enable shadow smooth GlclearColor (0.0, 0.0, 0.0, 0.0); // Black background GlcleardEpth (1.0); // Set depth cache Glenable (GL_Depth_test); // Enable depth test GLDEPTHFUNC (GL_SS); // Deep test type GLHINT (GL_PERSPECTIVE_CORRE_HINT, GL_NICEST); // Highly Optimized Perspective Projection Calculation GLLightFv (GL_Light1, GL_AMBIENT, @Lightambient [0]); // Set ambient light GLLIGHTFV (GL_LIGHT1, GL_DIFFUSE, @LightDiffuse [0]); // Set the diffuse light GLLIGHTFV (GL_Light1, GL_Position, @lightposition); // Light source GLENABLE (GL_Light1); // Enable No. 1 Light source Glcolor4f (1.0, 1.0, 1.0 , 0.5); // Full brightness, 50% alpha mix (new) Glblendfunc (GL_SRC_ALPHA, GL_ONE); // Based on the translucent mixed function of the source pixel ALPHA channel value (new)

END;

{Find the following code segment at the end of the seventh class. IF keys [vk_left] the // LEFT direction button presses? YSPEED: = yspeed - 0.01; // If it is, reduce YSPEED, then the following code, we increase the following code. These lines monitor if the B key is pressed. If so, the computer checks if the mixing option has been opened. Then set it to the opposite state. } IF (Keys [ORD ('b')] and not bp) THEN / / B Jushi and BP is false? Begin bp: = true; // is set to True Blend: = not blend; / / Switch Mixed Option True / False if (Blend) THEN / / Mixed Open? Begin Glenable (GL_BLEND); // Open Mixed GLDISABLE (GL_DEPTH_TEST); // Turns the depth test ELSE / / Otherwise Begin GLDISABLE (GL_Blend) ; // Close the mixed glenable (GL_Depth_test); // Open the depth test end; end; if (Not Keys [ORD ('b')]) Then // B is loose? Begin bp: = false; // If BP is set to false end; {But how can you specify the color when using the texture map? It is very simple, when adjusting the map mode, the color of each pixel point of the document map is by Alpha channel parameters Multiplied with the current pixel color. For example, the color drawn is (0.5, 0.6, 0.4), we will get the color by color (0.5, 0.6, 0.4, 0.2) (the alpha parameter is not specified, default is zero). So is this! OpenGL is really simple to achieve Alpha mix! } {Original note (11/13/99) I (nehe) mixed code made modifications so that the displayed object looks more realistic. At the same time, the source pixels and destination pixels are mixed using Alpha parameters, which will cause the artificial traces of the object look obvious. It will cause the back of the object to be darker along the side.

Basically, the physical experience looks very weird. The mixing method I used may not be the best, but it is indeed possible. After the light source is enabled, the object looks realistic. Thanks to the original code provided by TOM, the mixing method he use is correct, but the object looks not as the appeal :) The code is again modified because the gldepthmask () function is addressed in some graphics cards. problem. This command does not seem to be very valid when the depth buffer test is enabled or turned off on some cards, so I have enabled or shut down the code for depth buffering tests into old-fashioned Glenable and GLDISABLE. The ALPHA mixture of texture maps is used for texture maps that can be read from the problem maps like colors. The method is as follows, you need to obtain Alpha parameters while loading the required material. Then use the color format of GL_RGBA when you call GLTexImage2D (). }

// Run a look

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

New Post(0)