void VirtualEnvironmentHandleARViewDrawPreCamera(void) { if (!VirtualEnvironment_AROSG) return; #ifdef USE_OPENGL_ES // Set some state to OSG's expected values. glStateCacheDisableLighting(); glStateCacheDisableTex2D(); glStateCacheDisableBlend(); glStateCacheEnableClientStateVertexArray(); glStateCacheEnableClientStateNormalArray(); glStateCacheEnableClientStateTexCoordArray(); #endif // Save the projection and modelview state. glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Draw the whole scenegraph. arOSGDraw(VirtualEnvironment_AROSG); // OSG modifies the viewport, so restore it. // Also restore projection and modelview. glViewport(viewPort[viewPortIndexLeft], viewPort[viewPortIndexBottom], viewPort[viewPortIndexWidth], viewPort[viewPortIndexHeight]); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); #ifdef USE_OPENGL_ES // Flush the state cache and ensure depth testing is enabled. glStateCacheFlush(); glStateCacheEnableDepthTest(); #else // Ensure depth testing is re-enabled. glEnable(GL_DEPTH_TEST); #endif }
JNIEXPORT void JNICALL JNIFUNCTION_NATIVE(nativeDrawFrame(JNIEnv* env, jobject obj, jint movieWidth, jint movieHeight, jint movieTextureID, jfloatArray movieTextureMtx)) { float width, height; // Get the array contents. //jsize movieTextureMtxLen = env->GetArrayLength(movieTextureMtx); float movieTextureMtxUnpacked[16]; env->GetFloatArrayRegion(movieTextureMtx, 0, /*movieTextureMtxLen*/ 16, movieTextureMtxUnpacked); if (!videoInited) { #ifdef DEBUG LOGI("nativeDrawFrame !VIDEO\n"); #endif return; // No point in trying to draw until video is inited. } if (!nftDataLoaded && nftDataLoadingThreadHandle) { // Check if NFT data loading has completed. if (threadGetStatus(nftDataLoadingThreadHandle) > 0) { nftDataLoaded = true; threadWaitQuit(nftDataLoadingThreadHandle); threadFree(&nftDataLoadingThreadHandle); // Clean up. } else { #ifdef DEBUG LOGI("nativeDrawFrame !NFTDATA\n"); #endif return; // No point in trying to draw until NFT data is loaded. } } #ifdef DEBUG LOGI("nativeDrawFrame\n"); #endif if (!gARViewInited) { if (!initARView()) return; } if (gARViewLayoutRequired) layoutARView(); // Upload new video frame if required. if (videoFrameNeedsPixelBufferDataUpload) { pthread_mutex_lock(&gVideoFrameLock); arglPixelBufferDataUploadBiPlanar(gArglSettings, gVideoFrame, gVideoFrame + videoWidth*videoHeight); videoFrameNeedsPixelBufferDataUpload = false; pthread_mutex_unlock(&gVideoFrameLock); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame. // Display the current frame arglDispImage(gArglSettings); // Set up 3D mode. glMatrixMode(GL_PROJECTION); glLoadMatrixf(cameraLens); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glStateCacheEnableDepthTest(); // Set any initial per-frame GL state you require here. // ---> // Lighting and geometry that moves with the camera should be added here. // (I.e. should be specified before camera pose transform.) // ---> // Draw an object on all valid markers. for (int i = 0; i < markersNFTCount; i++) { if (markersNFT[i].valid) { glLoadMatrixf(markersNFT[i].pose.T); // // Draw a rectangular surface textured with the movie texture. // float w = 80.0f; float h = w * (float)movieHeight/(float)movieWidth; GLfloat vertices[4][2] = { {0.0f, 0.0f}, {w, 0.0f}, {w, h}, {0.0f, h} }; GLfloat normals[4][3] = { {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f} }; GLfloat texcoords[4][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} }; glStateCacheActiveTexture(GL_TEXTURE0); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadMatrixf(movieTextureMtxUnpacked); glMatrixMode(GL_MODELVIEW); glVertexPointer(2, GL_FLOAT, 0, vertices); glNormalPointer(GL_FLOAT, 0, normals); glStateCacheClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, 0, texcoords); glStateCacheEnableClientStateVertexArray(); glStateCacheEnableClientStateNormalArray(); glStateCacheEnableClientStateTexCoordArray(); glStateCacheBindTexture2D(0); glStateCacheDisableTex2D(); glStateCacheDisableLighting(); glEnable(GL_TEXTURE_EXTERNAL_OES); glBindTexture(GL_TEXTURE_EXTERNAL_OES, movieTextureID); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); glDisable(GL_TEXTURE_EXTERNAL_OES); glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(GL_MODELVIEW); // // End. // } } if (cameraPoseValid) { glMultMatrixf(cameraPose); // All lighting and geometry to be drawn in world coordinates goes here. // ---> } // If you added external OpenGL code above, and that code doesn't use the glStateCache routines, // then uncomment the line below. //glStateCacheFlush(); // Set up 2D mode. glMatrixMode(GL_PROJECTION); glLoadIdentity(); width = (float)viewPort[viewPortIndexWidth]; height = (float)viewPort[viewPortIndexHeight]; glOrthof(0.0f, width, 0.0f, height, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glStateCacheDisableDepthTest(); // Add your own 2D overlays here. // ---> // If you added external OpenGL code above, and that code doesn't use the glStateCache routines, // then uncomment the line below. //glStateCacheFlush(); #ifdef DEBUG // Example of 2D drawing. It just draws a white border line. Change the 0 to 1 to enable. const GLfloat square_vertices [4][2] = { {0.5f, 0.5f}, {0.5f, height - 0.5f}, {width - 0.5f, height - 0.5f}, {width - 0.5f, 0.5f} }; glStateCacheDisableLighting(); glStateCacheDisableTex2D(); glVertexPointer(2, GL_FLOAT, 0, square_vertices); glStateCacheEnableClientStateVertexArray(); glColor4ub(255, 255, 255, 255); glDrawArrays(GL_LINE_LOOP, 0, 4); CHECK_GL_ERROR(); #endif }