Monday, October 1, 2007

What is COM ?

Components

Application consists of a single monolithic binary file. Once the application is shipped, it does not change until it is recompiled and shipped again (new version). There has to be a way out to be able to change the application without recompiling and re-shipping. The solution is to break it into components. As new additions are demanded, the older components are replaced by new components.

Traditional Application Architecture :

Files / Modules / Classes -> Compiled -> Linked -> Monolithic Application


Component Architecture: A component is a mini-application that has code already compiled, linked and ready to use. Modifying the application is simply replacing the old component by a new one. One component connects to other at run time an form an application. Thus the application is broken down into separate components connecting to each other at run time and forming the complete application.


The two main conditions that components must satisfy are:-

  1. They should link dynamically. This is essential if we want to support the change in components at run time.

  2. Data hiding. If a component is changed for some reason then it should connect to the other components in the same way as the old one did. If it does not happen then the system has to be recompiled and the whole purpose of using this architecture is lost. A component using other component is called as a client. A client is connected to a component using interface. If there is any change in the client of the component that does not affect the interface, everything works fine, but if the change affects the interface as well then the other side of the interface must change as well. The implementation is hidden from the client.


  • Components should be language independent and must be able to be written by anyone, in any language.

  • The application should keep supporting the old version even after a new one is released. It should still be possible to drastically change the behavior of the component while still supporting the old application.


COM components:

  • Consists of DLLs or EXEs

  • Are dynamically loaded

  • Are language independent

  • Hide data

  • Are shipped in binary form

  • Can be upgraded without breaking the old clients.

  • Can be relocated on the network, work in the same way for a local machine or a network machine.

Interface


An interface provides a connection between two different objects. An interface is an array of function pointers. Each array element contains the address of a function that is implemented by the component.


An interface has all pure virtual functions meaning that there are no objects of interfaces. In C++, multiple inheritance is used and the implementation of the pure virtual functions is done in the derived class. Using multiple inheritance, there can be many interfaces adhering to a single component as the definition suggests.


  • COM interfaces are implemented in C++ as pure abstract classes.

  • A class is not a component. A COM component can be implemented using several classes. Actually COM does not require C++ classes to implement a component, it just makes it easy to do it this way.

  • It is not necessary to inherit an interface to be able to implement it. The client does not see what is going on in the background anyway.

  • An interface is a set of functions, a component is a set of interfaces and the system is a set of components.

  • The client does not connect to the interface based on its name or the function name but based on the location in the block of memory representing the interface.

  • Interface never changes. For new additions you write a new interface and publish it. This can be easily done since COM supports multiple interfaces.

  • A small interface represents single behavior. A large interface represents many behaviors. The bigger the interface, the specialized it gets and it is likely that not many components would be using it.

Polymorphism:


If two different components support the same interface then the client can use the same code to manipulate either of the components. Thus the client can treat these two components polymorphically.

Virtual Function Table:


A pure abstract class is basically a block of memory, which has the same basic layout as that of a COM interface. For this reason can C++ pure abstract classes be used as COM interfaces.

The virtual function table is an array of pointers to the member functions. In short, a pointer to an abstract class points to a virtual table pointer which in turn points to the virtual function table which has pointers to the member functions. Hope you get this right.


CA *pA;


Lets say CA is a pure abstract class and pA is a pointer to it then eventually,

pA->virtual table pointer->virtual table->member functions.


Data members if any for a class sit with the vtbl pointer. The same vtbl is shared for different objects(instances) of the same class. Each instance pointer points to a different vtbl pointer but the table where it points is the same.

Query Interface

A client communicates with the component using interfaces. Even to get another interface that the component has implemented, it has to do it using an interface. All interfaces derive from an interface known as IUnknown. IUnknown has declaration for three methods namely QueryInterface, AddRef and Release.


The client calls the QueryInterface function to see if the component supports an interface. If it does then it can now call the functions declared by the requested interface and implemented by the component.


To get the first interface pointer, i.e. the IUnknown pointer, the following is done;


IUnknown * CreateInstance(); This creates the component and returns a pointer to the IUnknown interface. This pointer can now be used to get other interfaces using QueryInerface()should they be adhering to a particular component.


