OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SpinningCube3D.java
Go to the documentation of this file.
1 /* Copyright (c) 2011-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 package com.arm.malideveloper.openglessdk.spinningcubejava;
22 
23 import java.io.InputStream;
24 import java.nio.FloatBuffer;
25 import java.nio.ShortBuffer;
26 import android.graphics.Bitmap;
27 import android.graphics.BitmapFactory;
28 import android.opengl.GLES20;
29 import android.opengl.GLUtils;
30 import android.opengl.Matrix;
31 import android.content.Context;
32 
37 public class SpinningCube3D {
38 
39  // TODO: Added error checks
40 
42  private Context m_Context;
43 
45  private int m_RotateX = 0;
46  private int m_RotateY = 360;
47 
49  private int m_VertexCount = 23;
50 
52  private int m_IndexCount = 36;
53 
56 
59  private int[] m_VertexAttributeVBO = new int[1];
60 
62  private int[] m_VertexAttributeIBO = new int[1];
63 
65  private int m_ShaderProgramID;
66 
70 
73 
76  private final String m_VertexShaderSource =
77  "uniform mat4 uModelViewProjection;\n" +
78  "attribute vec4 aPosition;\n" +
79  "attribute vec2 aTextureCoordinate;\n" +
80  "varying vec2 vTextureCoordinate;\n" +
81  "void main(){\n" +
82  "gl_Position = uModelViewProjection * aPosition;\n" +
83  "vTextureCoordinate = aTextureCoordinate;\n" +
84  "}\n";
85 
86  private final String m_FragmentShaderSource =
87  "precision mediump float;\n" +
88  "varying vec2 vTextureCoordinate;\n" +
89  "uniform sampler2D sTextureSampler;\n" +
90  "void main(){\n" +
91  "gl_FragColor = texture2D(sTextureSampler, vTextureCoordinate);\n" +
92  "}\n";
93 
95  private float[] m_ModelViewProjectionMatrix = new float[16];
96  private float[] m_ModelingMatrix = new float[16];
97  private float[] m_ModelViewMatrix = new float[16];
98  private float[] m_ProjectionMatrix = new float[16];
99 
101  public SpinningCube3D() {
102  super();
103  }
104 
106  public SpinningCube3D(Context a_Context) {
107  super();
108 
110  this.m_Context = a_Context;
111  }
112 
114  public void createSpinningCube() {
115 
118  GLES20.glEnable(GLES20.GL_CULL_FACE);
119 
121  GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
122 
124  GLES20.glEnable(GLES20.GL_DEPTH_TEST);
125 
128 
130  createTexture();
131 
134 
140  Matrix.setLookAtM(this.m_ModelViewMatrix, 0, 0, 0, -2, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
141 
142  }
143 
145  private void createTexture() {
146 
148  int[] textureIds = new int[1];
149  GLES20.glGenTextures(1, textureIds, 0);
150  this.m_CubeDiffuseTextureId = textureIds[0];
151 
153  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeDiffuseTextureId);
154  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
155  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
156  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
157  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
158 
160  InputStream inputStream = this.m_Context.getResources().openRawResource(R.raw.bubbles);
161  Bitmap bitmapTexture = BitmapFactory.decodeStream(inputStream);
162 
164  GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmapTexture, 0);
165 
167  bitmapTexture.recycle();
168  }
169 
170  private void createShaderProgram() {
171 
173  int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
174 
176  GLES20.glShaderSource(vertexShader, this.m_VertexShaderSource);
177  GLES20.glCompileShader(vertexShader);
178 
180  int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
181 
183  GLES20.glShaderSource(fragmentShader, this.m_FragmentShaderSource);
184  GLES20.glCompileShader(fragmentShader);
185 
187  this.m_ShaderProgramID = GLES20.glCreateProgram();
188 
189  GLES20.glAttachShader(this.m_ShaderProgramID, vertexShader);
190  GLES20.glAttachShader(this.m_ShaderProgramID, fragmentShader);
191 
193  GLES20.glLinkProgram(this.m_ShaderProgramID);
194 
196  this.m_VerticesPositionAttributeId = GLES20.glGetAttribLocation(this.m_ShaderProgramID, "aPosition");
197  if (this.m_VerticesPositionAttributeId == -1) {
198  throw new RuntimeException("aPosition attribute location invalid");
199  }
200 
202  this.m_VerticesTextureAttributeId = GLES20.glGetAttribLocation(this.m_ShaderProgramID, "aTextureCoordinate");
203  if (this.m_VerticesTextureAttributeId == -1) {
204  throw new RuntimeException("aTextureCoordinate attribute location invalid");
205  }
206 
208  this.m_ModelViewProjectionId = GLES20.glGetUniformLocation(this.m_ShaderProgramID, "uModelViewProjection");
209  if (this.m_ModelViewProjectionId == -1) {
210  throw new RuntimeException("uModelViewProjection location invalid");
211  }
212  }
213 
214  public void render() {
215 
216  int floatSize = Float.SIZE >> 3;
218  GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
219 
221  GLES20.glUseProgram(this.m_ShaderProgramID);
222 
224  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
225  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeDiffuseTextureId);
226 
228  GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.m_VertexAttributeVBO[0]);
229  GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_VertexAttributeIBO[0]);
230 
233  GLES20.glVertexAttribPointer(this.m_VerticesPositionAttributeId, 3, GLES20.GL_FLOAT, false, 0, 0);
234  GLES20.glEnableVertexAttribArray(this.m_VerticesPositionAttributeId);
235 
239  GLES20.glVertexAttribPointer(this.m_VerticesTextureAttributeId, 2, GLES20.GL_FLOAT, false, 0 , this.m_VertexCount * 3 * floatSize);
240  GLES20.glEnableVertexAttribArray(this.m_VerticesTextureAttributeId);
241 
243  this.m_RotateX += 2;
244  this.m_RotateY -= 2;
245 
246  if (this.m_RotateX > 360) {
247  this.m_RotateX = 0;
248  }
249  if (this.m_RotateY < 0) {
250  this.m_RotateY = 360;
251  }
252 
253  float[] m_ModelingMatrix1 = new float[16];
254  float[] m_ModelingMatrix2 = new float[16];
255  float[] m_ModelingMatrix3 = new float[16];
256 
258  Matrix.setRotateM(m_ModelingMatrix1, 0, this.m_RotateX, 1.0f, 0.0f, 0.0f);
259  Matrix.setRotateM(m_ModelingMatrix2, 0, this.m_RotateY, 0.0f, 1.0f, 0.0f);
260 
262  Matrix.multiplyMM(m_ModelingMatrix3, 0, m_ModelingMatrix1, 0, m_ModelingMatrix2, 0);
263  Matrix.multiplyMM(this.m_ModelingMatrix, 0, m_ModelViewMatrix, 0, m_ModelingMatrix3, 0);
264 
266  Matrix.multiplyMM(this.m_ModelViewProjectionMatrix, 0, this.m_ProjectionMatrix, 0, this.m_ModelingMatrix, 0);
267 
269  GLES20.glUniformMatrix4fv(this.m_ModelViewProjectionId, 1, false, this.m_ModelViewProjectionMatrix, 0);
270 
272  GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, 0);
273  }
274 
276 
277  int floatSize = Float.SIZE >> 3;
278  int shortSize = Short.SIZE >> 3;
279 
280  float cubeVerticesAttributes[] = new float[] {
282  -0.5f, -0.5f, 0.5f, /* 0 */
283  0.5f, -0.5f, 0.5f, /* 1 */
284  -0.5f, 0.5f, 0.5f, /* 2 */
285  0.5f, 0.5f, 0.5f, /* 3 */
286  -0.5f, -0.5f, -0.5f, /* 4 */
287  0.5f, -0.5f, -0.5f, /* 5 */
288  -0.5f, 0.5f, -0.5f, /* 6 */
289  0.5f, 0.5f, -0.5f, /* 7 */
290  0.5f, -0.5f, 0.5f, /* 8 */
291  0.5f, 0.5f, 0.5f, /* 9 */
292  0.5f, -0.5f, -0.5f, /* 10 */
293  -0.5f, -0.5f, -0.5f, /* 11 */
294  0.5f, 0.5f, -0.5f, /* 12 */
295  -0.5f, 0.5f, -0.5f, /* 13 */
296  -0.5f, 0.5f, -0.5f, /* 14 */
297  -0.5f, -0.5f, 0.5f, /* 15 */
298  -0.5f, 0.5f, 0.5f, /* 16 */
299  -0.5f, 0.5f, 0.5f, /* 17 */
300  0.5f, 0.5f, 0.5f, /* 18 */
301  0.5f, 0.5f, -0.5f, /* 19 */
302  -0.5f, -0.5f, 0.5f, /* 20 */
303  -0.5f, -0.5f, -0.5f, /* 21 */
304  0.5f, -0.5f, 0.5f, /* 22 */
305 
307  0.0f, 0.0f, /* 0 */
308  1.0f, 0.0f, /* 1 */
309  0.0f, 1.0f, /* 2 */
310  1.0f, 1.0f, /* 3 */
311  0.0f, 0.0f, /* 4 */
312  1.0f, 0.0f, /* 5 */
313  0.0f, 1.0f, /* 6 */
314  1.0f, 1.0f, /* 7 */
315  0.0f, 0.0f, /* 8 */
316  0.0f, 1.0f, /* 9 */
317  0.0f, 0.0f, /* 10 */
318  1.0f, 0.0f, /* 11 */
319  0.0f, 1.0f, /* 12 */
320  1.0f, 1.0f, /* 13 */
321  0.0f, 1.0f, /* 14 */
322  1.0f, 0.0f, /* 15 */
323  1.0f, 1.0f, /* 16 */
324  0.0f, 0.0f, /* 17 */
325  1.0f, 0.0f, /* 18 */
326  1.0f, 1.0f, /* 19 */
327  0.0f, 1.0f, /* 20 */
328  0.0f, 0.0f, /* 21 */
329  1.0f, 1.0f, /* 22 */
330 
332  };
333 
334  short cubeTriangleIndices[] = new short[] {
337  0, 1, 2, /* 1 */
339  2, 1, 3, /* 2 */
340 
342  8, 5, 9, /* 3 */
344  9, 5, 7, /* 4 */
345 
347  10, 11, 12, /* 5 */
349  12, 11, 13, /* 6 */
350 
352  14, 4, 15, /* 7 */
354  14, 15, 16, /* 8 */
355 
357  17, 18, 6, /* 9 */
359  6, 18, 19, /* 10 */
360 
362  20, 21, 5, /* 11 */
364  20, 5, 22 /* 12 */
365  };
366 
368  FloatBuffer vertexDataBuffer;
369  ShortBuffer indexDataBuffer;
370 
372  vertexDataBuffer = FloatBuffer.wrap(cubeVerticesAttributes);
373  indexDataBuffer = ShortBuffer.wrap(cubeTriangleIndices);
374 
376  GLES20.glGenBuffers(1, this.m_VertexAttributeVBO, 0);
377  GLES20.glGenBuffers(1, this.m_VertexAttributeIBO, 0);
378 
380  GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.m_VertexAttributeVBO[0]);
381  GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, (this.m_VertexCount * 3 * floatSize) + (this.m_VertexCount * 2 * floatSize) , vertexDataBuffer, GLES20.GL_STATIC_DRAW);
382 
384  GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_VertexAttributeIBO[0]);
385  GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_IndexCount * shortSize , indexDataBuffer, GLES20.GL_STATIC_DRAW);
386  }
387 
388  public void setProjection(int a_Width, int a_Height) {
389 
391  GLES20.glViewport(0, 0, a_Width, a_Height);
392 
394  float aspectRatio = (float) a_Width / (float) a_Height;
395  Matrix.frustumM(this.m_ProjectionMatrix, 0, -aspectRatio, aspectRatio, -1, 1, 1, 10);
396  }
397 }
GLuint textureIds[2]
Definition: Native.cpp:151
GLfloat GLfloat f
Definition: gl2ext.h:2707
precision highp float
Definition: hiz_cull.cs:37