OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RotoZoom.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 
21 
22 #include <GLES2/gl2.h>
23 #include <GLES2/gl2ext.h>
24 
25 #include <cstdio>
26 #include <cstdlib>
27 #include <cmath>
28 #include <string>
29 
30 #include <jni.h>
31 #include <android/log.h>
32 
33 #include "RotoZoom.h"
34 #include "Timer.h"
35 #include "Text.h"
36 #include "Texture.h"
37 #include "Shader.h"
38 #include "Matrix.h"
39 #include "Platform.h"
40 #include "Mathematics.h"
41 
42 using std::string;
43 using namespace MaliSDK;
44 
45 /* Asset directories and filenames. */
46 string resourceDirectory = "/data/data/com.arm.malideveloper.openglessdk.rotozoom/";
47 string textureFilename = "RotoZoom.raw";
48 string vertexShaderFilename = "RotoZoom_cube.vert";
49 string fragmentShaderFilename = "RotoZoom_cube.frag";
50 
51 /* Texture variables. */
53 
54 /* Shader variables. */
56 GLint iLocTextureMatrix = -1;
57 GLint iLocPosition = -1;
58 GLint iLocTextureMix = -1;
59 GLint iLocTexture = -1;
60 GLint iLocTexCoord = -1;
61 
62 /* Animation variables. */
66 
67 int windowWidth = -1;
68 int windowHeight = -1;
69 
70 /* A text object to draw text on the screen. */
72 
73 bool setupGraphics(int width, int height)
74 {
75  /* Height and width of the texture being used. */
76  int textureWidth = 256;
77  int textureHeight = 256;
78 
81 
82  /* Full paths to the shader and texture files */
83  string texturePath = resourceDirectory + textureFilename;
84  string vertexShaderPath = resourceDirectory + vertexShaderFilename;
85  string fragmentShaderPath = resourceDirectory + fragmentShaderFilename;
86 
87  /* Initialize matrices. */
88  /* Make scale matrix to centre texture on screen. */
90  scale = Matrix::createScaling(width / (float)textureWidth, height / (float)textureHeight, 1.0f); /* 2.0 makes it smaller, 0.5 makes it bigger. */
92 
93  /* Initialize OpenGL ES. */
94  GL_CHECK(glEnable(GL_CULL_FACE));
95  GL_CHECK(glCullFace(GL_BACK));
96  GL_CHECK(glEnable(GL_DEPTH_TEST));
97  GL_CHECK(glEnable(GL_BLEND));
98  /* Should do src * (src alpha) + dest * (1-src alpha). */
99  GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
100 
101  /* Initialize the Text object and add some text. */
103  text->addString(0, 0, "Simple RotoZoom Example", 255, 255, 255, 255);
104 
105  /* Load just base level texture data. */
106  GL_CHECK(glGenTextures(1, &textureID));
107  GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureID));
108  unsigned char *textureData = NULL;
109  Texture::loadData(texturePath.c_str(), &textureData);
110 
111  GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData));
112 
113  /* Set texture mode. */
114  GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D));
115  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
116  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); /* Default anyway. */
117  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
118  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
119 
120  /* Process shaders. */
123  Shader::processShader(&vertexShaderID, vertexShaderPath.c_str(), GL_VERTEX_SHADER);
124  Shader::processShader(&fragmentShaderID, fragmentShaderPath.c_str(), GL_FRAGMENT_SHADER);
125 
126  /* Set up shaders. */
127  programID = GL_CHECK(glCreateProgram());
128  GL_CHECK(glAttachShader(programID, vertexShaderID));
129  GL_CHECK(glAttachShader(programID, fragmentShaderID));
130  GL_CHECK(glLinkProgram(programID));
131  GL_CHECK(glUseProgram(programID));
132 
133  /* Vertex positions. */
134  iLocPosition = GL_CHECK(glGetAttribLocation(programID, "a_v4Position"));
135  if(iLocPosition == -1)
136  {
137  LOGE("Attribute not found at %s:%i\n", __FILE__, __LINE__);
138  return false;
139  }
140  GL_CHECK(glEnableVertexAttribArray(iLocPosition));
141 
142  /* Texture. */
143  iLocTexture = GL_CHECK(glGetUniformLocation(programID, "u_s2dTexture"));
144  if(iLocTexture == -1)
145  {
146  LOGD("Warning: Uniform not found at %s:%i\n", __FILE__, __LINE__);
147  }
148  else
149  {
150  GL_CHECK(glUniform1i(iLocTexture, 0));
151  }
152 
153  /* Texture coordinates. */
154  iLocTexCoord = GL_CHECK(glGetAttribLocation(programID, "a_v2TexCoord"));
155  if(iLocTexCoord == -1)
156  {
157  LOGD("Warning: Attribute not found at %s:%i\n", __FILE__, __LINE__);
158  }
159  else
160  {
161  GL_CHECK(glEnableVertexAttribArray(iLocTexCoord));
162  }
163 
164  /* Texture matrix. */
165  iLocTextureMatrix = GL_CHECK(glGetUniformLocation(programID, "u_m4Texture"));
166  if(iLocTextureMatrix == -1)
167  {
168  LOGD("Warning: Uniform not found at %s:%i\n", __FILE__, __LINE__);
169  }
170  else
171  {
172  GL_CHECK(glUniformMatrix4fv(iLocTextureMatrix, 1, GL_FALSE, scale.getAsArray()));
173  }
174 
175  return true;
176 }
177 
178 void renderFrame(void)
179 {
180  static float angleZTexture = 0.0f;
181  static float angleZOffset = 0.0f;
182  static float angleZoom = 0.0f;
183  static Vec4f radius = {0.0f, 1.0f, 0.0f, 1.0f};
184 
185  /* Select our shader program. */
186  GL_CHECK(glUseProgram(programID));
187 
188  /* Set up vertex positions. */
189  GL_CHECK(glEnableVertexAttribArray(iLocPosition));
190  GL_CHECK(glVertexAttribPointer(iLocPosition, 3, GL_FLOAT, GL_FALSE, 0, quadVertices));
191 
192  /* And texture coordinate data. */
193  if(iLocTexCoord != -1)
194  {
195  GL_CHECK(glEnableVertexAttribArray(iLocTexCoord));
196  GL_CHECK(glVertexAttribPointer(iLocTexCoord, 2, GL_FLOAT, GL_FALSE, 0, quadTextureCoordinates));
197  }
198 
199  /* Reset viewport to the EGL window surface's dimensions. */
200  GL_CHECK(glViewport(0, 0, windowWidth, windowHeight));
201 
202  /* Clear the screen on the EGL surface. */
203  GL_CHECK(glClearColor(1.0f, 1.0f, 0.0f, 1.0));
204  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
205 
206  /* Construct a rotation matrix for rotating the texture about its centre. */
207  Matrix rotateTextureZ = Matrix::createRotationZ(angleZTexture);
208 
209  Matrix rotateOffsetZ = Matrix::createRotationZ(angleZOffset);
210 
211  Vec4f offset = Matrix::vertexTransform(&radius, &rotateOffsetZ);
212 
213  /* Construct offset translation. */
214  Matrix translateTexture = Matrix::createTranslation(offset.x, offset.y, offset.z);
215 
216  /* Construct zoom matrix. */
217  Matrix zoom = Matrix::createScaling(sinf(degreesToRadians(angleZoom)) * 0.75f + 1.25f, sinf(degreesToRadians(angleZoom)) * 0.75f + 1.25f, 1.0f);
218 
219  /* Create texture matrix. Operations happen bottom-up order. */
220  Matrix textureMovement = Matrix::identityMatrix * translation; /* Translate texture back to original position. */
221  textureMovement = textureMovement * rotateTextureZ; /* Rotate texture about origin. */
222  textureMovement = textureMovement * translateTexture; /* Translate texture away from origin. */
223  textureMovement = textureMovement * zoom; /* Zoom the texture. */
224  textureMovement = textureMovement * scale; /* Scale texture down in size from fullscreen to 1:1. */
225  textureMovement = textureMovement * negativeTranslation; /* Translate texture to be centred on origin. */
226 
227  GL_CHECK(glUniformMatrix4fv(iLocTextureMatrix, 1, GL_FALSE, textureMovement.getAsArray()));
228 
229  /* Ensure the correct texture is bound to texture unit 0. */
230  GL_CHECK(glActiveTexture(GL_TEXTURE0));
231  GL_CHECK(glBindTexture(GL_TEXTURE_2D, textureID));
232 
233  /* And draw. */
234  GL_CHECK(glDrawElements(GL_TRIANGLE_STRIP, sizeof(quadIndices) / sizeof(GLubyte), GL_UNSIGNED_BYTE, quadIndices));
235 
236  /* Draw any text. */
237  text->draw();
238 
239  /* Update rotation angles for animating. */
240  angleZTexture += 1;
241  angleZOffset += 1;
242  angleZoom += 1;
243 
244  if(angleZTexture >= 360) angleZTexture -= 360;
245  if(angleZTexture < 0) angleZTexture += 360;
246 
247  if(angleZOffset >= 360) angleZOffset -= 360;
248  if(angleZOffset < 0) angleZOffset += 360;
249 
250  if(angleZoom >= 360) angleZoom -= 360;
251  if(angleZoom < 0) angleZoom += 360;
252 }
253 
254 extern "C"
255 {
257  (JNIEnv *env, jclass jcls, jint width, jint height)
258  {
259  /* Make sure that all resource files are in place. */
263 
264  setupGraphics(width, height);
265  }
266 
268  (JNIEnv *env, jclass jcls)
269  {
270  renderFrame();
271  }
272 
274  (JNIEnv *, jclass)
275  {
276  delete text;
277  }
278 }
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_rotozoom_RotoZoom_step(JNIEnv *env, jclass jcls)
Definition: RotoZoom.cpp:268
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_rotozoom_RotoZoom_uninit(JNIEnv *, jclass)
Definition: RotoZoom.cpp:274
string resourceDirectory
Definition: RotoZoom.cpp:46
static const float quadVertices[]
Definition: IntegerLogic.h:96
Functions for drawing text in OpenGL ES.
Definition: Text.h:44
void renderFrame(void)
Definition: RotoZoom.cpp:178
int windowHeight
Definition: RotoZoom.cpp:68
static Matrix identityMatrix
The identity matrix.
Definition: Matrix.h:90
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLenum GLuint GLintptr offset
Definition: gl2ext.h:629
Functions for manipulating matrices.
Definition: Matrix.h:31
GLuint fragmentShaderID
static Matrix createTranslation(float x, float y, float z)
Create and return a translation matrix.
Definition: Matrix.cpp:414
#define LOGD(...)
Definition: AstcTextures.h:28
static Matrix createScaling(float x, float y, float z)
Create and return a scaling matrix.
Definition: Matrix.cpp:403
string fragmentShaderFilename
Definition: RotoZoom.cpp:49
int windowWidth
Definition: RotoZoom.cpp:67
float * getAsArray(void)
Get the matrix elements as a column major order array.
Definition: Matrix.cpp:78
GLint iLocTextureMix
Definition: RotoZoom.cpp:58
GLuint textureID
Definition: RotoZoom.cpp:52
string textureFilename
Definition: RotoZoom.cpp:47
static float zoom
Definition: app.cpp:82
GLuint programID
Definition: RotoZoom.cpp:55
Text * text
Definition: RotoZoom.cpp:71
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_rotozoom_RotoZoom_init(JNIEnv *env, jclass jcls, jint width, jint height)
Definition: RotoZoom.cpp:257
const GLint textureHeight
Definition: Native.cpp:78
GLfloat GLfloat f
Definition: gl2ext.h:2707
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
#define GL_CHECK(x)
Definition: AstcTextures.h:59
static Vec4f vertexTransform(Vec4f *vector, Matrix *matrix)
Transform a 4D vertex by a matrix.
Definition: Matrix.cpp:559
Matrix scale
Definition: RotoZoom.cpp:64
const GLint textureWidth
Definition: Native.cpp:77
unsigned char * textureData
Definition: ThreadSync.cpp:109
static Matrix createRotationZ(float angle)
Create and return a rotation matrix around the z-axis matrix.
Definition: Matrix.cpp:523
static void loadData(const char *filename, unsigned char **textureData)
Load texture data from a file into memory.
Definition: Texture.cpp:167
static bool getAndroidAsset(JNIEnv *JNIEnvironment, const char destinationDirectory[], const char filename[])
Extract an asset file from the APK.
float degreesToRadians(float degrees)
Convert an angle in degrees to radians.
Definition: Mathematics.h:86
Matrix negativeTranslation
Definition: RotoZoom.cpp:65
static const float quadTextureCoordinates[]
Definition: IntegerLogic.h:112
string vertexShaderFilename
Definition: RotoZoom.cpp:48
bool setupGraphics(int width, int height)
Definition: RotoZoom.cpp:73
GLint iLocTexture
Definition: RotoZoom.cpp:59
GLuint vertexShaderID
#define LOGE(...)
Definition: AstcTextures.h:30
GLint GLsizei width
Definition: gl2ext.h:179
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
GLint iLocTextureMatrix
Definition: RotoZoom.cpp:56
GLint iLocTexCoord
Definition: RotoZoom.cpp:60
void draw(void)
Draw the text to the screen.
Definition: Text.cpp:265
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
A 4D floating point vector.
Definition: VectorTypes.h:127
GLint iLocPosition
Definition: RotoZoom.cpp:57
Matrix translation
Definition: RotoZoom.cpp:63
static const GLubyte quadIndices[]
Definition: RotoZoom.h:29