Using OpenGL.NET

We have already concluded that the OpenGL library will be used to implement the 3D text functionality. Now we must develop a design that allows the implementation of this feature within the photo editor application.

All .NET code is managed. This means that the .NET runtime has control over the code and can enforce things such as security rules or garbage collection. The OpenGL library, however, is not managed by the .NET runtime. It is therefore considered unmanaged code and requires special handling. To access unmanaged code from a .NET application, the code must be contained in a DLL.

The .NET technology that allows access to unmanaged code is called the Platform Invocation service (PInvoke). PInvoke allows .NET applications to call API functions from any Windows DLL.

One approach to the integration of OpenGL rendering capabilities into the photo editor would be to declare all needed OpenGL API functions from opengl32.dll and glu32.dll within the .NET application. Another approach would be to build a new DLL that provides some high-level functions to render 3D text. Because all interfaces to unmanaged code in .NET, along with their parameters, must be declared manually, we decide to build a new DLL that provides only a few API functions that allow the photo editor to add 3D text to an image.

9.4.1 Rendering Three-Dimensional Text with OpenGL

We need very little knowledge about OpenGL to define the interfaces for the 3D Text DLL.

To render text using OpenGL, we create a window and a rendering context within that window. All OpenGL operations are rendered into the rendering context and are automatically displayed in the associated window.

For the photo editor application, however, offline rendering is desired. This means that we are not interested in displaying the text directly in a window but instead want to merge it into an existing Bitmap object that represents the loaded image. There are vendor-specific extensions (p-Buffer) for that purpose. However, the requirement image_3dtext prohibits the use of extensions, including p-Buffer, that are limited to a specific kind of graphics card.

Another way to achieve the same result is to create a window without making it visible on the screen. We can then read the content of the rendering context using the glReadPixel command.

Several libraries provide utility functions for drawing text in OpenGL, and some of them are even platform-independent. But because platform interoperability is not a requirement for the photo editor, the easiest and most straightforward approach should be taken. In our opinion this is to use the wglUseFontOutlines API function, which is supported on all Windows platforms. It directly converts a TrueType font into a set of OpenGL drawing commands. These commands are stored in lists, one for each letter. To draw text, you call those lists using the glCallLists API function.

The OpenGL library functions as a state machine. To modify the orientation or position of an object, you change the OpenGL state before drawing. For example, glTranslate modifies the translation of all objects drawn thereafter. In the same way, glColor changes the color in which those objects are rendered.

Having a basic understanding of OpenGL, we can now continue defining the interfaces for the 3D Text DLL as an extension to the photo editor application.

9.4.2 Three-Dimensional Text DLL Interfaces

Earlier in this chapter we decided that the 3D Text DLL will provide high-level API functions to render the text. Then we discovered that rendering text requires the creation of a window as well as conversion of a TrueType font into OpenGL commands. Both steps are rather time-consuming and should not be repeated every time the user adjusts the font color or the text position. Therefore, it makes sense to split these tasks into dedicated API functions. Table 9.3 lists the proposed API functions that we are planning to implement.

Before you define interfaces, it's a good practice to evaluate the usage of the proposed API functions in a sequence diagram for a typical use case. This helps you to understand the context in which the API functions are used. It also may help you discover wrong assumptions or may even lead to simplifications early on. The sequence diagram in Figure 9.3 shows how the API functions are invoked when the 3D text feature is used.

Figure 9.3. Sequence Diagram for 3D Text Feature

Table 9.3. Proposed 3D Text DLL API Functions

API Function Name

Parameters

Summary

CreateRC

Dimensions

Creates an OpenGL window and rendering context of the specified size

DeleteRC

None

Destroys a previously created window and rendering context

CreateOutlineFont

Font name, Font style

Converts the given TrueType font into OpenGL drawing commands

DeleteOutlineFont

None

Deletes a previously created OpenGL font

RenderText

Text, text size, color, rotation, image buffer

Renders text with the given attributes

Категории