/** * Reads pixels using dual buffers. This function sends the reading request to GPU and returns the * result from the previous call. Thus, the first call always returns null. The pixelBuffer member * in the returned object maps to the internal buffer. This buffer cannot be overrode, and it * becomes invalid after next call to submitAndAcquire(). * * @param textureId the OpenGL texture Id. * @param textureWidth width of the texture in pixels. * @param textureHeight height of the texture in pixels. * @return a TextureReaderImage object that contains the pixels read from the texture. */ public TextureReaderImage submitAndAcquire(int textureId, int textureWidth, int textureHeight) { // Release previously used front buffer. if (frontIndex != -1) { releaseFrame(frontIndex); } // Move previous back buffer to front buffer. frontIndex = backIndex; // Submit new request on back buffer. backIndex = submitFrame(textureId, textureWidth, textureHeight); // Acquire frame from the new front buffer. if (frontIndex != -1) { return acquireFrame(frontIndex); } return null; }
/** * Acquires the frame requested earlier. This routine returns a TextureReaderImage object that * contains the pixels mapped to the frame buffer requested previously through submitFrame(). * * <p>If input buffer index is invalid, an exception will be thrown. * * @param bufferIndex the index to the frame buffer to be acquired. It has to be a frame index * returned from submitFrame(). * @return a TextureReaderImage object if succeed. Null otherwise. */ public TextureReaderImage acquireFrame(int bufferIndex) { if (bufferIndex < 0 || bufferIndex >= bufferCount || !bufferUsed[bufferIndex]) { throw new RuntimeException("Invalid buffer index."); } // Bind the current PB and acquire the pixel buffer. GLES30.glBindBuffer(GLES30.GL_PIXEL_PACK_BUFFER, pbo[bufferIndex]); ByteBuffer mapped = (ByteBuffer) GLES30.glMapBufferRange( GLES30.GL_PIXEL_PACK_BUFFER, 0, pixelBufferSize, GLES30.GL_MAP_READ_BIT); // Wrap the mapped buffer into TextureReaderImage object. TextureReaderImage buffer = new TextureReaderImage(imageWidth, imageHeight, imageFormat, mapped); return buffer; }
ShaderUtil.checkGLError(TAG, "before create"); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "buffer alloc"); ShaderUtil.loadGLShader(TAG, context, GLES20.GL_VERTEX_SHADER, VERTEX_SHADER_NAME); int passthroughShader = ShaderUtil.loadGLShader(TAG, context, GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_NAME); GLES20.glUseProgram(programName); ShaderUtil.checkGLError(TAG, "program"); pointSizeUniform = GLES20.glGetUniformLocation(programName, "u_PointSize"); ShaderUtil.checkGLError(TAG, "program params");
continue; sortedPlanes.add(new SortablePlane(distance, plane)); ShaderUtil.checkGLError(TAG, "Setting up to draw planes"); plane.getCenterPose().toMatrix(planeMatrix, 0); updatePlaneParameters( planeMatrix, plane.getExtentX(), plane.getExtentZ(), plane.getPolygon()); colorRgbaToFloat(planeColor, PLANE_COLORS_RGBA[colorIndex]); GLES20.glUniform4fv(lineColorUniform, 1, planeColor, 0); GLES20.glUniform4fv(dotColorUniform, 1, planeColor, 0); GLES20.glUniformMatrix2fv(planeUvMatrixUniform, 1, false, planeAngleUvMatrix, 0); draw(cameraView, cameraPerspective); GLES20.glDepthMask(true); ShaderUtil.checkGLError(TAG, "Cleaning up after drawing planes");
/** * Updates the OpenGL buffer contents to the provided point. Repeated calls with the same point * cloud will be ignored. */ public void update(PointCloud cloud) { if (lastPointCloud == cloud) { // Redundant call. return; } ShaderUtil.checkGLError(TAG, "before update"); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); lastPointCloud = cloud; // If the VBO is not large enough to fit the new point cloud, resize it. numPoints = lastPointCloud.getPoints().remaining() / FLOATS_PER_POINT; if (numPoints * BYTES_PER_POINT > vboSize) { while (numPoints * BYTES_PER_POINT > vboSize) { vboSize *= 2; } GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vboSize, null, GLES20.GL_DYNAMIC_DRAW); } GLES20.glBufferSubData( GLES20.GL_ARRAY_BUFFER, 0, numPoints * BYTES_PER_POINT, lastPointCloud.getPoints()); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "after update"); }
ShaderUtil.checkGLError(TAG, "Before draw"); normalizeVec3(viewLightDirection); GLES20.glUniform4f( lightingParametersUniform, ShaderUtil.checkGLError(TAG, "After draw");
/** * Converts a raw text file, saved as a resource, into an OpenGL ES shader. * * @param type The type of shader we will be creating. * @param filename The filename of the asset file about to be turned into a shader. * @return The shader object handler. */ public static int loadGLShader(String tag, Context context, int type, String filename) throws IOException { String code = readRawTextFileFromAssets(context, filename); int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, code); GLES20.glCompileShader(shader); // Get the compilation status. final int[] compileStatus = new int[1]; GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); // If the compilation failed, delete the shader. if (compileStatus[0] == 0) { Log.e(tag, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } if (shader == 0) { throw new RuntimeException("Error creating shader."); } return shader; }
drawTexture(textureId, textureWidth, textureHeight);
continue; sortedPlanes.add(new SortablePlane(distance, plane)); ShaderUtil.checkGLError(TAG, "Setting up to draw planes"); plane.getCenterPose().toMatrix(planeMatrix, 0); updatePlaneParameters( planeMatrix, plane.getExtentX(), plane.getExtentZ(), plane.getPolygon()); colorRgbaToFloat(planeColor, PLANE_COLORS_RGBA[colorIndex]); GLES20.glUniform4fv(lineColorUniform, 1, planeColor, 0); GLES20.glUniform4fv(dotColorUniform, 1, planeColor, 0); GLES20.glUniformMatrix2fv(planeUvMatrixUniform, 1, false, planeAngleUvMatrix, 0); draw(cameraView, cameraPerspective); GLES20.glDepthMask(true); ShaderUtil.checkGLError(TAG, "Cleaning up after drawing planes");
ShaderUtil.checkGLError(TAG, "before create"); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "buffer alloc"); ShaderUtil.loadGLShader(TAG, context, GLES20.GL_VERTEX_SHADER, VERTEX_SHADER_NAME); int passthroughShader = ShaderUtil.loadGLShader(TAG, context, GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_NAME); GLES20.glUseProgram(programName); ShaderUtil.checkGLError(TAG, "program"); pointSizeUniform = GLES20.glGetUniformLocation(programName, "u_PointSize"); ShaderUtil.checkGLError(TAG, "program params");
/** * Updates the OpenGL buffer contents to the provided point. Repeated calls with the same point * cloud will be ignored. */ public void update(PointCloud cloud) { if (lastPointCloud == cloud) { // Redundant call. return; } ShaderUtil.checkGLError(TAG, "before update"); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); lastPointCloud = cloud; // If the VBO is not large enough to fit the new point cloud, resize it. numPoints = lastPointCloud.getPoints().remaining() / FLOATS_PER_POINT; if (numPoints * BYTES_PER_POINT > vboSize) { while (numPoints * BYTES_PER_POINT > vboSize) { vboSize *= 2; } GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vboSize, null, GLES20.GL_DYNAMIC_DRAW); } GLES20.glBufferSubData( GLES20.GL_ARRAY_BUFFER, 0, numPoints * BYTES_PER_POINT, lastPointCloud.getPoints()); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "after update"); }
ShaderUtil.checkGLError(TAG, "Before draw"); normalizeVec3(viewLightDirection); GLES20.glUniform4f( lightingParametersUniform, ShaderUtil.checkGLError(TAG, "After draw");
/** * Converts a raw text file, saved as a resource, into an OpenGL ES shader. * * @param type The type of shader we will be creating. * @param filename The filename of the asset file about to be turned into a shader. * @return The shader object handler. */ public static int loadGLShader(String tag, Context context, int type, String filename) throws IOException { String code = readRawTextFileFromAssets(context, filename); int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, code); GLES20.glCompileShader(shader); // Get the compilation status. final int[] compileStatus = new int[1]; GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0); // If the compilation failed, delete the shader. if (compileStatus[0] == 0) { Log.e(tag, "Error compiling shader: " + GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } if (shader == 0) { throw new RuntimeException("Error creating shader."); } return shader; }
ShaderUtil.loadGLShader(TAG, context, GLES20.GL_VERTEX_SHADER, VERTEX_SHADER_NAME); int passthroughShader = ShaderUtil.loadGLShader(TAG, context, GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER_NAME); GLES20.glUseProgram(planeProgram); ShaderUtil.checkGLError(TAG, "Program creation"); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); ShaderUtil.checkGLError(TAG, "Texture loading"); planeUvMatrixUniform = GLES20.glGetUniformLocation(planeProgram, "u_PlaneUvMatrix"); ShaderUtil.checkGLError(TAG, "Program parameters");
/** * Renders the point cloud. ArCore point cloud is given in world space. * * @param cameraView the camera view matrix for this frame, typically from {@link * com.google.ar.core.Camera#getViewMatrix(float[], int)}. * @param cameraPerspective the camera projection matrix for this frame, typically from {@link * com.google.ar.core.Camera#getProjectionMatrix(float[], int, float, float)}. */ public void draw(float[] cameraView, float[] cameraPerspective) { float[] modelViewProjection = new float[16]; Matrix.multiplyMM(modelViewProjection, 0, cameraPerspective, 0, cameraView, 0); ShaderUtil.checkGLError(TAG, "Before draw"); GLES20.glUseProgram(programName); GLES20.glEnableVertexAttribArray(positionAttribute); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); GLES20.glVertexAttribPointer(positionAttribute, 4, GLES20.GL_FLOAT, false, BYTES_PER_POINT, 0); GLES20.glUniform4f(colorUniform, 31.0f / 255.0f, 188.0f / 255.0f, 210.0f / 255.0f, 1.0f); GLES20.glUniformMatrix4fv(modelViewProjectionUniform, 1, false, modelViewProjection, 0); GLES20.glUniform1f(pointSizeUniform, 5.0f); GLES20.glDrawArrays(GLES20.GL_POINTS, 0, numPoints); GLES20.glDisableVertexAttribArray(positionAttribute); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "Draw"); } }
/** * Renders the point cloud. ArCore point cloud is given in world space. * * @param cameraView the camera view matrix for this frame, typically from {@link * com.google.ar.core.Camera#getViewMatrix(float[], int)}. * @param cameraPerspective the camera projection matrix for this frame, typically from {@link * com.google.ar.core.Camera#getProjectionMatrix(float[], int, float, float)}. */ public void draw(float[] cameraView, float[] cameraPerspective) { float[] modelViewProjection = new float[16]; Matrix.multiplyMM(modelViewProjection, 0, cameraPerspective, 0, cameraView, 0); ShaderUtil.checkGLError(TAG, "Before draw"); GLES20.glUseProgram(programName); GLES20.glEnableVertexAttribArray(positionAttribute); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo); GLES20.glVertexAttribPointer(positionAttribute, 4, GLES20.GL_FLOAT, false, BYTES_PER_POINT, 0); GLES20.glUniform4f(colorUniform, 31.0f / 255.0f, 188.0f / 255.0f, 210.0f / 255.0f, 1.0f); GLES20.glUniformMatrix4fv(modelViewProjectionUniform, 1, false, modelViewProjection, 0); GLES20.glUniform1f(pointSizeUniform, 5.0f); GLES20.glDrawArrays(GLES20.GL_POINTS, 0, numPoints); GLES20.glDisableVertexAttribArray(positionAttribute); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); ShaderUtil.checkGLError(TAG, "Draw"); } }
private void draw(float[] cameraView, float[] cameraPerspective) { // Build the ModelView and ModelViewProjection matrices // for calculating cube position and light. Matrix.multiplyMM(modelViewMatrix, 0, cameraView, 0, modelMatrix, 0); Matrix.multiplyMM(modelViewProjectionMatrix, 0, cameraPerspective, 0, modelViewMatrix, 0); // Set the position of the plane vertexBuffer.rewind(); GLES20.glVertexAttribPointer( planeXZPositionAlphaAttribute, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, BYTES_PER_FLOAT * COORDS_PER_VERTEX, vertexBuffer); // Set the Model and ModelViewProjection matrices in the shader. GLES20.glUniformMatrix4fv(planeModelUniform, 1, false, modelMatrix, 0); GLES20.glUniformMatrix4fv( planeModelViewProjectionUniform, 1, false, modelViewProjectionMatrix, 0); indexBuffer.rewind(); GLES20.glDrawElements( GLES20.GL_TRIANGLE_STRIP, indexBuffer.limit(), GLES20.GL_UNSIGNED_SHORT, indexBuffer); ShaderUtil.checkGLError(TAG, "Drawing plane"); }
private void draw(float[] cameraView, float[] cameraPerspective) { // Build the ModelView and ModelViewProjection matrices // for calculating cube position and light. Matrix.multiplyMM(modelViewMatrix, 0, cameraView, 0, modelMatrix, 0); Matrix.multiplyMM(modelViewProjectionMatrix, 0, cameraPerspective, 0, modelViewMatrix, 0); // Set the position of the plane vertexBuffer.rewind(); GLES20.glVertexAttribPointer( planeXZPositionAlphaAttribute, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, BYTES_PER_FLOAT * COORDS_PER_VERTEX, vertexBuffer); // Set the Model and ModelViewProjection matrices in the shader. GLES20.glUniformMatrix4fv(planeModelUniform, 1, false, modelMatrix, 0); GLES20.glUniformMatrix4fv( planeModelViewProjectionUniform, 1, false, modelViewProjectionMatrix, 0); indexBuffer.rewind(); GLES20.glDrawElements( GLES20.GL_TRIANGLE_STRIP, indexBuffer.limit(), GLES20.GL_UNSIGNED_SHORT, indexBuffer); ShaderUtil.checkGLError(TAG, "Drawing plane"); }
GLES20.glEnable(GLES20.GL_DEPTH_TEST); ShaderUtil.checkGLError(TAG, "Draw");
GLES20.glEnable(GLES20.GL_DEPTH_TEST); ShaderUtil.checkGLError(TAG, "Draw");