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 
21 #include <jni.h>
22 #include <android/log.h>
23 
24 #include <GLES2/gl2.h>
25 #include <GLES2/gl2ext.h>
26 
27 #include <cstdio>
28 #include <cstdlib>
29 #include <cmath>
30 
31 #include "Matrix.h"
32 
33 /* [New includes and global variables.] */
34 #include <assimp/cimport.h>
35 #include <assimp/scene.h>
36 #include <vector>
37 
38 /* The global Assimp scene object. */
39 const struct aiScene* scene = NULL;
40 
41 std::vector<GLfloat> vertices;
42 std::vector<GLushort> indices;
43 /* [New includes and global variables.] */
44 
45 #define LOG_TAG "libNative"
46 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
47 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
48 
49 static const char glVertexShader[] =
50  "attribute vec4 vertexPosition;\n"
51  "attribute vec3 vertexColour;\n"
52  "varying vec3 fragColour;\n"
53  "uniform mat4 projection;\n"
54  "uniform mat4 modelView;\n"
55  "void main()\n"
56  "{\n"
57  " gl_Position = projection * modelView * vertexPosition;\n"
58  " fragColour = vertexColour;\n"
59  "}\n";
60 
61 static const char glFragmentShader[] =
62  "precision mediump float;\n"
63  "varying vec3 fragColour;\n"
64  "void main()\n"
65  "{\n"
66  " gl_FragColor = vec4(fragColour, 1.0);\n"
67  "}\n";
68 
69 GLuint loadShader(GLenum shaderType, const char* shaderSource)
70 {
71  GLuint shader = glCreateShader(shaderType);
72  if (shader != 0)
73  {
74  glShaderSource(shader, 1, &shaderSource, NULL);
75  glCompileShader(shader);
76  GLint compiled = 0;
77  glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
78  if (compiled != GL_TRUE)
79  {
80  GLint infoLen = 0;
81  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
82 
83  if (infoLen > 0)
84  {
85  char * logBuffer = (char*) malloc(infoLen);
86 
87  if (logBuffer != NULL)
88  {
89  glGetShaderInfoLog(shader, infoLen, NULL, logBuffer);
90  LOGE("Could not Compile Shader %d:\n%s\n", shaderType, logBuffer);
91  free(logBuffer);
92  logBuffer = NULL;
93  }
94 
95  glDeleteShader(shader);
96  shader = 0;
97  }
98  }
99  }
100 
101  return shader;
102 }
103 
104 GLuint createProgram(const char* vertexSource, const char * fragmentSource)
105 {
106  GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
107  if (vertexShader == 0)
108  {
109  return 0;
110  }
111 
112  GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
113  if (fragmentShader == 0)
114  {
115  return 0;
116  }
117 
118  GLuint program = glCreateProgram();
119 
120  if (program != 0)
121  {
122  glAttachShader(program, vertexShader);
123  glAttachShader(program, fragmentShader);
124  glLinkProgram(program);
125  GLint linkStatus = GL_FALSE;
126  glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
127  if(linkStatus != GL_TRUE)
128  {
129  GLint bufLength = 0;
130  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
131  if (bufLength > 0)
132  {
133  char* logBuffer = (char*) malloc(bufLength);
134 
135  if (logBuffer != NULL)
136  {
137  glGetProgramInfoLog(program, bufLength, NULL, logBuffer);
138  LOGE("Could not link program:\n%s\n", logBuffer);
139  free(logBuffer);
140  logBuffer = NULL;
141  }
142  }
143  glDeleteProgram(program);
144  program = 0;
145  }
146  }
147  return program;
148 }
149 
155 
157 float modelViewMatrix[16];
158 float angle = 0;
159 
160 bool setupGraphics(int width, int height)
161 {
163 
164  if (glProgram == 0)
165  {
166  LOGE ("Could not create program");
167  return false;
168  }
169 
170  vertexLocation = glGetAttribLocation(glProgram, "vertexPosition");
171  vertexColourLocation = glGetAttribLocation(glProgram, "vertexColour");
172  projectionLocation = glGetUniformLocation(glProgram, "projection");
173  modelViewLocation = glGetUniformLocation(glProgram, "modelView");
174 
175  /* Setup the perspective */
176  matrixPerspective(projectionMatrix, 45, (float)width / (float)height, 0.1f, 100);
177  glEnable(GL_DEPTH_TEST);
178 
179  glViewport(0, 0, width, height);
180 
181  /* [Load a model into the Open Asset Importer.] */
182  std::string sphere = "s 0 0 0 10";
183  scene = aiImportFileFromMemory(sphere.c_str(), sphere.length(), 0, ".nff");
184 
185  if(!scene)
186  {
187  LOGE("Open Asset Importer could not load scene. \n");
188  return false;
189  }
190  /* [Load a model into the Open Asset Importer.] */
191 
192  /* [Accumulate the model vertices and indices.] */
193  int vertices_accumulation = 0;
194  /* Go through each mesh in the scene. */
195  for (int i = 0; i < scene->mNumMeshes; i++)
196  {
197  /* Add all the vertices in the mesh to our array. */
198  for (int j = 0; j < scene->mMeshes[i]->mNumVertices; j++)
199  {
200  const aiVector3D& vector = scene->mMeshes[i]->mVertices[j];
201  vertices.push_back(vector.x);
202  vertices.push_back(vector.y);
203  vertices.push_back(vector.z);
204  }
205 
206  /*
207  * Add all the indices in the mesh to our array.
208  * Indices are listed in the Open Asset importer relative to the mesh they are in.
209  * Because we are adding all vertices from all meshes to one array we must add an offset
210  * to the indices to correct for this.
211  */
212  for (unsigned int j = 0 ; j < scene->mMeshes[i]->mNumFaces ; j++)
213  {
214  const aiFace& face = scene->mMeshes[i]->mFaces[j];
215  indices.push_back(face.mIndices[0] + vertices_accumulation);
216  indices.push_back(face.mIndices[1] + vertices_accumulation);
217  indices.push_back(face.mIndices[2] + vertices_accumulation);
218  }
219 
220  /* Keep track of number of vertices loaded so far to use as an offset for the indices. */
221  vertices_accumulation += scene->mMeshes[i]->mNumVertices;
222  }
223  /* [Accumulate the model vertices and indices.] */
224 
225  return true;
226 }
227 
229 {
230  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
231  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
232 
234 
237 
238  matrixTranslate(modelViewMatrix, 0.0f, 0.0f, -10.0f);
239 
240  /* [Pass the the model vertices and indices to OpenGL ES.] */
241  glUseProgram(glProgram);
242  /* Use the vertex data loaded from the Open Asset Importer. */
243  glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, &vertices[0]);
244  glEnableVertexAttribArray(vertexLocation);
245  /* We're using vertices as the colour data here for simplicity. */
246  glVertexAttribPointer(vertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, &vertices[0]);
247  glEnableVertexAttribArray(vertexColourLocation);
248 
249  glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
250  glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, modelViewMatrix);
251 
252  /* Use the index data loaded from the Open Asset Importer. */
253  glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, &indices[0]);
254  /* [Pass the the model vertices and indices to OpenGL ES.] */
255 
256  angle += 1;
257  if (angle > 360)
258  {
259  angle -= 360;
260  }
261 }
262 
263 extern "C"
264 {
266  JNIEnv * env, jobject obj, jint width, jint height);
268  JNIEnv * env, jobject obj);
269 };
270 
272  JNIEnv * env, jobject obj, jint width, jint height)
273 {
274  setupGraphics(width, height);
275 }
276 
278  JNIEnv * env, jobject obj)
279 {
280  renderFrame();
281 }
void setupGraphics(int width, int height)
Definition: Native.cpp:1256
static const char glVertexShader[]
Definition: Native.cpp:49
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_assetloading_NativeLibrary_step(JNIEnv *env, jobject obj)
Definition: Native.cpp:277
GLenum face
Definition: gl2ext.h:2797
const struct aiScene * scene
Definition: Native.cpp:39
float projectionMatrix[16]
Definition: Native.cpp:156
float modelViewMatrix[16]
Definition: Native.cpp:157
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLuint modelViewLocation
Definition: Native.cpp:154
void matrixIdentityFunction(float *matrix)
Takes a 4 * 4 and sets the elements to the Identity function.
Definition: Matrix.cpp:23
GLuint vertexColourLocation
Definition: Native.cpp:152
#define LOGE(...)
Definition: Native.cpp:47
void matrixPerspective(float *matrix, float fieldOfView, float aspectRatio, float zNear, float zFar)
Create a perspective projection matrix and store the results in the first parameter.
Definition: Matrix.cpp:96
float angle
Definition: Native.cpp:158
void matrixRotateX(float *matrix, float angle)
Rotates a matrix around the x axis by a given angle.
Definition: Matrix.cpp:104
GLuint createProgram(const char *vertexSource, const char *fragmentSource)
Definition: Native.cpp:104
GLsizei GLenum const void * indices
Definition: gl2ext.h:322
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_assetloading_NativeLibrary_init(JNIEnv *env, jobject obj, jint width, jint height)
Definition: Native.cpp:271
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint loadShader(GLenum shaderType, const char *shaderSource)
Definition: Native.cpp:69
void renderFrame(void)
Definition: Native.cpp:1536
void matrixTranslate(float *matrix, float x, float y, float z)
Takes in a 4 * 4 matrix and translates it by the vector defined by x y and z.
Definition: Matrix.cpp:48
Mesh sphere
Definition: app.cpp:40
GLuint vertexLocation
Definition: Native.cpp:151
GLint GLsizei width
Definition: gl2ext.h:179
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLuint program
Definition: gl2ext.h:1475
std::vector< GLushort > indices
Definition: Native.cpp:42
static const char glFragmentShader[]
Definition: Native.cpp:61
std::vector< GLfloat > vertices
Definition: Native.cpp:41
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
GLuint projectionLocation
Definition: Native.cpp:153
void matrixRotateY(float *matrix, float angle)
Rotates a matrix around the y axis by a given angle.
Definition: Matrix.cpp:116
GLuint glProgram
Definition: Native.cpp:150