summaryrefslogtreecommitdiffstats
path: root/jni
diff options
context:
space:
mode:
authorWei-Ta Chen <weita@google.com>2011-10-19 12:42:44 -0700
committerWei-Ta Chen <weita@google.com>2011-10-26 15:15:39 -0700
commitd32aa042a7d7fdb52cd8cec571e7c648f837eaff (patch)
treedc7149fceba6fe30ec1f52520ce8fb96461b1d18 /jni
parenta4bfc37a8d4567745bf2c5d9bbb3166fa0e7f302 (diff)
downloadLegacyCamera-d32aa042a7d7fdb52cd8cec571e7c648f837eaff.zip
LegacyCamera-d32aa042a7d7fdb52cd8cec571e7c648f837eaff.tar.gz
LegacyCamera-d32aa042a7d7fdb52cd8cec571e7c648f837eaff.tar.bz2
Make Panorama work in portrait layout.
Add the support of both portrait and landscape layout to the panorama library. Add a step into the preview renderer that rotates the content in the offscreen buffer by 90 degrees in the case of a portrait layout. Change-Id: I879e3476daac522b0c8b27fe3ef5b17ebf0797e3
Diffstat (limited to 'jni')
-rw-r--r--jni/mosaic_renderer_jni.cpp145
1 files changed, 111 insertions, 34 deletions
diff --git a/jni/mosaic_renderer_jni.cpp b/jni/mosaic_renderer_jni.cpp
index fbf6862..bb01e7f 100644
--- a/jni/mosaic_renderer_jni.cpp
+++ b/jni/mosaic_renderer_jni.cpp
@@ -118,6 +118,10 @@ double gLastTx = 0.0f;
double gUILayoutScalingX = 1.0f;
double gUILayoutScalingY = 1.0f;
+// Whether the view that we will render preview FBO onto is in landscape or portrait
+// orientation.
+bool gIsLandscapeOrientation = true;
+
// State of the viewfinder. Set to false when the viewfinder hits the UI edge.
bool gPanViewfinder = true;
@@ -137,12 +141,26 @@ GLfloat g_dTranslationToFBOCenterGL[16];
double g_dTranslationToFBOCenter[16];
// GL 4x4 Identity transformation
-GLfloat g_dAffinetransIdent[] = {
+GLfloat g_dAffinetransIdentGL[] = {
1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.};
+// GL 4x4 Rotation transformation (column-majored): 90 degree
+GLfloat g_dAffinetransRotation90GL[] = {
+ 0., 1., 0., 0.,
+ -1., 0., 0., 0.,
+ 0., 0., 1., 0.,
+ 0., 0., 0., 1.};
+
+// 3x3 Rotation transformation (row-majored): 90 degree
+double gRotation90[] = {
+ 0., -1., 0.,
+ 1., 0., 0.,
+ 0., 0., 1.,};
+
+
float g_dIdent3x3[] = {
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
@@ -219,6 +237,39 @@ void ConvertAffine3x3toGL4x4(double *matGL44, double *mat33)
matGL44[15] = mat33[8];
}
+bool continuePanningFBO(double panOffset) {
+ double normalizedScreenLimitLeft = -1.0 + VIEWPORT_BORDER_FACTOR_HORZ * 2.0;
+ double normalizedScreenLimitRight = 1.0 - VIEWPORT_BORDER_FACTOR_HORZ * 2.0;
+ double normalizedXPositionOnScreenLeft;
+ double normalizedXPositionOnScreenRight;
+
+ // Compute the position of the current frame in the screen coordinate system
+ if (gIsLandscapeOrientation) {
+ normalizedXPositionOnScreenLeft = (2.0 *
+ (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) *
+ gUILayoutScalingX;
+ normalizedXPositionOnScreenRight = (2.0 *
+ ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) /
+ gPreviewFBOWidth - 1.0) * gUILayoutScalingX;
+ } else {
+ normalizedXPositionOnScreenLeft = (2.0 *
+ (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) *
+ gUILayoutScalingY;
+ normalizedXPositionOnScreenRight = (2.0 *
+ ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) /
+ gPreviewFBOWidth - 1.0) * gUILayoutScalingY;
+ }
+
+ // Stop the viewfinder panning if we hit the maximum border allowed for
+ // this UI layout
+ if (normalizedXPositionOnScreenRight > normalizedScreenLimitRight ||
+ normalizedXPositionOnScreenLeft < normalizedScreenLimitLeft) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
// This function computes fills the 4x4 matrices g_dAffinetrans,
// and g_dAffinetransPan using the specified 3x3 affine
// transformation between the first captured frame and the current frame.
@@ -289,23 +340,7 @@ void UpdateWarpTransformation(float *trs)
}
gLastTx = gThisTx;
-
- // Compute the position of the current frame in the screen coordinate system
- // and stop the viewfinder panning if we hit the maximum border allowed for
- // this UI layout
- double normalizedXPositionOnScreenLeft = (2.0 *
- (gCenterOffsetX + gPanOffset) / gPreviewFBOWidth - 1.0) *
- gUILayoutScalingX;
- double normalizedScreenLimitLeft = -1.0 + VIEWPORT_BORDER_FACTOR_HORZ * 2.0;
-
- double normalizedXPositionOnScreenRight = (2.0 *
- ((gCenterOffsetX + gPanOffset) + gPreviewImageWidth[HR]) /
- gPreviewFBOWidth - 1.0) * gUILayoutScalingX;
- double normalizedScreenLimitRight = 1.0 - VIEWPORT_BORDER_FACTOR_HORZ * 2.0;
-
- if(normalizedXPositionOnScreenRight > normalizedScreenLimitRight ||
- normalizedXPositionOnScreenLeft < normalizedScreenLimitLeft)
- gPanViewfinder = false;
+ gPanViewfinder = continuePanningFBO(gPanOffset);
db_Identity3x3(H);
H[2] = gPanOffset;
@@ -315,7 +350,13 @@ void UpdateWarpTransformation(float *trs)
db_Multiply3x3_3x3(Htemp1, H, gKm);
db_Multiply3x3_3x3(Hp, gKminv, Htemp1);
- ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp);
+ if (gIsLandscapeOrientation) {
+ ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp);
+ } else {
+ // rotate Hp by 90 degress.
+ db_Multiply3x3_3x3(Htemp1, gRotation90, Hp);
+ ConvertAffine3x3toGL4x4(g_dAffinetransPan, Htemp1);
+ }
}
void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR)
@@ -421,7 +462,8 @@ extern "C"
JNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init(
JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset(
- JNIEnv * env, jobject obj, jint width, jint height);
+ JNIEnv * env, jobject obj, jint width, jint height,
+ jboolean isLandscapeOrientation);
JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preprocess(
JNIEnv * env, jobject obj, jfloatArray stMatrix);
JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferGPUtoCPU(
@@ -461,19 +503,48 @@ JNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init(
}
+void calculateUILayoutScaling(int width, int height, bool isLandscape) {
+ if (isLandscape) {
+ // __________ ______
+ // |__________| => |______|
+ // (Preview FBO) (View)
+ //
+ // Scale the preview FBO's height to the height of view and
+ // maintain the aspect ratio of the current frame on the screen.
+ gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE;
+
+ // Note that OpenGL scales a texture to view's width and height automatically.
+ // The "width / height" inverts the scaling, so as to maintain the aspect ratio
+ // of the current frame.
+ gUILayoutScalingX = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR])
+ / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE)
+ / ((float) width / height);
+ } else {
+ // __
+ // __________ | |
+ // |__________| => | |
+ // (Preview FBO) | |
+ // |__|
+ // (View)
+ // Scale the preview FBO's height to the width of view and
+ // maintain the aspect ratio of the current frame on the screen.
+ gUILayoutScalingX = PREVIEW_FBO_HEIGHT_SCALE;
+
+ // Note that OpenGL scales a texture to view's width and height automatically.
+ // The "height / width" inverts the scaling, so as to maintain the aspect ratio
+ // of the current frame.
+ gUILayoutScalingY = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR])
+ / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE)
+ / ((float) height / width);
+
+ }
+}
+
JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset(
- JNIEnv * env, jobject obj, jint width, jint height)
+ JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation)
{
- // Scale the current frame's height to the height of view and
- // maintain the aspect ratio of the current frame on the screen.
- gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE;
-
- // Note that OpenGL scales a texture to view's width and height automatically.
- // The "width / height" inverts the scaling, so as to maintain the aspect ratio
- // of the current frame.
- gUILayoutScalingX = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR])
- / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE)
- / ((float) width / height);
+ gIsLandscapeOrientation = isLandscapeOrientation;
+ calculateUILayoutScaling(width, height, gIsLandscapeOrientation);
gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA);
gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA);
@@ -543,6 +614,7 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset(
gPreview.SetupGraphics(width, height);
gPreview.Clear(0.0, 0.0, 0.0, 1.0);
gPreview.SetViewportMatrix(1, 1, 1, 1);
+
// Scale the previewFBO so that the viewfinder window fills the layout height
// while maintaining the image aspect ratio
gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY);
@@ -560,8 +632,8 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preproces
env->ReleaseFloatArrayElements(stMatrix, stmat, 0);
- gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdent);
- gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdent);
+ gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdentGL);
+ gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdentGL);
}
#ifndef now_ms
@@ -626,7 +698,12 @@ JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step(
gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName());
gWarper2.DrawTexture(g_dTranslationToFBOCenterGL);
- gPreview.DrawTexture(g_dAffinetransIdent);
+
+ if (gIsLandscapeOrientation) {
+ gPreview.DrawTexture(g_dAffinetransIdentGL);
+ } else {
+ gPreview.DrawTexture(g_dAffinetransRotation90GL);
+ }
}
else
{