QueryInterface function takes two argument, one is the IID of the required interface and other is a pointer that it will return of the requested interface if is succeeds. The body of the QueryInterface function is a simple if-then-else statements checking for the matching IID and returning the pointer where the IID matches. If nothing matches it returns E_NOINTERFACE.


Steps in implementation: -


  1. Define as many interfaces you want, derived from IUnknown

  2. Define a class which will be your component. It will have multiple inheritance from interfaces that you want to implement in this class.

  3. Implement all the functions declared in all the interfaces from which this class is derived. Also implement QueryInterface() function.

  4. Define the CreateInstance() function outside the class. This function will be used by the client, which will create an instance of the component and return an IUnknown pointer.

  5. On the client side call the CreateInstance function to get the interface pointer.

  6. Using this pointer call the QueryInterface function passing in the IID of the interface that you want to use. You will get a valid pointer if this interface is implemented by the component.

  7. After getting the pointer you can call the methods declared in this interface.

  8. You can query for another interface using this pointer using QueryInterface.

  9. QueryInterface returns the same pointer in response to all requests for IUnknown.

  10. Every interface has its own unique IID.


Reference Counting


Once a component is created and used, it has to be deleted, if not then it keeps using the valuable memory space. The client has to perform a very complicated procedure to know whether or not there are no interfaces using the component. It has to also find out if more than one interface pointer points to the same object. Hence the best way to do it is to inform the component when the client is done with all the interfaces and the component will take care of its deletion.


The AddRef and Release keep track of the interfaces that the client uses.


Memory Management:


When a client gets an interface, the reference count is incremented using AddRef. When the client is done with the interface, the reference count is decremented using Release. When the reference count goes down to zero, the component deletes itself.


The client does the reference counting whenever it creates another reference on the existing interface.

  1. Call AddRef before the function returns an interface. This includes QueryInterface and CreateInstance functions.

  2. When finished with the interface, Release must be called, to release the memory and decrement the reference counting.

  3. If an interface pointer is assigned to other interface pointer, AddRef must be called. In short, AddRef should be called when another reference of the same interface is created.

  4. Thus, the CreateInstance and QueryInterface will call AddRef function for us before returning. Only Release operation now remains to be done when finished with the interface.

  5. Reference counting is usually done at Component level but it can also be done at Interface level under cases like when the interface uses a lot of memory etc. Under these cases reference counting is individually done for each interface and the interface is deleted when its reference count goes down to zero.

  6. Reference counting is not required if life of an interface is contained in that of the other one. For e.g.

PIUnknown->QueryInterface(IID_IX, (viod**)&pIX);

pIX2=pIX;

pIX2->AddRef();

pIX2->Release();

pIX->Release();

Here the AddRef and Release for pIX2 is not required since the component will not be deleted until pIX is deleted.


Rules for Reference Counting:


  1. An out parameter is a function parameter that returns a value to the function caller and not used by the function itself for other purposes. Any function that returns an interface pointer in an out parameter or return value must do an AddRef.

  2. an in parameter is a function parameter that passes a value to the function that is used by the function. The value is not modified or returned. In this case the lifetime gets nested within the caller’s life and AddRef and Release are not required.

  3. An in-out parameter is both an in and out parameter. The function uses this value, changes it and returns it. AddRef and Release must be called in this case.

  4. AddRef and Release not required for local interface pointers passed as in arguments.

  5. AddRef and Release should be called for an interface pointer stored in a global variable.

  6. When in doubt, AddRef and Release should be called. This is because these two functions are not too expensive but the component not getting deleted at all can be expensive.




HOLLYWOOD FX (Special Effects)

3D Wire Frame Model

3D Model Rendered by 3D Software

"How do they do that !". This is the big question in the minds of awestruck movie audiences worldwide watching a well-made Special Effects movie. Humans fly, prehistoric dinosaurs come back to life, space ships engage in dogfights, volcanoes erupt inside cities... Is there a limit to what the effects guys can achieve on screen ?!

Infact we are venturing into an era where technology is no longer a limitation to bringing magic onto the screen. Only imagination is. What emerges on the story board, finally lands on celluloid. How that actually happens is what this web site is all about. "How do they do that ?!" Well here's how.

