/** * Updates the object model matrix and applies scaling. * * @param modelMatrix A 4x4 model-to-world transformation matrix, stored in column-major order. * @param scaleFactor A separate scaling factor to apply before the {@code modelMatrix}. * @see android.opengl.Matrix */ public void updateModelMatrix(float[] modelMatrix, float scaleFactor) { float[] scaleMatrix = new float[16]; Matrix.SetIdentityM(scaleMatrix, 0); scaleMatrix[0] = scaleFactor; scaleMatrix[5] = scaleFactor; scaleMatrix[10] = scaleFactor; Matrix.MultiplyMM(mModelMatrix, 0, modelMatrix, 0, scaleMatrix, 0); }
private void DrawLabel(float[] cameraViews, float[] cameraProjection) { ShaderUtil.CheckGlError(TAG, "Draw label start."); Matrix.MultiplyMM(modelViewMatrix, 0, cameraViews, 0, modelMatrix, 0); Matrix.MultiplyMM(modelViewProjectionMatrix, 0, cameraProjection, 0, modelViewMatrix, 0); float halfWidth = LABEL_WIDTH / 2.0f; float halfHeight = LABEL_HEIGHT / 2.0f; float[] vertices = { -halfWidth, -halfHeight, 1, -halfWidth, halfHeight, 1, halfWidth, halfHeight, 1, halfWidth, -halfHeight, 1, }; // The size of each floating point is 4 bits. FloatBuffer vetBuffer = ByteBuffer.AllocateDirect(4 * vertices.Length) .Order(ByteOrder.NativeOrder()).AsFloatBuffer(); vetBuffer.Rewind(); for (int i = 0; i < vertices.Length; ++i) { vetBuffer.Put(vertices[i]); } vetBuffer.Rewind(); // The size of each floating point is 4 bits. GLES20.GlVertexAttribPointer(glPositionParameter, COORDS_PER_VERTEX, GLES20.GlFloat, false, 4 * COORDS_PER_VERTEX, vetBuffer); // Set the sequence of OpenGL drawing points to generate two triangles that form a plane. short[] indices = { 0, 1, 2, 0, 2, 3 }; // Size of the allocated buffer. ShortBuffer idxBuffer = ByteBuffer.AllocateDirect(2 * indices.Length) .Order(ByteOrder.NativeOrder()).AsShortBuffer(); idxBuffer.Rewind(); for (int i = 0; i < indices.Length; ++i) { idxBuffer.Put(indices[i]); } idxBuffer.Rewind(); GLES20.GlUniformMatrix4fv(glModelViewProjectionMatrix, 1, false, modelViewProjectionMatrix, 0); GLES20.GlDrawElements(GLES20.GlTriangleStrip, idxBuffer.Limit(), GLES20.GlUnsignedShort, idxBuffer); ShaderUtil.CheckGlError(TAG, "Draw label end."); }
/// <summary> /// Draw a virtual object at a specific location on a specified plane. /// This method is called when WorldRenderManager's OnDrawFrame. /// </summary> /// <param name="cameraView">The viewMatrix is a 4 * 4 matrix.</param> /// <param name="cameraProjection">The ProjectionMatrix is a 4 * 4 matrix.</param> /// <param name="lightIntensity">The lighting intensity.</param> /// <param name="obj">The virtual object.</param> public void OnDrawFrame(float[] cameraView, float[] cameraProjection, float lightIntensity, VirtualObject obj) { ShaderUtil.CheckGlError(TAG, "onDrawFrame start."); mModelMatrixs = obj.GetModelAnchorMatrix(); Matrix.MultiplyMM(mModelViewMatrixs, 0, cameraView, 0, mModelMatrixs, 0); Matrix.MultiplyMM(mModelViewProjectionMatrixs, 0, cameraProjection, 0, mModelViewMatrixs, 0); GLES20.GlUseProgram(mGlProgram); Matrix.MultiplyMV(mViewLightDirections, 0, mModelViewMatrixs, 0, LIGHT_DIRECTIONS, 0); MatrixUtil.NormalizeVec3(mViewLightDirections); // Light direction. GLES20.GlUniform4f(mLightingParametersUniform, mViewLightDirections[0], mViewLightDirections[1], mViewLightDirections[2], lightIntensity); float[] objColors = obj.GetColor(); GLES20.GlUniform4fv(mColorUniform, 1, objColors, 0); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlUniform1i(mTextureUniform, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); // The coordinate dimension of the read virtual object is 3. GLES20.GlVertexAttribPointer( mPositionAttribute, 3, GLES20.GlFloat, false, 0, 0); // The dimension of the normal vector is 3. GLES20.GlVertexAttribPointer( mNormalAttribute, 3, GLES20.GlFloat, false, 0, mNormalsBaseAddress); // The dimension of the texture coordinate is 2. GLES20.GlVertexAttribPointer( mTexCoordAttribute, 2, GLES20.GlFloat, false, 0, mTexCoordsBaseAddress); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); GLES20.GlUniformMatrix4fv( mModelViewUniform, 1, false, mModelViewMatrixs, 0); GLES20.GlUniformMatrix4fv( mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrixs, 0); GLES20.GlEnableVertexAttribArray(mPositionAttribute); GLES20.GlEnableVertexAttribArray(mNormalAttribute); GLES20.GlEnableVertexAttribArray(mTexCoordAttribute); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); GLES20.GlDrawElements(GLES20.GlTriangles, mIndexCount, GLES20.GlUnsignedShort, 0); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); GLES20.GlDisableVertexAttribArray(mPositionAttribute); GLES20.GlDisableVertexAttribArray(mNormalAttribute); GLES20.GlDisableVertexAttribArray(mTexCoordAttribute); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); ShaderUtil.CheckGlError(TAG, "onDrawFrame end."); }
void Draw(float[] cameraView, float[] cameraPerspective) { // Build the ModelView and ModelViewProjection matrices // for calculating cube position and light. Matrix.MultiplyMM(mModelViewMatrix, 0, cameraView, 0, mModelMatrix, 0); Matrix.MultiplyMM(mModelViewProjectionMatrix, 0, cameraPerspective, 0, mModelViewMatrix, 0); // Set the position of the plane mVertexBuffer.Rewind(); GLES20.GlVertexAttribPointer( mPlaneXZPositionAlphaAttribute, COORDS_PER_VERTEX, GLES20.GlFloat, false, BYTES_PER_FLOAT * COORDS_PER_VERTEX, mVertexBuffer); // Set the Model and ModelViewProjection matrices in the shader. GLES20.GlUniformMatrix4fv(mPlaneModelUniform, 1, false, mModelMatrix, 0); GLES20.GlUniformMatrix4fv( mPlaneModelViewProjectionUniform, 1, false, mModelViewProjectionMatrix, 0); mIndexBuffer.Rewind(); GLES20.GlDrawElements(GLES20.GlTriangleStrip, mIndexBuffer.Limit(), GLES20.GlUnsignedShort, mIndexBuffer); ShaderUtil.CheckGLError(TAG, "Drawing plane"); }
/** * Draws the model. * * @param cameraView A 4x4 view matrix, in column-major order. * @param cameraPerspective A 4x4 projection matrix, in column-major order. * @param lightIntensity Illumination intensity. Combined with diffuse and specular material * properties. * @see #setBlendMode(BlendMode) * @see #updateModelMatrix(float[], float) * @see #setMaterialProperties(float, float, float, float) * @see android.opengl.Matrix */ public void Draw(float[] cameraView, float[] cameraPerspective, float lightIntensity) { ShaderUtil.CheckGLError(TAG, "Before draw"); // Build the ModelView and ModelViewProjection matrices // for calculating object position and light. Matrix.MultiplyMM(mModelViewMatrix, 0, cameraView, 0, mModelMatrix, 0); Matrix.MultiplyMM(mModelViewProjectionMatrix, 0, cameraPerspective, 0, mModelViewMatrix, 0); GLES20.GlUseProgram(mProgram); // Set the lighting environment properties. Matrix.MultiplyMV(mViewLightDirection, 0, mModelViewMatrix, 0, LIGHT_DIRECTION, 0); normalizeVec3(mViewLightDirection); GLES20.GlUniform4f(mLightingParametersUniform, mViewLightDirection[0], mViewLightDirection[1], mViewLightDirection[2], lightIntensity); // Set the object material properties. GLES20.GlUniform4f(mMaterialParametersUniform, mAmbient, mDiffuse, mSpecular, mSpecularPower); // Attach the object texture. GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlUniform1i(mTextureUniform, 0); // Set the vertex attributes. GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); GLES20.GlVertexAttribPointer( mPositionAttribute, COORDS_PER_VERTEX, GLES20.GlFloat, false, 0, mVerticesBaseAddress); GLES20.GlVertexAttribPointer( mNormalAttribute, 3, GLES20.GlFloat, false, 0, mNormalsBaseAddress); GLES20.GlVertexAttribPointer( mTexCoordAttribute, 2, GLES20.GlFloat, false, 0, mTexCoordsBaseAddress); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); // Set the ModelViewProjection matrix in the shader. GLES20.GlUniformMatrix4fv( mModelViewUniform, 1, false, mModelViewMatrix, 0); GLES20.GlUniformMatrix4fv( mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrix, 0); // Enable vertex arrays GLES20.GlEnableVertexAttribArray(mPositionAttribute); GLES20.GlEnableVertexAttribArray(mNormalAttribute); GLES20.GlEnableVertexAttribArray(mTexCoordAttribute); if (mBlendMode != BlendMode.Null) { GLES20.GlDepthMask(false); GLES20.GlEnable(GLES20.GlBlend); switch (mBlendMode) { case BlendMode.Shadow: // Multiplicative blending function for Shadow. GLES20.GlBlendFunc(GLES20.GlZero, GLES20.GlOneMinusSrcAlpha); break; case BlendMode.Grid: // Grid, additive blending function. GLES20.GlBlendFunc(GLES20.GlSrcAlpha, GLES20.GlOneMinusSrcAlpha); break; } } GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); GLES20.GlDrawElements(GLES20.GlTriangles, mIndexCount, GLES20.GlUnsignedShort, 0); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); if (mBlendMode != BlendMode.Null) { GLES20.GlDisable(GLES20.GlBlend); GLES20.GlDepthMask(true); } // Disable vertex arrays GLES20.GlDisableVertexAttribArray(mPositionAttribute); GLES20.GlDisableVertexAttribArray(mNormalAttribute); GLES20.GlDisableVertexAttribArray(mTexCoordAttribute); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); ShaderUtil.CheckGLError(TAG, "After draw"); }
/// <summary> /// Check whether the virtual object is clicked. /// </summary> /// <param name="cameraView">The viewMatrix 4 * 4.</param> /// <param name="cameraPerspective">The ProjectionMatrix 4 * 4.</param> /// <param name="obj">The virtual object data.</param> /// <param name="mEvent">The gesture event.</param> /// <returns>Return the click result for determining whether the input virtual object is clicked</returns> public bool HitTest(float[] cameraView, float[] cameraPerspective, VirtualObject obj, MotionEvent mEvent) { mModelMatrixs = obj.GetModelAnchorMatrix(); Matrix.MultiplyMM(mModelViewMatrixs, 0, cameraView, 0, mModelMatrixs, 0); Matrix.MultiplyMM(mModelViewProjectionMatrixs, 0, cameraPerspective, 0, mModelViewMatrixs, 0); // Calculate the coordinates of the smallest bounding box in the coordinate system of the device screen. float[] screenPos = CalculateScreenPos(mBoundingBoxs[0], mBoundingBoxs[1], mBoundingBoxs[2]); // Record the largest bounding rectangle of an object (minX/minY/maxX/maxY). float[] boundarys = new float[4]; boundarys[0] = screenPos[0]; boundarys[1] = screenPos[0]; boundarys[2] = screenPos[1]; boundarys[3] = screenPos[1]; // Determine whether a screen position corresponding to (maxX, maxY, maxZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 3, 4, 5 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (minX, minY, maxZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 0, 1, 5 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (minX, maxY, minZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 0, 4, 2 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (minX, maxY, maxZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 0, 4, 5 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (maxX, minY, minZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 3, 1, 2 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (maxX, minY, maxZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 3, 1, 5 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } // Determine whether a screen position corresponding to (maxX, maxY, maxZ) is clicked. boundarys = FindMaximum(boundarys, new int[] { 3, 4, 2 }); if (((mEvent.GetX() > boundarys[0]) && (mEvent.GetX() < boundarys[1])) && ((mEvent.GetY() > boundarys[2]) && (mEvent.GetY() < boundarys[3]))) { return(true); } return(false); }