# dpLib #

__dpLib__ is a software library for applying image correction based on the correction data generated by domeprojection.com ProjectionTools. __dpLib__ supports DirectX 9, DirectX 11 and OpenGL.

## Dependencies ##

* [CodeMeter runtime](www.codemeter.de/de/service/downloads.html)
* [DirectX Extension Library](https://msdn.microsoft.com/en-us/library/bb172965(VS.85).aspx)

## Usage ##

To create and initialize the library a *dpContext* have to be created, which is necessary for any further function call. To create a *dpContext* call *dpCreateContext* somewhere in initialization part. After the context is created successful the correction settings have to be loaded from a configuartion file. This is done with a call to *dpLoadConfigurationFromFile*. After these both functions are called successful the *dpContext* is configured and ready to use.
Right before the engine starts rendering the scene call *dpSetActiveChannel* with the desired channel id to prepare the *dpContext*. Then call *dpPreDraw* to retrieve the correct projection matrix or frustum for further rendering. After the engine has rendered the whole scene a call to *dpPostDraw* applies the correction to the scene.
The following pseudo code snippet shows the general usage of __dpLib__.

```c
dpContext* g_pContext;
dpCreateContext(&g_pContext,...)
dpLoadConfigurationFromFile(g_pContext,...)

while(running)
{
    for each channel
    {
        dpSetActiveChannel(g_pContext,...)
        dpPreDraw(g_pContext,...)

        .. render the scene ..

        dpPostDraw(g_pContext,...)

        .. buffer swap ..
    }
}

dpDestroyContext(g_pContext)
```

### Coordinate System ###

__dpLib__ internally works with a right handed coordinate system which means **X** goes from left to right, **Y** from bottom to top and **Z** goes out of the screen.

![coordinate system](coordinatesystem.png "dpLib coordinate system")

Heading/Yaw is the clockwise rotation around the Y-axis, pitch is the counter clockwise rotation around the X-axis and bank/roll is the counter clockwise rotation around the Z-axis.

The order of rotation is heading/yaw first, then pitch, then bank/roll. Assuming matY defines the rotation around the y-axis, matP defines the rotation around the x-axis and matR defines the rotation around the z-axis. The resulting rotation matrix gets calculated by matY * matP * matR.

### Configuration File ###

The following section describes the configuration file used by __dpLib__ in order to configure the correction data to use for each channel.

```xml
<?xml version="1.0" encoding="utf-8"?>
<dpCorrection>
    <!-- type of correction //-->
    <type>0</type>
    <!-- gamma used in ProjectionTools Mapper //-->
    <gamma>2.2</gamma>
    <!-- gamma for source and output //-->
    <input-gamma>2.2</input-gamma>
    <output-gamma>2.2</output-gamma>

    <!-- correction data per channel //-->
    <channel id="0" .../>
    <channel id="1" .../>
</dpCorrection>
```

The number of attributes for a channel tag depends on the selected correction type. __type__ and __gamma__ are set for all channels. To configure static correction the attributes *warpmap* and *frustum* are needed, for dynamic correction *shape* and *target* have to be configured. The attributes *blending*, *blacklevel* and *secondary-blending* are used in both cases.

* static correction
  * warpmap, blending, secondary-blending, blacklevel and frustum
* dynamic correction
  * blending, secondary-blending, blacklevel, shape and target

| tag | description |
| --- | ----------- |
| //__type__ | 0: static correction , 1:dynamic correction |
| //__gamma__ | the gamma value specified in ProjectionTools Mapper |
| //__input-gamma__ | the gamma value of the source image |
| //__output-gamma__ | the desired output gamma value |
| //__channel__[@*id*] | the channel number this tag describes |
| //__channel__[@*warpmap*] | warpmap specifying the correction to apply (for OpenGL only) (for static correction only) |
| //__channel__[@*frustum*] | virtual camera configuration (for static correction only) |
| //__channel__[@*blending*] | blending to apply (for OpenGL only) |
| //__channel__[@*secondary-blending*] | secondary blending to apply (for all graphics engines) |
| //__channel__[@*blacklevel*] | blacklevel to apply (for OpenGL only) |
| //__channel__[@*shape*] | mesh defining the screen shape (for dynamic correction only) |
| //__channel__[@*target*] | mesh defining the target rectangle (for dynamic correction only) |
| //__channel__[@*input-gamma*] | the input gamma value |
| //__channel__[@*output-gamma*] | the output gamma value |
| //__channel__[@*directional-shading*] | color correction texture to apply eyepoint dependent white-point correction (for dynamic correction only) |

All relative file paths are interpreted as relative to configuration file path. When 'c:/file/to/config.xml' is the path the configuration file is located, all relative paths are interpreted as relative to 'c:/file/to'. A relative path 'data/frustum_1.csv' is resolved to 'c:/file/to/data/frustum_1.csv'.

Here are a set of example configurations.

* [3 channel static correction OpenGL](config_3ch_sta.xml "3 channel static correction")
* [3 channel dynamic correction OpenGL](config_3ch_dyn.xml "3 channel dynamic correction")

### ProjectionTools Mapper3d Export Settings ###

To generate static correction data select the __Generic__ exporter and configure it as follows:

* Warping: uv-warped
* Shading: Projector (warped) and png 32bit color
* select Black Level Adjust
* select Frustum

To generate dynamic correction data select the __Generic Advanced 3D__ exporter and configure it as follows:

* Shape: Generic CSV
* Shading: png 32bit color
* select Black Level Adjust
* select Target Rectangle

## API ##

### naming conventions ###

__dpLib__ provides for each graphics engine the same set of functions. According to the graphics engines specifics different parameters are nessecary. Each function for using DirectX 9 ends with *D3D9*, functions for using DirectX 11 are ending with *D3D11* and functions for using OpenGL ends with *OpenGL*.

### API Documentation ###

In general __dpLib__ provides the following set of functions. Each function returns a *dpResult* indicating success or failure. In case of failure, __dpGetErrorString__ returns a more detailed error description.

Rendering:

* dpResult __dpCreateContext__(*dpContext*** ppContext, ...);
* dpResult __dpDestroyContext__(*dpContext** pContext, ...);
* dpResult __dpLoadConfigurationFromFile__(*dpContext** pContext, ...);
* dpResult __dpSetClippingPlanes__(*dpContext** pContext, *float* cNear, *float* cFar);
* dpResult __dpSetActiveChannel__(*dpContext** pContext, *unsigned int* channelId, ...);
* dpResult __dpSetCorrectionPass__(*dpContext** pContext, *dpCorrectionPassType* pass, bool enabled);
* dpResult __dpSetCorrectionPass1__(*dpContext** pContext, *dpCorrectionPassType* pass, float value);
* dpResult __dpSetFlipWarpmeshVerticesY__(*dpContext** pContext, bool flip);
* dpResult __dpSetFlipWarpmeshTexcoordsV__(*dpContext** pContext, bool flip);
* dpResult __dpPreDraw__(*dpContext** pContext, *const dpVec3f* eyepoint, *dpVec3f** pOrientation, *dpMatrix4x4** pProjection, ...);
* dpResult __dpPreDraw1__(*dpContext** pContext,*const dpVec3f* eyepoint, *dpCamera** pCamera);
* dpResult __dpPostDraw__(*dpContext** pContext, ...)

General:

* dpResult __dpGetErrorString__(*dpContext** pContext, *char** pBuffer, *size_t* length);
* dpResult __dpGetVersion__(*int** pMajor, *int** pMinor, *int** pRevision, *int** pBuild);
* dpResult __dpGetVersionString__(*char** pBuffer, *size_t* length);

Correction passes:

__dpLib__ supports the following correction passes:
* dpWarpingPass: correction pass applying the warping
* dpBlendingPass: correction pass applying blending
* dpBlackLevelPass: correction pass applying black level correction
* dpSecondaryBlendingPass: correction pass applying a secondary blending
* dpDirectionalShadingPass: correction pass applying eyepoint-dependent white-point correction
Each pass can be enabled/disabled via __dpSetCorrectionPass__. With a call to __dpSetCorrectionPass1__ the intensity can be set between 0 and 1.

See [dpLib.h](../include/dpLib.h) for a more detailed function description.

## pluginID ##

The __pluginId__ necessary for creating the *dpContext* is a very specific number provided by domeprojection.com GmbH. Please contact domeprojection.com GmbH for details.