The design of the rendering model was driven by three requirements:
| 1. | The Framework should be completely unaware of how rendering is done. That is, it should be technology (e.g., GDI+, OpenGL, etc.) and hardware independent. |
| 2. | A plugin developer should have complete control over how rendering is done. |
| 3. | Different types of images (2D, 3D, etc.) should be renderable by different renderers. |

Now, let’s try and understand how these requirements are met by the rendering object model shown above.
First, the renderer and the rendering surface are both abstracted through the IRenderer and IRenderingSurface interfaces. By using interfaces, the Framework need not know anything about the specifics of how rendering is done, thus meeting Requirement #1.
Second, IRenderingSurface has two properties, WindowID and ContextID (which on Windows, corresponds to an hwnd and hdc respectively). These two IDs, provided to IRenderingSurface by the TileControl (which is just a WinForms UserControl), give the implementer of IRenderingSurface complete control over how rendering is done, since it makes no assumptions about what rendering technology is to be used. In fact, those two IDs are all you need to make just about any technology work, be it GDI+, OpenGL or DirectX. This meets Requirement #2.
Third, every PresentationImage owns an IRenderer. This allows different subclasses of PresentationImage to use different implementations of IRenderer, thereby meeting Requirement #3.
An important implication of this design is that implementations of IRenderer and IRenderingSurface and a subclass of PresentationImage can all be contained in one plugin. Consider for example, the use case in which you, the plugin developer, wants to create a 3D volume rendering from DICOM images provided through the CC Framework. In such a scenario you could create a VolumeRenderer that would know how to render a VolumePresentationImage to a VolumeRenderingSurface. All of those classes could be defined in a single plugin.