OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EGLPreserve.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2012-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
40 #include <GLES2/gl2.h>
41 #include <GLES2/gl2ext.h>
42 #include <EGL/egl.h>
43 
44 #include <string>
45 
46 #include <jni.h>
47 #include <android/log.h>
48 
49 #include <sys/time.h>
50 
51 #include "EGLPreserve.h"
52 #include "Text.h"
53 #include "Shader.h"
54 #include "Texture.h"
55 #include "Matrix.h"
56 #include "Platform.h"
57 #include "Timer.h"
58 #include "AndroidPlatform.h"
59 
60 using std::string;
61 using namespace MaliSDK;
62 
63 /* Asset directories and filenames. */
64 string resourceDirectory = "/data/data/com.arm.malideveloper.openglessdk.eglpreserve/";
65 string vertexShaderFilename = "EGLPreserve_cube.vert";
66 string fragmentShaderFilename = "EGLPreserve_cube.frag";
67 
68 string scissorOff = "Scissor: off";
69 string scissorOn = "Scissor: on ";
70 string preserveOff = "Preserve: off";
71 string preserveOn = "Preserve: on ";
72 
73 /* Shader variables. */
75 GLint iLocPosition = -1;
76 GLint iLocFillColor = -1;
77 GLint iLocProjection = -1;
78 GLint iLocModelview = -1;
79 
80 /* Animation variables. */
83 
84 unsigned int windowWidth = 0;
85 unsigned int windowHeight = 0;
86 
87 /* Timer variable to do the animation. */
89 
90 /* A text object to draw text on the screen. */
92 
93 bool setupGraphics(int width, int height)
94 {
97 
98  /* Full paths to the shader and texture files */
99  string vertexShaderPath = resourceDirectory + vertexShaderFilename;
100  string fragmentShaderPath = resourceDirectory + fragmentShaderFilename;
101 
102  /* Initialize matrices. */
104  /* Move cube 2 further away from camera. */
105  translation = Matrix::createTranslation(0.0f, 0.0f, -2.0f);
106 
107  /* Initialize OpenGL ES. */
108  GL_CHECK(glEnable(GL_CULL_FACE));
109  GL_CHECK(glCullFace(GL_BACK));
110  GL_CHECK(glEnable(GL_DEPTH_TEST));
111  GL_CHECK(glEnable(GL_BLEND));
112  /* Should do src * (src alpha) + dest * (1-src alpha). */
113  GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
114 
115  /* Initialize the Text object. */
117 
118  /* Process shaders. */
121  Shader::processShader(&vertexShaderID, vertexShaderPath.c_str(), GL_VERTEX_SHADER);
122  Shader::processShader(&fragmentShaderID, fragmentShaderPath.c_str(), GL_FRAGMENT_SHADER);
123 
124  /* Set up shaders. */
125  programID = GL_CHECK(glCreateProgram());
126  GL_CHECK(glAttachShader(programID, vertexShaderID));
127  GL_CHECK(glAttachShader(programID, fragmentShaderID));
128  GL_CHECK(glLinkProgram(programID));
129  GL_CHECK(glUseProgram(programID));
130 
131  /* Vertex positions. */
132  iLocPosition = GL_CHECK(glGetAttribLocation(programID, "a_v4Position"));
133  if(iLocPosition == -1)
134  {
135  LOGE("Attribute not found at %s:%i\n", __FILE__, __LINE__);
136  return false;
137  }
138  GL_CHECK(glEnableVertexAttribArray(iLocPosition));
139 
140  /* Vertex colors. */
141  iLocFillColor = GL_CHECK(glGetAttribLocation(programID, "a_v4FillColor"));
142  if(iLocFillColor == -1)
143  {
144  LOGD("Warning: Attribute not found at %s:%i\n", __FILE__, __LINE__);
145  }
146  else
147  {
148  GL_CHECK(glEnableVertexAttribArray(iLocFillColor));
149  }
150 
151  /* Projection matrix. */
152  iLocProjection = GL_CHECK(glGetUniformLocation(programID, "u_m4Projection"));
153  if(iLocProjection == -1)
154  {
155  LOGD("Warning: Uniform not found at %s:%i\n", __FILE__, __LINE__);
156  }
157  else
158  {
159  GL_CHECK(glUniformMatrix4fv(iLocProjection, 1, GL_FALSE, perspective.getAsArray()));
160  }
161 
162  /* Modelview matrix. */
163  iLocModelview = GL_CHECK(glGetUniformLocation(programID, "u_m4Modelview"));
164  if(iLocModelview == -1)
165  {
166  LOGD("Warning: Uniform not found at %s:%i\n", __FILE__, __LINE__);
167  }
168  /* We pass this for each object, below. */
169 
170  /* Set clear screen color. */
171  GL_CHECK(glClearColor(0.5f, 0.5f, 0.5f, 1.0));
172 
174 
175  /* Tweak EGL. */
176  /* Check if the EGL_SWAP_BEHAVIOR_PRESERVED_BIT is set in EGL_SURFACE_TYPE. */
177  EGLint swapBehaviour;
178  if(eglQuerySurface(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), EGL_SWAP_BEHAVIOR, &swapBehaviour) != EGL_TRUE)
179  {
180  LOGD("Warning: eglQuerySurface() failed at %s:%i\n", __FILE__, __LINE__);
181  }
182 
183  LOGI("Default values:");
184  LOGI("EGL_SWAP_BEHAVIOR = 0x%.4x", (int)swapBehaviour);
185  switch(swapBehaviour)
186  {
187  case (EGL_BUFFER_PRESERVED):
188  LOGI(" = EGL_BUFFER_PRESERVED");
189  break;
190  case (EGL_BUFFER_DESTROYED):
191  LOGI(" = EGL_BUFFER_DESTROYED");
192  break;
193  default:
194  LOGI(" = UNKNOWN");
195  break;
196  }
197 
198  /* Set preserve bit. */
199  if(eglSurfaceAttrib(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED) != EGL_TRUE)
200  {
201  LOGD("Warning: eglSurfaceAttrib() failed at %s:%i\n", __FILE__, __LINE__);
202  }
203 
204  return true;
205 }
206 
207 void renderFrame(void)
208 {
209  static float angleX = 0.0f;
210  static float angleY = 0.0f;
211  static float angleZ = 0.0f;
212 
213  static bool fullScreen = false;
214  static bool preserve = false;
215 
216  /* Change the animation state if more than 3 seconds are passed since the last state change. */
217  if(animationTimer.isTimePassed(3.0f))
218  {
219  fullScreen = !fullScreen;
220 
221  text->clear();
222  if(fullScreen)
223  {
225  LOGI("Scissor off\n");
226 
227  GL_CHECK(glDisable(GL_SCISSOR_TEST))
228  preserve = !preserve;
229  if(preserve)
230  {
231  /* Set preserve bit. */
232  LOGI("Preserve on\n");
233  if(eglSurfaceAttrib(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED) != EGL_TRUE)
234  {
235  LOGD("Warning: eglSurfaceAttrib() failed at %s:%i\n", __FILE__, __LINE__);
236  }
237  }
238  else
239  {
240  /* Clear preserve bit. */
241  LOGI("Preserve off\n");
242  if(eglSurfaceAttrib(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED) != EGL_TRUE)
243  {
244  LOGD("Warning: eglSurfaceAttrib() failed at %s:%i\n", __FILE__, __LINE__);
245  }
246  }
247  }
248  else
249  {
251  LOGI("Scissor on\n");
252  GL_CHECK(glEnable(GL_SCISSOR_TEST));
253  GL_CHECK(glScissor(windowWidth / 2, 0, windowWidth / 2, windowHeight));
254  if(preserve)
255  {
256  text->addString(windowWidth - preserveOn.length() * Text::textureCharacterWidth, 0, preserveOn.c_str(), 0, 255, 0, 255);
257  }
258  else
259  {
260  text->addString(windowWidth - preserveOff.length() * Text::textureCharacterWidth, 0, preserveOff.c_str(), 255, 0, 0, 255);
261  }
262  }
263  }
264 
265  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
266 
270 
271  /* Update cube's rotation angles for animating. */
272  angleX += 3;
273  angleY += 2;
274  angleZ += 1;
275 
276  if(angleX >= 360) angleX -= 360;
277  if(angleY >= 360) angleY -= 360;
278  if(angleZ >= 360) angleZ -= 360;
279 
280  /* Rotate about origin, then translate away from camera. */
282  modelView = modelView * rotationY;
283  modelView = modelView * rotationZ;
284 
285  GL_CHECK(glUseProgram(programID));
286 
287  GL_CHECK(glUniformMatrix4fv(iLocModelview, 1, GL_FALSE, modelView.getAsArray()));
288  GL_CHECK(glUniformMatrix4fv(iLocProjection, 1, GL_FALSE, perspective.getAsArray()));
289 
290  /* Both drawing surfaces also share vertex data. */
291  GL_CHECK(glEnableVertexAttribArray(iLocPosition));
292  GL_CHECK(glVertexAttribPointer(iLocPosition, 3, GL_FLOAT, GL_FALSE, 0, cubeVertices));
293 
294  if(iLocFillColor != -1)
295  {
296  GL_CHECK(glEnableVertexAttribArray(iLocFillColor));
297  GL_CHECK(glVertexAttribPointer(iLocFillColor, 4, GL_FLOAT, GL_FALSE, 0, cubeColors));
298  }
299 
300  /* Draw the cube. */
301  GL_CHECK(glDrawElements(GL_TRIANGLE_STRIP, 22, GL_UNSIGNED_BYTE, cubeIndices));
302 
303  /* Draw fonts. */
304  text->draw();
305 }
306 
307 extern "C"
308 {
310  (JNIEnv *env, jclass jcls, jint width, jint height)
311  {
312  /* Reset the timer variables to do the animation. */
314 
315  /* Make sure that all resource files are in place. */
318 
319  setupGraphics(width, height);
320  }
321 
323  (JNIEnv *env, jclass jcls)
324  {
325  renderFrame();
326  }
327 
329  (JNIEnv *, jclass)
330  {
331  delete text;
332  }
333 }
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_eglpreserve_EGLPreserve_init(JNIEnv *env, jclass jcls, jint width, jint height)
GLuint programID
Definition: EGLPreserve.cpp:74
Matrix rotationY
#define LOGI(...)
Definition: AstcTextures.h:29
Matrix rotationZ
GLfloat cubeColors[numberOfValuesInCubeColorsArray]
Definition: Native.cpp:67
Functions for drawing text in OpenGL ES.
Definition: Text.h:44
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
Functions for manipulating matrices.
Definition: Matrix.h:31
Timer animationTimer
Definition: EGLPreserve.cpp:88
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_eglpreserve_EGLPreserve_step(JNIEnv *env, jclass jcls)
GLuint fragmentShaderID
static Matrix createTranslation(float x, float y, float z)
Create and return a translation matrix.
Definition: Matrix.cpp:414
static float angleZ
Provides a platform independent high resolution timer.
Definition: Timer.h:37
void clear(void)
Removes the current string from the class.
Definition: Text.cpp:142
#define LOGD(...)
Definition: AstcTextures.h:28
Matrix modelView
string scissorOn
Definition: EGLPreserve.cpp:69
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
Definition: Matrix.cpp:425
GLint iLocPosition
Definition: EGLPreserve.cpp:75
GLint iLocModelview
Definition: EGLPreserve.cpp:78
unsigned int windowWidth
Definition: EGLPreserve.cpp:84
GLint iLocFillColor
Definition: EGLPreserve.cpp:76
float * getAsArray(void)
Get the matrix elements as a column major order array.
Definition: Matrix.cpp:78
static const float cubeVertices[]
Definition: EGLPreserve.h:42
static const int textureCharacterHeight
The height (in pixels) of the characters in the text texture.
Definition: Text.h:89
static const GLubyte cubeIndices[]
Definition: EGLPreserve.h:29
GLint iLocProjection
Definition: EGLPreserve.cpp:77
void reset()
Resets the timer to 0.0f.
Definition: Timer.cpp:100
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_eglpreserve_EGLPreserve_uninit(JNIEnv *, jclass)
static const int textureCharacterWidth
The width (in pixels) of the characters in the text texture.
Definition: Text.h:83
static float angleX
Matrix perspective
Definition: EGLPreserve.cpp:81
GLfloat GLfloat f
Definition: gl2ext.h:2707
Matrix translation
Definition: EGLPreserve.cpp:82
void addString(int xPosition, int yPosition, const char *string, int red, int green, int blue, int alpha)
Add a std::string to be drawn to the screen.
Definition: Text.cpp:157
bool setupGraphics(int width, int height)
Definition: EGLPreserve.cpp:93
#define GL_CHECK(x)
Definition: AstcTextures.h:59
unsigned int windowHeight
Definition: EGLPreserve.cpp:85
static Matrix createRotationY(float angle)
Create and return a rotation matrix around the y-axis matrix.
Definition: Matrix.cpp:511
static Matrix createRotationZ(float angle)
Create and return a rotation matrix around the z-axis matrix.
Definition: Matrix.cpp:523
string preserveOn
Definition: EGLPreserve.cpp:71
static bool getAndroidAsset(JNIEnv *JNIEnvironment, const char destinationDirectory[], const char filename[])
Extract an asset file from the APK.
float angleY
Definition: Native.cpp:118
string preserveOff
Definition: EGLPreserve.cpp:70
string fragmentShaderFilename
Definition: EGLPreserve.cpp:66
string scissorOff
Definition: EGLPreserve.cpp:68
string resourceDirectory
Definition: EGLPreserve.cpp:64
GLuint vertexShaderID
#define LOGE(...)
Definition: AstcTextures.h:30
Text * text
Definition: EGLPreserve.cpp:91
Matrix rotationX
GLint GLsizei width
Definition: gl2ext.h:179
string vertexShaderFilename
Definition: EGLPreserve.cpp:65
static void processShader(GLuint *shader, const char *filename, GLint shaderType)
Create shader, load in source, compile, and dump debug as necessary.
Definition: Shader.cpp:29
bool isTimePassed(float seconds=1.0f)
Tests if 'seconds' seconds have passed since reset() or this method was called.
Definition: Timer.cpp:141
void draw(void)
Draw the text to the screen.
Definition: Text.cpp:265
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
static Matrix createRotationX(float angle)
Create and return a rotation matrix around the x-axis matrix.
Definition: Matrix.cpp:499
void renderFrame(void)