# Appendix A: Sample code

Please refer to the following code snippets for information on how to the Warping Library and <span style="color: rgb(230, 126, 35);">[Candera](http://dev.doc.cgistudio.at/APILINK/namespace_candera.html "[DataBinding_RefTypeSample]")</span> are used in order to calculate the warped output that will be rendered on display.

#### Create Warp Matrix

```
    en_warp_result_t enResult = WarpResultSuccess;          // Enumeration for possible return values of warping library functions.
    stc_warp_configuration_parameter_t stcWarpConfigParams; // Warping configuration parameters and limit parameters.
    stc_warp_parameter_set_t stcWarpParamSet;               // Structure of the encoded input parameter set for the reference points.
    stc_warp_matrix_t stcWarpMatrix;                        // Structure for the calculated matrix vertex points.
    
    ... // Specify the configuration parameters and the input parameter set according the project needs
    
    // generate the warp matrix based on provided input configuration data
    enResult = CalculateWarpMatrix(&stcWarpConfigParams, &stcWarpParamSet, &stcWarpMatrix);

    // check return error of previous call
    if (enResult == WarpResultSuccess) {
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___f_e_a_t_s_t_d___d_i_a_g_n_o_s_t_i_c_s.html#ga1fc8f6fbe760498d4d2ea7e9760c6576">FEATSTD_LOG_DEBUG</a>("Warp matrix succsessfully created.\n");
    } else {
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___f_e_a_t_s_t_d___d_i_a_g_n_o_s_t_i_c_s.html#ga1fc8f6fbe760498d4d2ea7e9760c6576">FEATSTD_LOG_DEBUG</a>("Failed to create warp matrix.\n");
    }
```

#### Warp Matrix Adjustments

```
    en_warp_result_t enResult = WarpResultSuccess;          // Enumeration for possible return values of warping library functions.
    stc_warp_configuration_parameter_t stcWarpConfigParams; // Warping configuration parameters and limit parameters.
    stc_warp_adjust_parameter_t stcWarpAdjustParams;        // Structure with all parameters for delta calculation.
    stc_warp_matrix_t stcWarpMatrix;                        // Structure for the calculated matrix vertex points.
    en_warp_bool_t bSuccess;
    
    ... // Specify the configuration parameters
    
    // Specify parameters for delta calculation (example)
    stcWarpAdjustParams.WarpAdjustMode = WarpAdjustModeTrapezoid;
    stcWarpAdjustParams.WarpAdjustDirection = WarpAdjustDirectionDown;
    stcWarpAdjustParams.WarpDelta = 100;
    
    enResult = AdjustWarpMatrix(&stcWarpConfigParams, &stcWarpAdjustParams, &bSuccess, &stcWarpMatrix);

    if (enResult == WarpResultSuccess) {
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___f_e_a_t_s_t_d___d_i_a_g_n_o_s_t_i_c_s.html#ga1fc8f6fbe760498d4d2ea7e9760c6576">FEATSTD_LOG_DEBUG</a>("Adjusted warp matrix.\n");
    } else {
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___f_e_a_t_s_t_d___d_i_a_g_n_o_s_t_i_c_s.html#ga1fc8f6fbe760498d4d2ea7e9760c6576">FEATSTD_LOG_DEBUG</a>("Failed to adjust warp matrix.\n");
    }
```

#### Create the Candera WarpMatrix from the previously calculated warp matrix

<div class="contents" id="bkmrk-"><div class="contents"><div class="textblock"><div class="fragment">  
</div></div></div></div>```
      // Create warp matrix. This is a proof of the disposer concept.
      // The matrix data doesn't need to be copied, since it is static and can
      // be simply set into the warp matrix without a disposer.
      Candera::Float* matrixData = CANDERA_NEW_ARRAY(Candera::Float, 2 * stcWarpMatrix.usNumRefPointsX * stcWarpMatrix.usNumRefPointsY);
      if (matrixData == 0) {
        FEATSTD_LOG_ERROR("failed to allocate matrix data");
        return;
      }
      Candera::MemoryPlatform::Copy(matrixData, FeatStd::Internal::PointerToPointer<void*>(stcWarpMatrix.pVertex), 2 * stcWarpMatrix.usNumRefPointsX * stcWarpMatrix.usNumRefPointsY * sizeof(Candera::Float));
      typedef <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_memory_management_1_1_adapted_array_disposer.html" title="A native FeatStd Array Disposer which calls FEATSTD_DELETE_ARRAY in Dispose, but first casts...">Candera::MemoryManagement::AdaptedArrayDisposer<Candera::WarpMatrix::ConstData, const Candera::Float*></a> MatrixDataDisposer;
      Candera::WarpMatrix warpMatrix(stcWarpMatrix.usNumRefPointsX, stcWarpMatrix.usNumRefPointsY, matrixData, &MatrixDataDisposer::Dispose);
```

#### Calculate Warp Texture Bounds

```
      WRP_SFLOAT textureOriginX; 
      WRP_SFLOAT textureOriginY;
      WRP_SFLOAT textureWidth;
      WRP_SFLOAT textureHeight;
      
      ComputeWarpImageBoundsFromConfig(&stcWarpConfigParams, &textureOriginX, &textureOriginY, &textureWidth, &textureHeight);
      <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_rectangle.html" title="Represents a rectangle.">Candera::Rectangle</a> warpTextureBounds(textureOriginX, textureOriginY, textureWidth, textureHeight);
```

#### Render Warped Image to Display

```
      // define display parameters
      Candera::Display::CommonSettings params;
      Candera::MemoryPlatform::Set(&params, 0, sizeof(params));

      params.width =          800;
      params.hps =            832;
      params.hpe =            976;
      params.hpt =            1008;
      
      params.height =         600; 
      params.vps =            612; 
      params.vpe =            618; 
      params.vpt =            631;
        
      params.refreshRate =    60;
      params.colorBits =      32;
      
      // create display
      Candera::Display *display = Candera::DevicePackageInterface::CreateDisplay(0);
      if (display == 0) {
          FEATSTD_LOG_ERROR("Failed to create display.");
          return false;
      }
      
      //enable warping
      display->SetWarpingEnabled(true);
      
      // pass previously created Candera warpMatrix to display
      display->SetWarpMatrix(warpMatrix);          
      
      // optionally, set the warp texture bounds
      display->SetWarpImageBounds(warpTextureBounds);
      
      // ApplyChanges() has to be called for the changes to be taken into account
      display->ApplyChanges(); 
      
      //upload display
      if (!display->Upload(params)) {
          FEATSTD_LOG_ERROR("Failed to upload display.");
          return false;
      }
```

<p class="callout info">Warping should be enabled before the NativeHandle is attached to the display (attached either by AttachNativeHandle or created at display upload).  
</p>

#### Create a Default WarpMatrix Data

```
      // retrieve display
      Candera::Display *display = Candera::DevicePackageInterface::GetDisplay(0);
      
      if (display == 0) {
        FEATSTD_LOG_ERROR("Failed to retrieve display.");
        return false;
      }      
      
      // default warpMatrix data
      static const Candera::Float data[] = {
                0.0F, 0.0F,
                1.0F, 0.0F,
                0.0F, 1.0F,
                1.0F, 1.0F,
            };
      
      Candera::WarpMatrix warpMatrix(2, 2, data);
      display->SetWarpMatrix(warpMatrix);
      
      <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_rectangle.html" title="Represents a rectangle.">Candera::Rectangle</a> defaultImageBounds(0.F, 0.F, 1.F, 1.F);
      display->SetWarpImageBounds(defaultImageBounds);
```

<div class="contents" id="bkmrk--0"><div class="contents"><div class="textblock"><div class="fragment">---

</div></div></div></div>