mosaic_renderer_jni.cpp revision 41a2e9735136f372de95652d0828600282c8e967
1eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// OpenGL ES 2.0 code 2eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <jni.h> 3eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <android/log.h> 4eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 5eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <db_utilities_camera.h> 6eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic/ImageUtils.h" 7eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/FrameBuffer.h" 8eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/WarpRenderer.h" 941a2e9735136f372de95652d0828600282c8e967mbansal#include "mosaic_renderer/SurfaceTextureRenderer.h" 10eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <stdio.h> 11eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <stdlib.h> 12eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <math.h> 13eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 14eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer_jni.h" 15eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 16eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define LOG_TAG "MosaicRenderer" 17eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 1841a2e9735136f372de95652d0828600282c8e967mbansal#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__) 19eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 20eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 21eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Texture handle 2241a2e9735136f372de95652d0828600282c8e967mbansalGLuint gSurfaceTextureID[1]; 23eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 2441a2e9735136f372de95652d0828600282c8e967mbansalbool gWarpImage = true; 25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 2641a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res input image frame in RGB format for preview rendering and processing 2741a2e9735136f372de95652d0828600282c8e967mbansal// and high-res RGB input image for processing. 2841a2e9735136f372de95652d0828600282c8e967mbansalunsigned char* gPreviewImageRGB[NR]; 2941a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image width 3041a2e9735136f372de95652d0828600282c8e967mbansalint gPreviewImageRGBWidth[NR]; 3141a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image height 3241a2e9735136f372de95652d0828600282c8e967mbansalint gPreviewImageRGBHeight[NR]; 33eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 34eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Semaphore to protect simultaneous read/writes from gPreviewImageRGB 35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalsem_t gPreviewImageRGB_semaphore; 3641a2e9735136f372de95652d0828600282c8e967mbansalsem_t gPreviewImageReady_semaphore; 37eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 38eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO width (large enough to store the entire 39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic). 40eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOWidth; 41eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO height (large enough to store the entire 42eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic). 43eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOHeight; 44eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 4541a2e9735136f372de95652d0828600282c8e967mbansal// Shader to copy input SurfaceTexture into and RGBA FBO. The two shaders 4641a2e9735136f372de95652d0828600282c8e967mbansal// render to the textures with dimensions corresponding to the low-res and 4741a2e9735136f372de95652d0828600282c8e967mbansal// high-res image frames. 4841a2e9735136f372de95652d0828600282c8e967mbansalSurfaceTextureRenderer gSurfTexRenderer[NR]; 4941a2e9735136f372de95652d0828600282c8e967mbansal// Off-screen FBOs to store the low-res and high-res RGBA copied out from 5041a2e9735136f372de95652d0828600282c8e967mbansal// the SurfaceTexture by the gSurfTexRenderers. 5141a2e9735136f372de95652d0828600282c8e967mbansalFrameBuffer gBufferInput[NR]; 52eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Shader to add warped current frame to the preview FBO 53eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer gWarper; 54eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Shader to warp and render the preview FBO to the screen 55eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer gPreview; 56eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen FBO to store the result of gWarper 5741a2e9735136f372de95652d0828600282c8e967mbansalFrameBuffer gBuffer; 58eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 59eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Affine transformation in GL 4x4 format (column-major) to warp the 6041a2e9735136f372de95652d0828600282c8e967mbansal// current frame into the first frame coordinate system. 61eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransGL[16]; 62eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 63eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Affine transformation in GL 4x4 format (column-major) to warp the 6441a2e9735136f372de95652d0828600282c8e967mbansal// preview FBO into the current frame coordinate system. 65eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransInvGL[16]; 66eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 67eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// GL 4x4 Identity transformation 68eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransIdent[] = { 69eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 1., 0., 0., 0., 70eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 1., 0., 0., 71eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 0., 1., 0., 72eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 0., 0., 1.}; 73eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7441a2e9735136f372de95652d0828600282c8e967mbansalconst int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65; 75eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 76eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalstatic void printGLString(const char *name, GLenum s) { 77eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal const char *v = (const char *) glGetString(s); 78eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal LOGI("GL %s = %s\n", name, v); 79eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 80eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 81eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// @return false if there was an error 82eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool checkGlError(const char* op) { 83eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GLint error = glGetError(); 84eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (error != 0) { 85eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal LOGE("after %s() glError (0x%x)\n", op, error); 86eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return false; 87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return true; 89eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 90eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 9141a2e9735136f372de95652d0828600282c8e967mbansalvoid bindSurfaceTexture(GLuint texId) 92eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 9341a2e9735136f372de95652d0828600282c8e967mbansal glBindTexture(GL_TEXTURE_EXTERNAL_OES_ENUM, texId); 9441a2e9735136f372de95652d0828600282c8e967mbansal 9541a2e9735136f372de95652d0828600282c8e967mbansal // Can't do mipmapping with camera source 9641a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MIN_FILTER, 9741a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 9841a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MAG_FILTER, 9941a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 10041a2e9735136f372de95652d0828600282c8e967mbansal // Clamp to edge is the only option 10141a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_S, 10241a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 10341a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_T, 10441a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 105eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 106eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 10741a2e9735136f372de95652d0828600282c8e967mbansalvoid ClearPreviewImageRGB(int mID) 108eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 10941a2e9735136f372de95652d0828600282c8e967mbansal unsigned char* ptr = gPreviewImageRGB[mID]; 11041a2e9735136f372de95652d0828600282c8e967mbansal for(int j = 0, i = 0; 11141a2e9735136f372de95652d0828600282c8e967mbansal j < gPreviewImageRGBWidth[mID] * gPreviewImageRGBHeight[mID] * 4; 11241a2e9735136f372de95652d0828600282c8e967mbansal j += 4) 11341a2e9735136f372de95652d0828600282c8e967mbansal { 11441a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 11541a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 11641a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 11741a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 255; 11841a2e9735136f372de95652d0828600282c8e967mbansal } 11941a2e9735136f372de95652d0828600282c8e967mbansal 120eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 121eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 122eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid ConvertAffine3x3toGL4x4(double *matGL44, double *mat33) 123eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 124eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[0] = mat33[0]; 125eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[1] = mat33[3]; 126eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[2] = 0.0; 127eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[3] = mat33[6]; 128eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 129eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[4] = mat33[1]; 130eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[5] = mat33[4]; 131eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[6] = 0.0; 132eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[7] = mat33[7]; 133eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 134eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[8] = 0; 135eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[9] = 0; 136eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[10] = 1.0; 137eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[11] = 0.0; 138eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 139eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[12] = mat33[2]; 140eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[13] = mat33[5]; 141eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[14] = 0.0; 142eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[15] = mat33[8]; 143eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 144eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 145eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// This function computes fills the 4x4 matrices g_dAffinetrans and 146eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// g_dAffinetransInv using the specified 3x3 affine transformation 147eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// between the first captured frame and the current frame. The computed 148eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// g_dAffinetrans is such that it warps the current frame into the 149eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// coordinate system of the first frame. Thus, applying this transformation 150eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// to each successive frame builds up the preview mosaic in the first frame 151eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// coordinate system. Then the computed g_dAffinetransInv is such that it 152eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// warps the computed preview mosaic into the coordinate system of the 153eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// original (as captured) current frame. This has the effect of showing 154eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// the current frame as is (without warping) but warping the rest of the 155eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// mosaic data to still be in alignment with this frame. 156eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid UpdateWarpTransformation(float *trs) 157eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 158eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal double H[9], Hinv[9], Hp[9], Htemp[9]; 159eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal double K[9], Kinv[9]; 160eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 16141a2e9735136f372de95652d0828600282c8e967mbansal int w = gPreviewImageRGBWidth[LR]; 16241a2e9735136f372de95652d0828600282c8e967mbansal int h = gPreviewImageRGBHeight[LR]; 163eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 164eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // K is the transformation to map the canonical [-1,1] vertex coordinate 165eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // system to the [0,w] image coordinate system before applying the given 166eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // affine transformation trs. 167eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[0] = w / 2.0; 168eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[1] = 0.0; 169eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[2] = w / 2.0; 170eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[3] = 0.0; 171eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[4] = -h / 2.0; 172eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[5] = h / 2.0; 173eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[6] = 0.0; 174eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[7] = 0.0; 175eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[8] = 1.0; 176eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 177eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Identity3x3(Kinv); 178eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_InvertCalibrationMatrix(Kinv, K); 179eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 180eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal for(int i=0; i<9; i++) 181eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 182eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal H[i] = trs[i]; 183eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 184eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 185eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Move the origin such that the frame is centered in the previewFBO 18641a2e9735136f372de95652d0828600282c8e967mbansal H[2] += (gPreviewFBOWidth / 2 - gPreviewImageRGBWidth[LR] / 2); 18741a2e9735136f372de95652d0828600282c8e967mbansal H[5] -= (gPreviewFBOHeight / 2 - gPreviewImageRGBHeight[LR] / 2); 188eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 189eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Hp = inv(K) * H * K 190eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Identity3x3(Htemp); 191eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Multiply3x3_3x3(Htemp, H, K); 192eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Multiply3x3_3x3(Hp, Kinv, Htemp); 193eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 194eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal ConvertAffine3x3toGL4x4(g_dAffinetrans, Hp); 195eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 196eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal //////////////////////////////////////////////// 197eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal ////// Compute g_dAffinetransInv now... ////// 198eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal //////////////////////////////////////////////// 199eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 200eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal w = gPreviewFBOWidth; 201eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal h = gPreviewFBOHeight; 202eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 203eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[0] = w / 2.0; 204eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[1] = 0.0; 205eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[2] = w / 2.0; 206eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[3] = 0.0; 207eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[4] = h / 2.0; 208eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[5] = h / 2.0; 209eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[6] = 0.0; 210eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[7] = 0.0; 211eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal K[8] = 1.0; 212eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 213eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Identity3x3(Kinv); 214eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_InvertCalibrationMatrix(Kinv, K); 215eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 216eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Identity3x3(Hinv); 217eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_InvertAffineTransform(Hinv, H); 218eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 21941a2e9735136f372de95652d0828600282c8e967mbansal Hinv[2] += (gPreviewFBOWidth / 2 - gPreviewImageRGBWidth[LR] / 2); 22041a2e9735136f372de95652d0828600282c8e967mbansal Hinv[5] -= (gPreviewFBOHeight / 2 - gPreviewImageRGBHeight[LR] / 2); 221eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 222eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Hp = inv(K) * Hinv * K 223eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Identity3x3(Htemp); 224eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Multiply3x3_3x3(Htemp, Hinv, K); 225eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal db_Multiply3x3_3x3(Hp, Kinv, Htemp); 226eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 227eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal ConvertAffine3x3toGL4x4(g_dAffinetransInv, Hp); 228eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 229eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 23041a2e9735136f372de95652d0828600282c8e967mbansalvoid AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) 231eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 23241a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBWidth[HR] = widthHR; 23341a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[HR] = heightHR; 23441a2e9735136f372de95652d0828600282c8e967mbansal 23541a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBWidth[LR] = widthLR; 23641a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[LR] = heightLR; 237eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 238eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_init(&gPreviewImageRGB_semaphore, 0, 1); 23941a2e9735136f372de95652d0828600282c8e967mbansal sem_init(&gPreviewImageReady_semaphore, 0, 1); 240eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 241eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_wait(&gPreviewImageRGB_semaphore); 24241a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGB[LR] = ImageUtils::allocateImage(gPreviewImageRGBWidth[LR], 24341a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[LR], 4); 24441a2e9735136f372de95652d0828600282c8e967mbansal ClearPreviewImageRGB(LR); 24541a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGB[HR] = ImageUtils::allocateImage(gPreviewImageRGBWidth[HR], 24641a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[HR], 4); 24741a2e9735136f372de95652d0828600282c8e967mbansal ClearPreviewImageRGB(HR); 248eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_post(&gPreviewImageRGB_semaphore); 249eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 25041a2e9735136f372de95652d0828600282c8e967mbansal gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageRGBWidth[LR]; 25141a2e9735136f372de95652d0828600282c8e967mbansal gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageRGBHeight[LR]; 252eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 253eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal UpdateWarpTransformation(g_dAffinetransIdent); 254eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 255eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 256eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid FreeTextureMemory() 257eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 258eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_wait(&gPreviewImageRGB_semaphore); 25941a2e9735136f372de95652d0828600282c8e967mbansal ImageUtils::freeImage(gPreviewImageRGB[LR]); 26041a2e9735136f372de95652d0828600282c8e967mbansal ImageUtils::freeImage(gPreviewImageRGB[HR]); 261eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_post(&gPreviewImageRGB_semaphore); 262eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 263eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_destroy(&gPreviewImageRGB_semaphore); 26441a2e9735136f372de95652d0828600282c8e967mbansal sem_destroy(&gPreviewImageReady_semaphore); 265eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 266eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 267eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalextern "C" 268eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 26941a2e9735136f372de95652d0828600282c8e967mbansal JNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init( 270eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 271eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset( 272eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj, jint width, jint height); 27341a2e9735136f372de95652d0828600282c8e967mbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preprocess( 27441a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix); 27541a2e9735136f372de95652d0828600282c8e967mbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferGPUtoCPU( 27641a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj); 277eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step( 278eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 279eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_ready( 280eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 28141a2e9735136f372de95652d0828600282c8e967mbansal JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarping( 28241a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag); 283eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}; 284eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 28541a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init( 286eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 287eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 28841a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].InitializeGLProgram(); 28941a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].InitializeGLProgram(); 290eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gWarper.InitializeGLProgram(); 291eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.InitializeGLProgram(); 29241a2e9735136f372de95652d0828600282c8e967mbansal gBuffer.InitializeGLContext(); 29341a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].InitializeGLContext(); 29441a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].InitializeGLContext(); 295eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 296eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 29741a2e9735136f372de95652d0828600282c8e967mbansal 29841a2e9735136f372de95652d0828600282c8e967mbansal glGenTextures(1, gSurfaceTextureID); 29941a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 30041a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 30141a2e9735136f372de95652d0828600282c8e967mbansal 30241a2e9735136f372de95652d0828600282c8e967mbansal return (jint) gSurfaceTextureID[0]; 303eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 304eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 30541a2e9735136f372de95652d0828600282c8e967mbansal 306eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset( 307eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj, jint width, jint height) 308eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 30941a2e9735136f372de95652d0828600282c8e967mbansal gBuffer.Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); 31041a2e9735136f372de95652d0828600282c8e967mbansal 31141a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].Init(gPreviewImageRGBWidth[LR], 31241a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[LR], GL_RGBA); 31341a2e9735136f372de95652d0828600282c8e967mbansal 31441a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].Init(gPreviewImageRGBWidth[HR], 31541a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[HR], GL_RGBA); 316eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 317eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_wait(&gPreviewImageRGB_semaphore); 31841a2e9735136f372de95652d0828600282c8e967mbansal ClearPreviewImageRGB(LR); 31941a2e9735136f372de95652d0828600282c8e967mbansal ClearPreviewImageRGB(HR); 320eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal sem_post(&gPreviewImageRGB_semaphore); 321eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 32241a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 32341a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 32441a2e9735136f372de95652d0828600282c8e967mbansal 32541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetupGraphics(&gBufferInput[LR]); 32641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].Clear(0.0, 0.0, 0.0, 1.0); 32741a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetViewportMatrix(1, 1, 1, 1); 32841a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetScalingMatrix(1.0f, -1.0f); 32941a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureName(gSurfaceTextureID[0]); 33041a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 331eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 33241a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetupGraphics(&gBufferInput[HR]); 33341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].Clear(0.0, 0.0, 0.0, 1.0); 33441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetViewportMatrix(1, 1, 1, 1); 33541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetScalingMatrix(1.0f, -1.0f); 33641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureName(gSurfaceTextureID[0]); 33741a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 33841a2e9735136f372de95652d0828600282c8e967mbansal 33941a2e9735136f372de95652d0828600282c8e967mbansal gWarper.SetupGraphics(&gBuffer); 340eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gWarper.Clear(0.0, 0.0, 0.0, 1.0); 34141a2e9735136f372de95652d0828600282c8e967mbansal gWarper.SetViewportMatrix(gPreviewImageRGBWidth[LR], 34241a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGBHeight[LR], gBuffer.GetWidth(), 34341a2e9735136f372de95652d0828600282c8e967mbansal gBuffer.GetHeight()); 344eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gWarper.SetScalingMatrix(1.0f, 1.0f); 34541a2e9735136f372de95652d0828600282c8e967mbansal gWarper.SetInputTextureName(gBufferInput[LR].GetTextureName()); 34641a2e9735136f372de95652d0828600282c8e967mbansal gWarper.SetInputTextureType(GL_TEXTURE_2D); 347eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 348eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetupGraphics(width, height); 349eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.Clear(0.0, 0.0, 0.0, 1.0); 350eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetViewportMatrix(1, 1, 1, 1); 351eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetScalingMatrix(1.0f, -1.0f); 35241a2e9735136f372de95652d0828600282c8e967mbansal gPreview.SetInputTextureName(gBuffer.GetTextureName()); 35341a2e9735136f372de95652d0828600282c8e967mbansal gPreview.SetInputTextureType(GL_TEXTURE_2D); 35441a2e9735136f372de95652d0828600282c8e967mbansal} 35541a2e9735136f372de95652d0828600282c8e967mbansal 35641a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preprocess( 35741a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix) 35841a2e9735136f372de95652d0828600282c8e967mbansal{ 35941a2e9735136f372de95652d0828600282c8e967mbansal jfloat *stmat = env->GetFloatArrayElements(stMatrix, 0); 36041a2e9735136f372de95652d0828600282c8e967mbansal 36141a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetSTMatrix((float*) stmat); 36241a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetSTMatrix((float*) stmat); 36341a2e9735136f372de95652d0828600282c8e967mbansal 36441a2e9735136f372de95652d0828600282c8e967mbansal env->ReleaseFloatArrayElements(stMatrix, stmat, 0); 36541a2e9735136f372de95652d0828600282c8e967mbansal 36641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdent); 36741a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdent); 36841a2e9735136f372de95652d0828600282c8e967mbansal} 36941a2e9735136f372de95652d0828600282c8e967mbansal 37041a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferGPUtoCPU( 37141a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj) 37241a2e9735136f372de95652d0828600282c8e967mbansal{ 37341a2e9735136f372de95652d0828600282c8e967mbansal sem_wait(&gPreviewImageRGB_semaphore); 37441a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input LR FBO and read the Low-Res data from there... 37541a2e9735136f372de95652d0828600282c8e967mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInput[LR].GetFrameBufferName()); 37641a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 37741a2e9735136f372de95652d0828600282c8e967mbansal 0, 37841a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetWidth(), 37941a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetHeight(), 38041a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 38141a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 38241a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGB[LR]); 38341a2e9735136f372de95652d0828600282c8e967mbansal 38441a2e9735136f372de95652d0828600282c8e967mbansal checkGlError("glReadPixels LR"); 38541a2e9735136f372de95652d0828600282c8e967mbansal 38641a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input HR FBO and read the high-res data from there... 38741a2e9735136f372de95652d0828600282c8e967mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInput[HR].GetFrameBufferName()); 38841a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 38941a2e9735136f372de95652d0828600282c8e967mbansal 0, 39041a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetWidth(), 39141a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetHeight(), 39241a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 39341a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 39441a2e9735136f372de95652d0828600282c8e967mbansal gPreviewImageRGB[HR]); 39541a2e9735136f372de95652d0828600282c8e967mbansal 39641a2e9735136f372de95652d0828600282c8e967mbansal checkGlError("glReadPixels HR"); 39741a2e9735136f372de95652d0828600282c8e967mbansal 39841a2e9735136f372de95652d0828600282c8e967mbansal sem_post(&gPreviewImageRGB_semaphore); 399eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 400eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 401eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step( 402eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 403eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 404eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Use the gWarper shader to apply the current frame transformation to the 405eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // current frame and then add it to the gBuffer FBO. 406eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gWarper.DrawTexture(g_dAffinetransGL); 407eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 408eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Use the gPreview shader to apply the inverse of the current frame 409eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // transformation to the gBuffer FBO and render it to the screen. 410eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.DrawTexture(g_dAffinetransInvGL); 411eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 412eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 41341a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarping( 41441a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag) 415eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 41641a2e9735136f372de95652d0828600282c8e967mbansal // TODO: Review this logic 41741a2e9735136f372de95652d0828600282c8e967mbansal if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa 41841a2e9735136f372de95652d0828600282c8e967mbansal { 41941a2e9735136f372de95652d0828600282c8e967mbansal gWarper.Clear(0.0, 0.0, 0.0, 1.0); 42041a2e9735136f372de95652d0828600282c8e967mbansal gPreview.Clear(0.0, 0.0, 0.0, 1.0); 42141a2e9735136f372de95652d0828600282c8e967mbansal // Clear the screen to black. 42241a2e9735136f372de95652d0828600282c8e967mbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 42341a2e9735136f372de95652d0828600282c8e967mbansal glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 42441a2e9735136f372de95652d0828600282c8e967mbansal glClear(GL_COLOR_BUFFER_BIT); 42541a2e9735136f372de95652d0828600282c8e967mbansal } 42641a2e9735136f372de95652d0828600282c8e967mbansal gWarpImage = (bool)flag; 427eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 428eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 429eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 430eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_ready( 431eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 432eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 43341a2e9735136f372de95652d0828600282c8e967mbansal if(!gWarpImage) 434eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 43541a2e9735136f372de95652d0828600282c8e967mbansal // TODO: Review this logic... 43641a2e9735136f372de95652d0828600282c8e967mbansal UpdateWarpTransformation(g_dAffinetransIdent); 43741a2e9735136f372de95652d0828600282c8e967mbansal 438eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal for(int i=0; i<16; i++) 439eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 440eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal g_dAffinetrans[i] = g_dAffinetransIdent[i]; 44141a2e9735136f372de95652d0828600282c8e967mbansal g_dAffinetransInv[i] = g_dAffinetransIdent[i]; 442eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 44341a2e9735136f372de95652d0828600282c8e967mbansal g_dAffinetrans[12] = 1.0f; 44441a2e9735136f372de95652d0828600282c8e967mbansal g_dAffinetrans[13] = 1.0f; 445eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 446eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 447eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal for(int i=0; i<16; i++) 448eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 449eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal g_dAffinetransGL[i] = g_dAffinetrans[i]; 450eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal g_dAffinetransInvGL[i] = g_dAffinetransInv[i]; 451eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 452eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 453