/* * Copyright 2014 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.kitware.tangoutils.renderables; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import android.opengl.GLES20; import android.opengl.Matrix; /** * {@link Renderable} OpenGL object showing the 'floor' of the current scene. * This is a static grid placed in the scene to provide perspective in the * various views. */ public class Grid extends Renderable { private static final int COORDS_PER_VERTEX = 3; private static final int GRID_RANGE_M = 100; private static final int BYTES_PER_FLOAT = 4; private static final String sVertexShaderCode = "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + "gl_Position = uMVPMatrix * vPosition;" + "}"; private static final String sFragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vec4(0.8,0.8,0.8,1.0);" + "}"; private FloatBuffer mVertexBuffer; private final int mProgram; private int mPosHandle; private int mMVPMatrixHandle; public Grid() { // Reset the model matrix to the identity Matrix.setIdentityM(getModelMatrix(), 0); // Allocate a vertex buffer ByteBuffer vertexByteBuffer = ByteBuffer .allocateDirect((GRID_RANGE_M * 2 + 1) * 4 * 3 * BYTES_PER_FLOAT); vertexByteBuffer.order(ByteOrder.nativeOrder()); mVertexBuffer = vertexByteBuffer.asFloatBuffer(); // Load the vertices for the z-axis grid lines into the vertex buffer for (int x = -GRID_RANGE_M; x <= GRID_RANGE_M; x++) { mVertexBuffer.put(new float[] { x, -1.3f, (float) -GRID_RANGE_M }); mVertexBuffer.put(new float[] { x, -1.3f, (float) GRID_RANGE_M }); } // Load the vertices for the x-axis grid lines into the vertex buffer for (int z = -GRID_RANGE_M; z <= GRID_RANGE_M; z++) { mVertexBuffer.put(new float[] { (float) -GRID_RANGE_M, -1.3f, z }); mVertexBuffer.put(new float[] { (float) GRID_RANGE_M, -1.3f, z }); } // Load the vertex and fragment shaders, then link the program int vertexShader = RenderUtils.loadShader(GLES20.GL_VERTEX_SHADER, sVertexShaderCode); int fragShader = RenderUtils.loadShader(GLES20.GL_FRAGMENT_SHADER, sFragmentShaderCode); mProgram = GLES20.glCreateProgram(); GLES20.glAttachShader(mProgram, vertexShader); GLES20.glAttachShader(mProgram, fragShader); GLES20.glLinkProgram(mProgram); } @Override public void draw(float[] viewMatrix, float[] projectionMatrix) { GLES20.glUseProgram(mProgram); mVertexBuffer.position(0); // Compose the model, view, and projection matrices into a single m-v-p // matrix updateMvpMatrix(viewMatrix, projectionMatrix); // Load vertex attribute data mPosHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); GLES20.glVertexAttribPointer(mPosHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, mVertexBuffer); GLES20.glEnableVertexAttribArray(mPosHandle); // Draw the Grid mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, getMvpMatrix(), 0); GLES20.glLineWidth(1); GLES20.glDrawArrays(GLES20.GL_LINES, 0, (GRID_RANGE_M * 2 + 1) * 4); } }