Special Effects is both an art and a science. The "science" part involves the complete understanding of how the audio-visual sensory parts of our body and brain perceive the world around us, while the "art" part involves the strategic use of this information to fool the sensory system. The table shown below lists the various scientific phenomenon that work behind the various special effects. First study the scientific facts, and then see how they are exploited by the gurus of Movie Magic.

Persistence of Vision : Look at a bright light for a few seconds and then abruptly close your eyes. The image of the light seems to stay in your eyes a little longer even though your eyes are closed. This phenomenon is termed as Persistence of Vision because the vision seems to persist for a brief moment of time.

When the retina of the eyes are excited by light, they send impulses to the brain which are then interpreted as an image by the visual cortex in the brain. The cells in the retina continue to send impulses even after the incident light is removed. This continues for a few fractions of a second till the retinal cells return back to normal. Until that time, the brain continues to receive impulses from the retina, and hence seems to perceive an image of the source of light, giving rise to the phenomenon called Persistence of Vision.

Principle of Motion Picture : The Principle of Motion Picture is totally based on the phenomenon of Persistence of Vision. Without it, motion picture as we know it simply would'nt exist. Our eyes can retain a picture for a fraction of a second after seeing one. Before this time frame expires, if a another similar picture is shown in its place, the eyes see it as a continuation of the first picture, and don't perceive the gap between the two. If a series of still pictures depicting progressively incrementing action is flashed before the eyes in rapid succession, the eyes see it as a scene depicting smooth, flowing action. All visual media (Movies, TV, Electronic Displays, Laser Light Shows, etc) exploit this phenomenon. Thanks to Persistence of Vision, our entertainment industry could make a transition from perpectual live shows like dance and dramas, to recordable entertainment like movies.

What is Motion : Motion of an object is the continuous displacement of the object in space with reference to another object. In the absence of a reference object, motion ceases to be apparent. What this means is that motion is always measured in relation to another object, which is used as a reference point.

When we drive, the road & the surroundings move past us. Thus we get the sensation of motion. So the road & surroundings are our reference points. When we fly, the earth beneath us is our reference point. But as you can see, the closer the reference point, the more acute the sense of motion. That's why astronauts in orbit seldom sense speed (though they are moving at thousands of miles an hour ) because earth, their only reference point is quite far away.

OK, but what has this got to do with Special Effects ?! A Sfx technique called Compositing totally relies on the way our mind perceives motion. Compositing is one of the most useful tools in a Sfx technician's bag of tricks. Keep these two in mind; the object, and its reference point(s); both of these are necessary to perceive motion in a scene.

Blue Screen : In Compositing, the foreground and background shots are shot seperately and later superimposed one on the other. Certain areas of the foreground have to be transparent for the background detail to show through. (If the foreground detail fills the entire frame, the background detail will not be visible)! For this purpose, the foreground object is usually shot against a plain blue screen. A particular shade of blue called Chroma Blue is used for this purpose. (Human skin does not contain this shade of blue). The blue area is later erased from the frame making the area transparent. The background detail can now show through this blank area.

Story Board : A series of sketches based on the final draft of the script depicting various scenes in the story, which the director, cameraman and the art department use to plan for each scene.

Animation : The art of giving motion to objects is known as Animation. To "animate an object" is to make it move in a realistic fashion. The term applies more specifically to living, organic objects than to inanimate ones. Also, animating living creatures is much more difficult than animating mechanical ones. For example, animating a human being is more difficult than animating an aeroplane. When a human being walks, his/her arms and legs move in a specific way in relation to his/her body, whereas an aeroplane is one whole chunk of metal with relatively few visible moving parts.

Computer Animation : Computer Animation can be broadly classified into 2D and 3D animation. Though both categories take the same approach towards animation, the way each still picture is drawn is drastically different. In 2D animation, the artist draws the scene pretty much the same way he would on a sheet of paper. Only instead of using a pencil or a brush, he now uses a mouse or a graphic tablet. The computer software has the equivalents of all the tools that an artist would use manually. Brushes, pencils, spraying tools, erasers, different types of papers; virtually everything is available in the software. Although all the tools are readily available, the artist has to wholly rely on his ability to draw or paint.

