OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Native.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2014-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 
30 #include <jni.h>
31 #include <android/log.h>
32 
33 #include <GLES3/gl3.h>
34 #include "Common.h"
35 #include "CubeModel.h"
36 #include "Instancing.h"
37 #include "Shader.h"
38 #include "Timer.h"
39 #include <cstring>
40 
41 using namespace MaliSDK;
42 
43 /* Instance of a timer. Used for setting positions and rotations of cubes. */
45 /* Program used for transforming vertices into world space. */
46 /* Fragment shader name. */
48 /* Vertex shader name. */
50 /* Program name. */
52 
53 /* Cubes. */
54 /* Number of coordinates written to cubeTrianglesCoordinates array*/
56 /* Number of vertices that make up a cubic shape. */
58 /* Array holding coordinates of triangles which a cube consists of. */
60 /* Number of values written to vertexColors array. */
62 /* Array holding color values for each vertex of cube triangle. */
64 /* Number of values written to cubeColors array. RGBA values for each cube. */
66 /* Array holding color values for each cube. */
68 /* Scaling factor indicating size of a cube. */
69 const float cubeSize = 2.5f;
70 
71 /* Uniform and attribute locations. */
72 /* "Camera position" shader uniform which is used to set up a view. */
74 /* Shader uniform block index. */
76 /* "Perspective matrix" shader uniform's location. */
78 /* "Position" shader attribute's location. */
79 GLint positionLocation = 0;
80 /* "Color" shader attribute's location. */
82 /* "Time" shader uniform that is used to hold timer value. */
83 GLint timeLocation = 0;
84 
85 /* Buffer objects. */
86 /* Constant telling number of buffer objects that should be generated:
87 * - buffer object holding cube coordinates,
88 * - buffer object holding per-vertex cube colors,
89 * - buffer object holding data used in uniform block.
90 */
92 /* Array of buffer object names. */
94 /* Name of buffer object which holds color of triangle vertices. */
96 /* Name of buffer object which holds coordinates of triangles making cube. */
98 /* Name of buffer object which holds start positions of cubes and values of color for each cube. */
100 
101 /* Start positions of cubes in 3D space. */
102 /* Array holding start position of cubes in 3D space which are used to draw cubes for the first time. */
104 
105 /*
106  * Arrays holding data used for setting perspective and view.
107  * 45.0f - field of view angle (in degrees) in the y direction
108  * (float)windowWidth / (float)windowHeight - ratio used to calculate the field of view in the x direction.
109  * 0.1f - distance from the camera to the near clipping plane.
110  * 1000.0f - distance from the camera to the far clipping plane.
111 */
113 /* Array used for view configuration in vertex shader. */
115 
116 /* [Generate cube start positions data] */
122 {
123  float spaceBetweenCubes = (2 * M_PI) / (NUMBER_OF_CUBES);
124 
125  /* Fill array with startPosition data. */
126  for (int allCubes = 0; allCubes < NUMBER_OF_CUBES; allCubes++)
127  {
128  startPosition[allCubes] = allCubes * spaceBetweenCubes;
129  }
130 }
131 /* [Generate cube start positions data] */
132 
133 /* [Generate cube colours data] */
138 {
139  for (int allComponents = 0;
140  allComponents < numberOfValuesInCubeColorsArray;
141  allComponents++)
142  {
143  /* Get random value from [0.0, 1.0] range. */
144  cubeColors[allComponents] = (float)rand() / (float)RAND_MAX;
145  }
146 }
147 /* [Generate cube colours data] */
148 
149 /*
150  * \brief Fill vertexColors array with random color for each vertex of a cube triangular representation.
151  */
153 {
154  /* Calculate number of colour components for each cube vertex. */
156 
157  /* Allocate memory for vertexColors array. */
158  vertexColors = (float*) malloc (numberOfValuesInVertexColorsArray * sizeof(float));
159 
160  ASSERT(vertexColors != NULL, "Could not allocate memory for vertexColors array.");
161 
162  for (int allComponents = 0;
163  allComponents < numberOfValuesInVertexColorsArray;
164  allComponents++)
165  {
166  vertexColors[allComponents] = (float)rand() / (float)RAND_MAX;
167  }
168 }
169 
174 {
175  /* [Get cube coordinates] */
176  /* Get triangular representation of a cube. Save data in cubeTrianglesCoordinates array. */
180  cubeSize);
181  /* [Get cube coordinates] */
182 
183  /* Make sure triangular representation of a cube was created successfully. */
185  "Could not retrieve triangle representation of a cube");
186 
187  /* Set start values of positions. */
189 
190  /* Calculate color for each cube. */
192 
193  /* Calculate color for each vertex of a cube. */
195 }
196 
197 /*
198  * Initializes data used for rendering.
199  */
201 {
202  /* Create all data needed to draw cube. */
203  createCubesData();
204 
205  /* Settings for 3D shape drawing. */
206  GL_CHECK(glEnable(GL_DEPTH_TEST));
207 
208  /* [Generate buffer objects] */
209  /* Generate buffers. */
211 
215  /* [Generate buffer objects] */
216 
217  /* [Fill buffer object with vertex data] */
218  /* Buffer holding coordinates of triangles which create a cube. */
219  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,
221  GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
224  GL_STATIC_DRAW));
225  /* [Fill buffer object with vertex data] */
226 
227  /* Buffer holding RGBA values of color for each vertex. */
228  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,
230  GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
232  vertexColors,
233  GL_STATIC_DRAW));
234 
235  /* [Set uniform block buffer data] */
236  /* Buffer holding coordinates of start positions of cubes and RGBA values of colors. */
237  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER,
239  GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
240  sizeof(startPosition) + sizeof(cubeColors),
241  NULL,
242  GL_STATIC_DRAW));
243 
244  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER,
245  0,
246  sizeof(startPosition),
247  startPosition));
248  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER,
249  sizeof(startPosition),
250  sizeof(cubeColors),
251  cubeColors));
252  /* [Set uniform block buffer data] */
253 
254  /* Deallocate memory (data is now stored in buffer objects). */
255  if (vertexColors != NULL)
256  {
257  free(vertexColors);
258 
259  vertexColors = NULL;
260  }
261 
262  if (cubeTrianglesCoordinates != NULL)
263  {
265 
267  }
268 }
269 
270 /*
271  * Create programs that will be used to rasterize the geometry of cubes.
272  */
274 {
275  /* [Create a program object] */
276  renderingProgramId = GL_CHECK(glCreateProgram());
277  /* [Create a program object] */
278 
279  /* Initialize rendering program. */
280  /* [Initialize shader objects] */
283  /* [Initialize shader objects] */
284 
285  /* [Attach vertex and fragment shader objects to rendering program] */
286  GL_CHECK(glAttachShader(renderingProgramId, vertexShaderId));
287  GL_CHECK(glAttachShader(renderingProgramId, fragmentShaderId));
288  /* [Attach vertex and fragment shader objects to rendering program] */
289 
290  /* Link and use rendering program object. */
291  /* [Link the program object] */
292  GL_CHECK(glLinkProgram(renderingProgramId));
293  /* [Link the program object] */
294  /* [Set active program object] */
295  GL_CHECK(glUseProgram(renderingProgramId));
296  /* [Set active program object] */
297 
298  /* Get uniform, attribute and uniform block locations from current program. */
299  /* [Get position attribute location] */
300  positionLocation = GL_CHECK(glGetAttribLocation (renderingProgramId, "attributePosition"));
301  /* [Get position attribute location] */
302  cubeVertexColorLocation = GL_CHECK(glGetAttribLocation (renderingProgramId, "attributeColor"));
303  perspectiveMatrixLocation = GL_CHECK(glGetUniformLocation (renderingProgramId, "perspectiveVector"));
304  cameraPositionLocation = GL_CHECK(glGetUniformLocation (renderingProgramId, "cameraVector"));
305  /* [Get uniform block index] */
306  uniformBlockIndex = GL_CHECK(glGetUniformBlockIndex(renderingProgramId, "CubesUniformBlock"));
307  /* [Get uniform block index] */
308  timeLocation = GL_CHECK(glGetUniformLocation (renderingProgramId, "time"));
309 
310  /* [Check position attribute location] */
311  ASSERT(positionLocation != -1, "Could not retrieve attribute location: attributePosition");
312  /* [Check position attribute location] */
313  ASSERT(cubeVertexColorLocation != -1, "Could not retrieve attribute location: attributeColor");
314  ASSERT(perspectiveMatrixLocation != -1, "Could not retrieve uniform location: perspectiveVector");
315  ASSERT(cameraPositionLocation != -1, "Could not retrieve uniform location: cameraVector");
316  ASSERT(timeLocation != -1, "Could not retrieve uniform location: time");
317  /* [Check uniform block index] */
318  ASSERT(uniformBlockIndex != GL_INVALID_INDEX, "Could not retrieve uniform block index: CubesUniformBlock");
319  /* [Check uniform block index] */
320 }
321 
326 {
327  /* Clear contents of back buffer. */
328  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
329 
330  /* Value of time returned by timer used for setting cubes rotations and positions. */
331  const float time = timer.getTime();
332 
333  /* [Set time uniform value] */
334  GL_CHECK(glUniform1f(timeLocation, time));
335  /* [Set time uniform value] */
336 
337  /* [Instanced drawing command] */
338  /* Draw cubes on a screen. */
339  GL_CHECK(glDrawArraysInstanced(GL_TRIANGLES,
340  0,
342  NUMBER_OF_CUBES));
343  /* [Instanced drawing command] */
344 }
345 
346 void setupGraphics(int width, int height)
347 {
348  perspectiveVector.x = 45.0f;
349  perspectiveVector.y = (float)width / (float)height;
350  perspectiveVector.z = 0.1f;
351  perspectiveVector.w = 1000.0f;
352 
353  cameraVector.x = 0.0f;
354  cameraVector.y = 0.0f;
355  cameraVector.z = -60.0f;
356 
357  /* Initialize data used for rendering. */
358  initializeData();
359  /* Create program. */
360  setupProgram();
361  /* Start counting time. */
362  timer.reset();
363 
364  GL_CHECK(glUseProgram(renderingProgramId));
365 
366  /* Enable VAAa. */
367  /* [Set Vertex Attrib Array for cube coordinates] */
368  GL_CHECK(glBindBuffer (GL_ARRAY_BUFFER,
370  GL_CHECK(glEnableVertexAttribArray(positionLocation));
371  GL_CHECK(glVertexAttribPointer (positionLocation,
373  GL_FLOAT,
374  GL_FALSE,
375  0,
376  0));
377  /* [Set Vertex Attrib Array for cube coordinates] */
378 
379  GL_CHECK(glBindBuffer (GL_ARRAY_BUFFER,
381  GL_CHECK(glEnableVertexAttribArray(cubeVertexColorLocation));
382  GL_CHECK(glVertexAttribPointer (cubeVertexColorLocation,
384  GL_FLOAT,
385  GL_FALSE,
386  0,
387  0));
388 
389  /* Set uniform values which are constant during the rendering process. */
390  /* [Set perspective vector uniform value] */
391  GL_CHECK(glUniform4fv(perspectiveMatrixLocation,
392  1,
394  /* [Set perspective vector uniform value] */
395  /* [Set camera position uniform value] */
396  GL_CHECK(glUniform3fv(cameraPositionLocation,
397  1,
398  (GLfloat*)&cameraVector));
399  /* [Set camera position uniform value] */
400 
401  /* [Set uniform block data] */
402  /* Set binding point for uniform block. */
403  GL_CHECK(glUniformBlockBinding(renderingProgramId,
405  0));
406  GL_CHECK(glBindBufferBase (GL_UNIFORM_BUFFER,
407  0,
409  /* [Set uniform block data] */
410 }
411 
412 void uninit()
413 {
414  /* Delete buffers. */
416 
417  /* Free allocated memory. */
418  if (cubeTrianglesCoordinates != NULL)
419  {
421 
423  }
424 
425  if (vertexColors != NULL)
426  {
427  free(vertexColors);
428 
429  vertexColors = NULL;
430  }
431 }
432 
433 extern "C"
434 {
435  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_init (JNIEnv * env, jobject obj, jint width, jint height);
436  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_step (JNIEnv * env, jobject obj);
437  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_uninit(JNIEnv * env, jobject obj);
438 };
439 
441  JNIEnv * env, jobject obj, jint width, jint height)
442 {
443  setupGraphics(width, height);
444 }
445 
447  JNIEnv * env, jobject obj)
448 {
449  uninit();
450 }
451 
452 
454  JNIEnv * env, jobject obj)
455 {
456  renderFrame();
457 }
void setupGraphics(int width, int height)
Definition: Native.cpp:1256
const int numberOfValuesInCubeColorsArray
Definition: Native.cpp:65
Vec4f perspectiveVector
Definition: Native.cpp:112
GLint perspectiveMatrixLocation
Definition: Native.cpp:97
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_init(JNIEnv *env, jobject obj, jint width, jint height)
Definition: Native.cpp:440
GLint cameraPositionLocation
Definition: Native.cpp:93
#define GL_CHECK(x)
Definition: Native.cpp:64
float getTime()
Returns the time passed since object creation or since reset() was last called.
Definition: Timer.cpp:109
void fillCubeColorsArray()
Fill cubeColors array with random color (used for setting random color for each cube).
Definition: Native.cpp:137
GLfloat cubeColors[numberOfValuesInCubeColorsArray]
Definition: Native.cpp:67
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
const float cubeSize
Definition: Native.cpp:69
GLint positionLocation
Definition: Native.cpp:99
GLuint vertexShaderId
Definition: Native.cpp:57
GLuint uniformBlockDataBufferObjectId
Definition: Native.cpp:99
Vec3f cameraVector
Definition: Native.cpp:114
Provides a platform independent high resolution timer.
Definition: Timer.h:37
#define NUMBER_OF_COLOR_COMPONENTS
Definition: Instancing.h:29
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_uninit(JNIEnv *env, jobject obj)
Definition: Native.cpp:446
GLuint renderingProgramId
Definition: Native.cpp:59
GLuint cubeCoordinatesBufferObjectId
Definition: Native.cpp:97
#define VERTEX_SHADER_FILE_NAME
Definition: Boids.h:29
A 3D floating point vector.
Definition: VectorTypes.h:83
float * vertexColors
Definition: Native.cpp:83
void createCubesData()
Definition: Native.cpp:173
void reset()
Resets the timer to 0.0f.
Definition: Timer.cpp:100
int numberOfCubeVertices
Definition: Native.cpp:57
GLuint uniformBlockIndex
Definition: Native.cpp:75
int numberOfCubeTriangleCoordinates
Definition: Native.cpp:55
void uninit()
Delete created objects and free allocated memory.
Definition: Native.cpp:1706
void generateStartPosition()
Generate positions of cubes which are used during first draw call.
Definition: Native.cpp:121
GLint cubeVertexColorLocation
Definition: Native.cpp:81
GLfloat startPosition[NUMBER_OF_CUBES]
Definition: Native.cpp:103
static void getTriangleRepresentation(float scalingFactor, int *numberOfCoordinates, float **coordinates)
Compute coordinates of points which make up a cube.
Definition: CubeModel.cpp:29
#define M_PI
The value of pi.
Definition: Mathematics.h:37
void renderFrame(void)
Definition: Native.cpp:1536
#define FRAGMENT_SHADER_FILE_NAME
Definition: Boids.h:27
void initializeData()
Initializes data used for rendering.
Definition: Native.cpp:196
Timer timer
Definition: Native.cpp:1059
void setupProgram()
Definition: Native.cpp:273
GLuint cubeColorsBufferObjectId
Definition: Native.cpp:95
void fillVertexColorsArray()
Fill vertexColors array with random color for each triangle vertex.
Definition: Native.cpp:155
GLuint bufferObjectIds[numberOfBufferObjectIds]
Definition: Native.cpp:113
float * cubeTrianglesCoordinates
Definition: Native.cpp:59
int numberOfValuesInVertexColorsArray
Definition: Native.cpp:61
GLint timeLocation
Definition: Native.cpp:105
#define ASSERT(x, s)
Definition: common.h:45
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_instancing_NativeLibrary_step(JNIEnv *env, jobject obj)
Definition: Native.cpp:453
precision highp float
Definition: hiz_cull.cs:37
GLuint fragmentShaderId
Definition: Native.cpp:55
GLint GLsizei width
Definition: gl2ext.h:179
#define NUMBER_OF_POINT_COORDINATES
Number of coordinates for a point in 3D space.
Definition: Common.h:36
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
const GLuint numberOfBufferObjectIds
Definition: Native.cpp:111
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
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
A 4D floating point vector.
Definition: VectorTypes.h:127
#define NUMBER_OF_CUBES
Definition: Native.cpp:72
uniform float time
Definition: spawn.cs:50