ArViewer  Android Version
Arvos - Augmented reality viewer open source
 All Classes Namespaces Files Functions Variables
ArvosRenderer.java
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013, Peter Graf
3 
4  This file is part of Arvos - AR Viewer Open Source for Android.
5  Arvos is free software.
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20  For more information on the AR Viewer Open Source or Peter Graf,
21  please see: http://www.mission-base.com/.
22  */
23 
24 package com.mission_base.arviewer_android.viewer.opengl;
25 
26 import java.util.LinkedList;
27 import java.util.List;
28 
29 import javax.microedition.khronos.egl.EGLConfig;
30 import javax.microedition.khronos.opengles.GL10;
31 
32 import android.opengl.GLSurfaceView.Renderer;
33 import android.opengl.GLU;
34 
35 import com.mission_base.arviewer_android.Arvos;
36 import com.mission_base.arviewer_android.viewer.utilities.MatrixGrabber;
37 import com.mission_base.arviewer_android.viewer.utilities.MatrixTrackingGL;
38 
45 public class ArvosRenderer implements Renderer
46 {
47  private Arvos mInstance;
48 
49  public ArvosRenderer()
50  {
51  mInstance = Arvos.getInstance();
52  }
53 
54  private long mSecond = System.currentTimeMillis() / 1000;
55  private long mFPS = 0;
56 
57  private int counter = 0;
58 
59  @Override
60  public void onDrawFrame(GL10 gl)
61  {
62  long second = System.currentTimeMillis() / 1000;
63  if (mSecond != second)
64  {
65  mInstance.mFPS = mFPS;
66  mFPS = 1L;
67  mSecond = second;
68  }
69  else
70  {
71  mFPS++;
72  }
73 
74  long now = System.currentTimeMillis();
75 
76  List<ArvosObject> arvosObjects;
77  synchronized (mInstance.mArvosObjects)
78  {
79  arvosObjects = new LinkedList<ArvosObject>(mInstance.mArvosObjects);
80  }
81 
82  List<ArvosObject> newObjects = mInstance.mAugment.getObjects(now, arvosObjects);
83 
84  synchronized (mInstance.mArvosObjects)
85  {
86  mInstance.mArvosObjects.clear();
87  mInstance.mArvosObjects.addAll(newObjects);
88 
89  MatrixTrackingGL mgl = null;
90 
91  if (mInstance.mModelViewMatrixesRequested)
92  {
93  gl = mgl = new MatrixTrackingGL(gl);
94  }
95 
96  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
97 
98  synchronized (mInstance.mModelViewMatrixes)
99  {
100  for (ArvosObject arvosObject : mInstance.mArvosObjects)
101  {
102  gl.glLoadIdentity();
103  arvosObject.draw(gl);
104 
105  if (mgl != null)
106  {
107  MatrixGrabber matrixGrabber = new MatrixGrabber();
108  matrixGrabber.getCurrentState(mgl);
109 
110  if (mInstance.mModelViewMatrixesRequested)
111  {
112  mInstance.mModelViewMatrixes.put(Integer.valueOf(arvosObject.mId), matrixGrabber.mModelView);
113  }
114  }
115  }
116  }
117  mInstance.mModelViewMatrixesRequested = false;
118  }
119 
120  if (++counter % 10 == 0)
121  {
122  getCorrectedAzimuth(new MatrixTrackingGL(gl));
123  counter = 0;
124  }
125  }
126 
127  private void getCorrectedAzimuth(MatrixTrackingGL gl)
128  {
129  gl.glLoadIdentity();
130 
131  // Take the device orientation into account
132  //
133  gl.glRotatef(mInstance.getRotationDegrees(), 0f, 0f, 1f);
134 
135  // The device coordinates are flat on the table with X east, Y north and
136  // Z up.
137  // The world coordinates are X east, Y up and Z north
138  //
139  gl.glRotatef(90, 1f, 0f, 0f);
140 
141  // Apply azimut, pitch and roll of the device
142  //
143  gl.glRotatef(mInstance.mRoll, 0f, 0f, -1f);
144  gl.glRotatef(mInstance.mPitch, 1f, 0f, 0f);
145  gl.glRotatef(mInstance.mAzimuth, 0f, 1f, 0f);
146 
147  MatrixGrabber matrixGrabber = new MatrixGrabber();
148  matrixGrabber.getCurrentState(gl);
149 
150  float[] modelViewMatrix = matrixGrabber.mModelView;
151 
152  float f = ArvosObject.l3dBillboardCylindricalDegrees(0, 0, 0, modelViewMatrix[2], 0, -modelViewMatrix[10], null);
153  if (!Float.isNaN(f))
154  {
155  int sign = 1;
156  if (modelViewMatrix[2] > 0)
157  {
158  sign = -1;
159  }
160  mInstance.mCorrectedAzimuth = sign * f;
161  }
162  }
163 
164  @Override
165  public void onSurfaceChanged(GL10 gl, int width, int height)
166  {
167  mInstance.mHandleTouch = false;
168  mInstance.mModelViewMatrixesRequested = false;
169 
170  MatrixTrackingGL mgl = new MatrixTrackingGL(gl);
171  if (height == 0)
172  {
173  height = 1;
174  }
175 
176  mInstance.mHeight = height;
177  mInstance.mWidth = width;
178 
179  synchronized (mInstance.mArvosObjects)
180  {
181  for (ArvosObject arvosObject : mInstance.mArvosObjects)
182  {
183  arvosObject.mTextureLoaded = false;
184  }
185  }
186 
187  mgl.glViewport(0, 0, width, height); // Reset The Current Viewport
188  mgl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix
189  mgl.glLoadIdentity(); // Reset The Projection Matrix
190 
191  // Calculate The Aspect Ratio Of The Window
192  GLU.gluPerspective(mgl, 45.0f, (float) width / (float) height, 0.1f, 200.0f);
193 
194  MatrixGrabber matrixGrabber = new MatrixGrabber();
195  matrixGrabber.getCurrentState(mgl);
196  mInstance.mProjectionMatrix = matrixGrabber.mProjection;
197 
198  mgl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix
199  mgl.glLoadIdentity(); // Reset The Modelview Matrix
200  }
201 
202  @Override
203  public void onSurfaceCreated(GL10 gl, EGLConfig config)
204  {
205  gl.glEnable(GL10.GL_TEXTURE_2D); // Enable mTexture Mapping ( NEW )
206  gl.glShadeModel(GL10.GL_SMOOTH); // Enable Smooth Shading
207 
208  gl.glClearDepthf(1.0f); // Depth Buffer Setup
209  gl.glEnable(GL10.GL_DEPTH_TEST); // Enables Depth Testing
210  gl.glDepthFunc(GL10.GL_LEQUAL); // The Type Of Depth Testing To Do
211 
212  // Really Nice Perspective Calculations
213  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
214 
215  gl.glClearColor(0, 0, 0, 0);
216 
217  gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
218  gl.glEnable(GL10.GL_BLEND);
219  }
220 }