Tutorial 2c : Transparency effects |
|
Introduction One of the main uses of alpha values is to create transparency and blending effects. When we use the word "transparency" in terms of a Glide program, we're referring to any rendering operation that allows the background to show through to some extent, instead of being replaced. In this tutorial we're going to learn about another new function, grAlphaBlendFunction. Whereas all of the colour / alpha functions that we've seen so far allow us to control how the source values are determined and modified, this function allows us to control the way that the computed colour of a new pixel is modified by the colour of the pixel that already exists in the rendering buffer. The steps we follow to render a semi-transparent shape are:
We can use any of Glide's available colour sources, but for now let's just consider the two that we've seen in the previous tutorials. We specify them in exactly the same way as we did before. Note: using transparency doesn't change the way that the colour source is determined.
For instance, to use the constant colour:
As humans who live in a real environment with real objects, we think of a transparent object as one that allows a certain amount of light to pass through it. Glide doesn't actually understand the concept of transparency, but it does allow the programmer to determine how a new pixel should be blended with an existing pixel, which we can use to simulate transparency. Let's imagine a real-world scenario and then see how it could be simulated in Glide: Suppose we're looking at a picture hanging on the wall. We can see all of its colours exactly how they should be - blue is blue, green is green, etc. Then, we hold a sheet of semi-transparent red plastic in front of the picture. Because of the way the plastic affects light passing through it, the picture loses most of its blue and green qualities, and every colour becomes tinted red. To do the same thing in Glide, we would first draw the picture, and we would then draw a red rectangle on top of it. However, before drawing the red rectangle we tell Glide that new pixels should be a combination of the source pixel (part of the red rectangle) and the destination pixel (part of the picture that is already there).
The call to grAlphaBlendFunction would be:
The first and second parameters passed to the grAlphaBlendFunction function specify the scaling factors for the source and destination colours. The third and fourth parameters specify the scaling factors for the source and destination alpha values. For the purposes of this example, let's suppose we're using an opacity value of 75%, meaning that the final colour of a new pixel should be 75% of the source colour and 25% of the pixel that already exists in the rendering buffer. The opacity value would be set by specifying a value of 191 for the constant alpha. Note: transparency and opacity are inversely proportional - the more transparent something is, the less opaque it is. A window is very transparent; a brick wall is 100% opaque. The first parameter passed to the grAlphaBlendFunction function, GR_BLEND_SRC_ALPHA, tells Glide to scale the source colour by the source alpha, which in this case is the constant alpha. For example, if the source colour was bright red, it would be scaled to approximately 75% red. The second parameter, GR_BLEND_ONE_MINUS_SRC_ALPHA, tells Glide to scale the destination colour by the source alpha, but to invert the source alpha before doing so. For example, if the destination colour was bright blue, it would be scaled to approximately 25% blue. Note: before Glide scales a colour using an alpha value, which will be in the range 0 - 255, it first divides it by 255, bringing it within the range 0 - 1 (with 0 being minimum alpha and 1 being maximum alpha). The GR_BLEND_ONE_MINUS_SRC_ALPHA function tells Glide that an additional step should be performed, with the converted alpha value being subtracted from 1, so a value of 1 would become 0, a value of 0 would become 1, and a value of 0.75 would become 0.25, etc. The third parameter, GR_BLEND_ONE, means that the source alpha should be unmodified. This is the value that is being used to determine the transparency / blending factor. The fourth parameter, GR_BLEND_ZERO, means that the destination alpha should be set to zero. The algorithm we're creating doesn't need to know what the destination alpha value is, so we'd might as well set it to zero. To help us picture how everything comes together to create the illusion of transparency, let's look at the system we've just created as a flowchart:
The top row is the source colour, going through both the grColorCombine and grAlphaBlendFunction modifiers, while the bottom row is the destination colour, which is only modified by grAlphaBlendFunction. The two source colours, red and a non-existant colour, are combined to produce red, which is then scaled by the constant alpha value to produce 75% red. It then remains unchanged. The destination colour, blue, is scaled by the inverted constant alpha value to produce 25% blue, which also remains unchanged. Finally, the two calculated colours are combined to produce a final colour that is 75% red and 25% blue, which is magenta. That is the colour that is written to the rendering buffer. Tell Glide how transparent the shape should be The alpha value that we want to use for the transparency factor can be taken from any of the available sources, but for the moment let's just use the constant alpha value. As always, we set the constant colour / alpha value using the grConstantColorValue function, with the only parameter being the return value from our own colour_ARGB function.
If the semi-transparent shape we're going to draw uses the constant colour, then we can set the colour at the same time. For instance, to set the colour to yellow, with an alpha value of 191 (to create a 75% transparency effect), the code would be:
We draw the semi-transparent shape in exactly the same way as we would draw any other shape. For instance, to draw a triangle:
Notice how the program is structured:
This tutorial is ©1998 by Andrew Smith. No part of this tutorial may be reproduced without permission. If you want to reproduce any of this tutorial for non-commercial purposes then I'm not likely to try and stop you, but please ask me first. |