On the other hand, in 3D animation, every object in the scene has to be sculpted in 3D to form what is called a wire frame model. A wire frame model is actually made up of a series of perpendicular lines following the contours of the object. If you cover an object with a figure-hugging suit made of fishing net, and vaporise the object without disturbing the suit, the resulting form looks pretty much like a wire frame model ! Once the model is ready, color and texture are added to the model and lights placed in 3D space around the object. The software then generates the actual still image of the object. The artist does'nt actually paint the still image. He/she only creates the 3D wire frame, assigns colors and texture to the object and places the lights in the scene; the actual painting of the still image is done by the software. The software also takes care of all the additional effects such as shadows, reflections, shine etc,. As you might have guessed, you need to be a good artist to work in 2D, but you have to be a good sculptor to work in 3D.

Sculpting the 3D wire frame model is an elaborate process. There are a lot of modelling tools in the 3D software which allow you to come up with a decent model. There are also scanning tools (hardware equipment) that allow you to scan an actual physical model into the computer.

Whichever way you prefer to fashion your model, at the end of the process, you get a solid 3D wire frame object that looks something like this.

ince the entire vital statistics of the model have been transferred to the software, you can now command the software to render or paint the still image from which ever angle you choose. The program then goes to work and after a few minutes (few or many, depending upon your particular hardware), comes up with a complete rendered 3D image of your model.

Animation Software : A popular method called Key Frame animation is employed by most animation software, be it 2D or 3D. Every animation sequence usually has a few key points. For instance if you want to animate a ball dropping from the top of the screen to the bottom, the key points are the top and bottom positions of the ball. The software program can compute the positions of the ball in the frames in between. This process is called Tweening. The computer Tweens for all the frames in between, whereas the animator provides the data for the Key Frames, where the action starts or stops or changes course. The animator also decides on the number of frames that the animation sequence lasts. This process in not very different from traditional animation where you have Key Frame animators and Tweening artists.

The process of Animation : Attempting to mimic realistic motion of an object is the ultimate aim of animation. But it is also one of the most difficult propositions. Take for instance the human walk. We all walk, but the funniest thing about it is that we know incredibily little about how we do it. It is only when you attempt to recreate a human walk using animation that you actually realise how little you know about the subject. You almost have to learn to walk all over again, to animate a convincing looking walk. The process can be very frustrating at times. A little mistake, and your mind immediately tells you somethings not right. But it does'nt tell you what exactly is wrong. You have to find that using trial and error. And its error that keeps company most of the time. One way is to watch people walk and learn from that. Anyway you got to be careful not to let people catch you staring at them.

Compositing : Compositing is a technique by which one shot is super-imposed on another, resulting in a composite shot. A common example is our everyday weather forecast on TV. The weather map is a seperate computer generated shot onto which the announcer is super-imposed, making it look as if he/she is standing in front of a giant TV screen flashing different weather images.


Your understanding of motion, objects and reference points finally paid of you see ! Now think about the countless possibilities this technique offers you.


  • You can shoot your actors in the studio and composite them onto any outdoor location shot you choose.


  • If the script needs an elaborate set as the back drop, the whole set can be built on a miniature scale. A shot of this set then serves as the background image onto which the actors can be composited.


  • If you replace the model aeroplane in Shots A or C with an actor suspended from the ceiling, you essentially have SuperMan !!!


  • When an actor has to perform a double act with himself, you can composite a shot of the actor playing the first character onto the shot of the same actor playing the second character ! Infact, the number of characters does'nt have to stop with just two. Once you composite character 2 on character 1, you have a film strip showing two characters on the same film. Now you can shoot the third character with the same actor and composite this on the original shot. Thus you get three characters on the same film. Likewise you can go on and on till your patience runs out or till the actor loses track of which character he's playing !


  • Or for instance if you have only one good model of the aeroplane, you can keep compositing the plane on an earlier shot of itself and thus create an aircraft fleet. Think about the air battle in Independence Day. No prizes for guessing how so many aeroplanes were shown on screen on a single shot !