void initGL(int screenWidth, int screenHeight) { frameGL.init(screenWidth, screenHeight); Renderer renderer = Renderer.getInstance(); VideoBackgroundConfig vc = renderer.getVideoBackgroundConfig(); int temp[] = vc.getSize().getData(); float[] videoBackgroundConfigSize = new float[2]; videoBackgroundConfigSize[0] = temp[0] * 0.5f; videoBackgroundConfigSize[1] = temp[1] * 0.5f; halfScreenSize.setData(videoBackgroundConfigSize); // sets last frame timer lastFrameTime = System.currentTimeMillis(); reset(); }
// Function for initializing the renderer. private void initRendering() { mTeapot = new Teapot(); mTextPlane = new TextPlane(); mRenderer = Renderer.getInstance(); GLES20.glClearColor(0.0f, 0.0f, 0.0f, Vuforia.requiresAlpha() ? 0.0f : 1.0f); for (Texture t : mTextures) { GLES20.glGenTextures(1, t.mTextureID, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, t.mTextureID[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, t.mWidth, t.mHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, t.mData); } shaderProgramID = SampleUtils.createProgramFromShaderSrc( CubeShaders.CUBE_MESH_VERTEX_SHADER, CubeShaders.CUBE_MESH_FRAGMENT_SHADER); vertexHandle = GLES20.glGetAttribLocation(shaderProgramID, "vertexPosition"); normalHandle = GLES20.glGetAttribLocation(shaderProgramID, "vertexNormal"); textureCoordHandle = GLES20.glGetAttribLocation(shaderProgramID, "vertexTexCoord"); mvpMatrixHandle = GLES20.glGetUniformLocation(shaderProgramID, "modelViewProjectionMatrix"); texSampler2DHandle = GLES20.glGetUniformLocation(shaderProgramID, "texSampler2D"); try { mBuildingsModel = new SampleApplication3DModel(); mBuildingsModel.loadModel(mActivity.getResources().getAssets(), "ImageTargets/Buildings.txt"); } catch (IOException e) { Log.e(LOGTAG, "Unable to load buildings"); } // Hide the Loading Dialog mActivity.loadingDialogHandler.sendEmptyMessage(LoadingDialogHandler.HIDE_LOADING_DIALOG); }
// The render function. private void renderFrame() { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); State state = mRenderer.begin(); mRenderer.drawVideoBackground(); GLES20.glEnable(GLES20.GL_DEPTH_TEST); // handle face culling, we need to detect if we are using reflection // to determine the direction of the culling GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glCullFace(GLES20.GL_BACK); if (Renderer.getInstance().getVideoBackgroundConfig().getReflection() == VIDEO_BACKGROUND_REFLECTION.VIDEO_BACKGROUND_REFLECTION_ON) GLES20.glFrontFace(GLES20.GL_CW); // Front camera else GLES20.glFrontFace(GLES20.GL_CCW); // Back camera // did we find any trackables this frame? for (int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++) { TrackableResult result = state.getTrackableResult(tIdx); Trackable trackable = result.getTrackable(); printUserData(trackable); Matrix44F modelViewMatrix_Vuforia = Tool.convertPose2GLMatrix(result.getPose()); float[] modelViewMatrix = modelViewMatrix_Vuforia.getData(); int textureIndex = trackable.getName().equalsIgnoreCase("cat") ? 0 : 1; textureIndex = trackable.getName().equals("city") ? 1 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("tree") ? 2 : textureIndex; // Part B Calendar calendar = Calendar.getInstance(); int day = calendar.get(Calendar.DAY_OF_WEEK); if (day != Calendar.SATURDAY && day != Calendar.SUNDAY) { textureIndex = trackable.getName().equalsIgnoreCase("b11_013") ? ImageTargets.orderImages.indexOf("b11_013") + 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("b11_014") ? ImageTargets.orderImages.indexOf("b11_014") + 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("b11_015") ? ImageTargets.orderImages.indexOf("b11_015") + 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("berkaer_003") ? ImageTargets.orderImages.indexOf("berkaer_003") + 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("p_013") ? ImageTargets.orderImages.indexOf("p_013") + 3 : textureIndex; } else { textureIndex = trackable.getName().equalsIgnoreCase("b11_013") ? 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("b11_014") ? 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("b11_015") ? 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("berkaer_003") ? 3 : textureIndex; textureIndex = trackable.getName().equalsIgnoreCase("p_013") ? 3 : textureIndex; } // deal with the modelview and projection matrices float[] modelViewProjection = new float[16]; boolean partA = trackable.getName().equalsIgnoreCase("cat") || trackable.getName().equalsIgnoreCase("city") || trackable.getName().equalsIgnoreCase("tree"); if (!mActivity.isExtendedTrackingActive()) { if (partA) { Matrix.translateM(modelViewMatrix, 0, 0.0f, 0.0f, OBJECT_SCALE_FLOAT); Matrix.scaleM( modelViewMatrix, 0, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT); } else { Matrix.translateM( modelViewMatrix, 0, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT); Matrix.scaleM( modelViewMatrix, 0, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT, OBJECT_SCALE_FLOAT); } } else { Matrix.rotateM(modelViewMatrix, 0, 90.0f, 1.0f, 0, 0); Matrix.scaleM(modelViewMatrix, 0, kBuildingScale, kBuildingScale, kBuildingScale); } Matrix.multiplyMM( modelViewProjection, 0, vuforiaAppSession.getProjectionMatrix().getData(), 0, modelViewMatrix, 0); // activate the shader program and bind the vertex/normal/tex coords GLES20.glUseProgram(shaderProgramID); if (!mActivity.isExtendedTrackingActive()) { if (partA) { GLES20.glVertexAttribPointer( vertexHandle, 3, GLES20.GL_FLOAT, false, 0, mTeapot.getVertices()); GLES20.glVertexAttribPointer( normalHandle, 3, GLES20.GL_FLOAT, false, 0, mTeapot.getNormals()); GLES20.glVertexAttribPointer( textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTeapot.getTexCoords()); } else { Log.d("Object", "Name:" + trackable.getName()); // To replace the Teapot for a plane Image GLES20.glVertexAttribPointer( vertexHandle, 3, GLES20.GL_FLOAT, false, 0, mTextPlane.getVertices()); GLES20.glVertexAttribPointer( normalHandle, 3, GLES20.GL_FLOAT, false, 0, mTextPlane.getNormals()); GLES20.glVertexAttribPointer( textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTextPlane.getTexCoords()); } GLES20.glEnableVertexAttribArray(vertexHandle); GLES20.glEnableVertexAttribArray(normalHandle); GLES20.glEnableVertexAttribArray(textureCoordHandle); // activate texture 0, bind it, and pass to shader GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures.get(textureIndex).mTextureID[0]); GLES20.glUniform1i(texSampler2DHandle, 0); // pass the model view matrix to the shader GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0); if (partA) { // Finally draw the teapot GLES20.glDrawElements( GLES20.GL_TRIANGLES, mTeapot.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT, mTeapot.getIndices()); } else { // Draw the plane text GLES20.glDrawElements( GLES20.GL_TRIANGLES, mTextPlane.getNumObjectIndex(), GLES20.GL_UNSIGNED_SHORT, mTextPlane.getIndices()); } // disable the enabled arrays GLES20.glDisableVertexAttribArray(vertexHandle); GLES20.glDisableVertexAttribArray(normalHandle); GLES20.glDisableVertexAttribArray(textureCoordHandle); } else { GLES20.glDisable(GLES20.GL_CULL_FACE); GLES20.glVertexAttribPointer( vertexHandle, 3, GLES20.GL_FLOAT, false, 0, mBuildingsModel.getVertices()); GLES20.glVertexAttribPointer( normalHandle, 3, GLES20.GL_FLOAT, false, 0, mBuildingsModel.getNormals()); GLES20.glVertexAttribPointer( textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mBuildingsModel.getTexCoords()); GLES20.glEnableVertexAttribArray(vertexHandle); GLES20.glEnableVertexAttribArray(normalHandle); GLES20.glEnableVertexAttribArray(textureCoordHandle); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures.get(3).mTextureID[0]); GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0); GLES20.glUniform1i(texSampler2DHandle, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mBuildingsModel.getNumObjectVertex()); SampleUtils.checkGLError("Renderer DrawBuildings"); } SampleUtils.checkGLError("Render Frame"); } GLES20.glDisable(GLES20.GL_DEPTH_TEST); mRenderer.end(); }
public BackgroundMesh( int vbNumVertexRows, int vbNumVertexCols, boolean isActivityInPortraitMode) { if (vbNumVertexRows < 2 || vbNumVertexCols < 2) { throw new IllegalArgumentException("vbNumVertexRows and vbNumVertexCols must be at least 2"); } mNumVertexRows = vbNumVertexRows; mNumVertexCols = vbNumVertexCols; // Get the texture and image dimensions from Vuforia VideoBackgroundTextureInfo texInfo = Renderer.getInstance().getVideoBackgroundTextureInfo(); // Detect if the renderer is reporting reflected pose info, possibly due // to useage of the front camera. // If so, we need to reflect the image of the video background to match // the pose. int reflection = Renderer.getInstance().getVideoBackgroundConfig().getReflection(); float reflectionOffset = (float) vbNumVertexCols - 1.0f; Log.e(LOGTAG, "Activity is in " + (isActivityInPortraitMode ? "Portrait" : "Landscape")); // If there is no image data yet then return; if ((texInfo.getImageSize().getData()[0] == 0) || (texInfo.getImageSize().getData()[1] == 0)) { Log.e( LOGTAG, "Invalid Image Size!! " + texInfo.getImageSize().getData()[0] + " x " + texInfo.getImageSize().getData()[1]); return; } // These calculate a slope for the texture coords float uRatio = ((float) texInfo.getImageSize().getData()[0] / (float) texInfo.getTextureSize().getData()[0]); float vRatio = ((float) texInfo.getImageSize().getData()[1] / (float) texInfo.getTextureSize().getData()[1]); float uSlope = uRatio / ((float) vbNumVertexCols - 1.0f); float vSlope = vRatio / ((float) vbNumVertexRows - 1.0f); // These calculate a slope for the vertex values in this case we have a // span of 2, from -1 to 1 float totalSpan = 2.0f; float colSlope = totalSpan / ((float) vbNumVertexCols - 1.0f); float rowSlope = totalSpan / ((float) vbNumVertexRows - 1.0f); // Some helper variables short currentVertexIndex = 0; mOrthoQuadVertices = ByteBuffer.allocateDirect(vbNumVertexRows * vbNumVertexCols * 3 * SIZE_OF_FLOAT) .order(ByteOrder.nativeOrder()); mOrthoQuadTexCoords = ByteBuffer.allocateDirect(vbNumVertexRows * vbNumVertexCols * 2 * SIZE_OF_FLOAT) .order(ByteOrder.nativeOrder()); mOrthoQuadIndices = ByteBuffer.allocateDirect(getNumObjectIndex()).order(ByteOrder.nativeOrder()); for (int j = 0; j < vbNumVertexRows; j++) { for (int i = 0; i < vbNumVertexCols; i++) { // We populate the mesh with a regular grid mOrthoQuadVertices.putFloat(((colSlope * i) - (totalSpan / 2.0f))); // We subtract this because the values range from -totalSpan/2 to totalSpan/2 mOrthoQuadVertices.putFloat(((rowSlope * j) - (totalSpan / 2.0f))); // It is all a flat polygon orthogonal to the view vector mOrthoQuadVertices.putFloat(0.0f); float u = 0.0f, v = 0.0f; // We also populate its associated texture coordinate if (isActivityInPortraitMode) { u = uRatio - (uSlope * j); v = vRatio - ((reflection == VIDEO_BACKGROUND_REFLECTION.VIDEO_BACKGROUND_REFLECTION_ON) ? vSlope * (reflectionOffset - i) : vSlope * i); } else /* Landscape */ { u = ((reflection == VIDEO_BACKGROUND_REFLECTION.VIDEO_BACKGROUND_REFLECTION_ON) ? uSlope * (reflectionOffset - i) : uSlope * i); v = vRatio - (vSlope * j); } mOrthoQuadTexCoords.putFloat(u); mOrthoQuadTexCoords.putFloat(v); // Log.d(LOGTAG, "Vert (Text): " + // ((colSlope*i)-(totalSpan/2.0f)) + "," + // ((rowSlope*j)-(totalSpan/2.0f)) + " (" + u + "," + v +")"); // Now we populate the triangles that compose the mesh // First triangle is the upper right of the vertex if (j < vbNumVertexRows - 1) { // In the example above this would make triangles ABD and BCE if (i < vbNumVertexCols - 1) { mOrthoQuadIndices.put((byte) currentVertexIndex); mOrthoQuadIndices.put((byte) (currentVertexIndex + 1)); mOrthoQuadIndices.put((byte) (currentVertexIndex + vbNumVertexCols)); } // In the example above this would make triangles BED and CFE if (i > 0) { mOrthoQuadIndices.put((byte) currentVertexIndex); mOrthoQuadIndices.put((byte) (currentVertexIndex + vbNumVertexCols)); mOrthoQuadIndices.put((byte) (currentVertexIndex + vbNumVertexCols - 1)); } } currentVertexIndex += 1; // Vertex index increased by one } } mOrthoQuadVertices.rewind(); mOrthoQuadTexCoords.rewind(); mOrthoQuadIndices.rewind(); }