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) 2013-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.rendertotexturejava;
22 
23 import java.io.InputStream;
24 import java.nio.FloatBuffer;
25 import java.nio.ShortBuffer;
26 
27 import android.graphics.Bitmap;
28 import android.graphics.BitmapFactory;
29 import android.opengl.GLES20;
30 import android.opengl.GLUtils;
31 import android.opengl.Matrix;
32 import android.content.Context;
33 
38 public class SpinningCube3D {
39 
40  // TODO: Added error checks
41 
43  private Context m_Context;
44 
46  private int m_RotateX = 0;
47  private int m_RotateY = 360;
48 
50  private int m_VertexCount = 23;
51 
53  private int m_IndexCount = 36;
54 
57 
59  private int m_CubeFBOTextureId;
60 
61 
64  private int[] m_RenderToTextureFBO = new int[1];
65 
67  private int[] m_VertexAttributeVBO = new int[1];
68 
70  private int[] m_VertexAttributeIBO = new int[1];
71 
73  private int m_ShaderProgramID;
74 
78 
81 
84  private final String m_VertexShaderSource =
85  "uniform mat4 uModelViewProjection;\n" +
86  "attribute vec4 aPosition;\n" +
87  "attribute vec2 aTextureCoordinate;\n" +
88  "varying vec2 vTextureCoordinate;\n" +
89  "void main(){\n" +
90  "gl_Position = uModelViewProjection * aPosition;\n" +
91  "vTextureCoordinate = aTextureCoordinate;\n" +
92  "}\n";
93 
94  private final String m_FragmentShaderSource =
95  "precision mediump float;\n" +
96  "varying vec2 vTextureCoordinate;\n" +
97  "uniform sampler2D sTextureSampler;\n" +
98  "void main(){\n" +
99  "gl_FragColor = texture2D(sTextureSampler, vTextureCoordinate);\n" +
100  "}\n";
101 
103  private float[] m_ModelViewProjectionMatrix = new float[16];
104  private float[] m_ModelingMatrix = new float[16];
105  private float[] m_ModelViewMatrix = new float[16];
106  private float[] m_ProjectionMatrix = new float[16];
107 
109  private int m_Width;
110  private int m_Height;
111 
113  private int m_FBOWidth = 256;
114  private int m_FBOHeight = 256;
115 
117  public SpinningCube3D() {
118  super();
119  }
120 
122  public SpinningCube3D(Context a_Context) {
123  super();
124 
126  this.m_Context = a_Context;
127  }
128 
130  public void createSpinningCube() {
131 
134  GLES20.glEnable(GLES20.GL_CULL_FACE);
135 
137  GLES20.glEnable(GLES20.GL_DEPTH_TEST);
138 
141 
143  createTexture();
144 
147 
153  Matrix.setLookAtM(this.m_ModelViewMatrix, 0, 0, 0, -2, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
154  }
155 
157  private void createTexture() {
158 
160  int[] textureIds = new int[1];
161  GLES20.glGenTextures(1, textureIds, 0);
162  this.m_CubeDiffuseTextureId = textureIds[0];
163 
165  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeDiffuseTextureId);
166  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
167  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
168  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
169  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
170 
172  InputStream inputStream = this.m_Context.getResources().openRawResource(R.raw.bubbles);
173  Bitmap bitmapTexture = BitmapFactory.decodeStream(inputStream);
174 
176  GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmapTexture, 0);
177 
179  bitmapTexture.recycle();
180  }
181 
182  private void createShaderProgram() {
183 
185  int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
186 
188  GLES20.glShaderSource(vertexShader, this.m_VertexShaderSource);
189  GLES20.glCompileShader(vertexShader);
190 
192  int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
193 
195  GLES20.glShaderSource(fragmentShader, this.m_FragmentShaderSource);
196  GLES20.glCompileShader(fragmentShader);
197 
199  this.m_ShaderProgramID = GLES20.glCreateProgram();
200 
201  GLES20.glAttachShader(this.m_ShaderProgramID, vertexShader);
202  GLES20.glAttachShader(this.m_ShaderProgramID, fragmentShader);
203 
205  GLES20.glLinkProgram(this.m_ShaderProgramID);
206 
208  this.m_VerticesPositionAttributeId = GLES20.glGetAttribLocation(this.m_ShaderProgramID, "aPosition");
209  if (this.m_VerticesPositionAttributeId == -1) {
210  throw new RuntimeException("aPosition attribute location invalid");
211  }
212 
214  this.m_VerticesTextureAttributeId = GLES20.glGetAttribLocation(this.m_ShaderProgramID, "aTextureCoordinate");
215  if (this.m_VerticesTextureAttributeId == -1) {
216  throw new RuntimeException("aTextureCoordinate attribute location invalid");
217  }
218 
220  this.m_ModelViewProjectionId = GLES20.glGetUniformLocation(this.m_ShaderProgramID, "uModelViewProjection");
221  if (this.m_ModelViewProjectionId == -1) {
222  throw new RuntimeException("uModelViewProjection location invalid");
223  }
224  }
225 
226  public void render() {
227 
230  int floatSize = Float.SIZE >> 3;
231 
233  GLES20.glUseProgram(this.m_ShaderProgramID);
234 
236  GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.m_VertexAttributeVBO[0]);
237  GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_VertexAttributeIBO[0]);
238 
241  GLES20.glVertexAttribPointer(this.m_VerticesPositionAttributeId, 3, GLES20.GL_FLOAT, false, 0, 0);
242  GLES20.glEnableVertexAttribArray(this.m_VerticesPositionAttributeId);
243 
247  GLES20.glVertexAttribPointer(this.m_VerticesTextureAttributeId, 2, GLES20.GL_FLOAT, false, 0 , this.m_VertexCount * 3 * floatSize);
248  GLES20.glEnableVertexAttribArray(this.m_VerticesTextureAttributeId);
249 
251  this.m_RotateX += 2;
252  this.m_RotateY -= 2;
253 
254  if (this.m_RotateX > 360) {
255  this.m_RotateX = 0;
256  }
257  if (this.m_RotateY < 0) {
258  this.m_RotateY = 360;
259  }
260 
261  float[] m_ModelingMatrix1 = new float[16];
262  float[] m_ModelingMatrix2 = new float[16];
263  float[] m_ModelingMatrix3 = new float[16];
264 
266  Matrix.setRotateM(m_ModelingMatrix1, 0, this.m_RotateX, 1.0f, 0.0f, 0.0f);
267  Matrix.setRotateM(m_ModelingMatrix2, 0, this.m_RotateY, 0.0f, 1.0f, 0.0f);
268 
270  Matrix.multiplyMM(m_ModelingMatrix3, 0, m_ModelingMatrix1, 0, m_ModelingMatrix2, 0);
271  Matrix.multiplyMM(this.m_ModelingMatrix, 0, m_ModelViewMatrix, 0, m_ModelingMatrix3, 0);
272 
274  this.setProjection(this.m_FBOWidth, this.m_FBOHeight);
275 
277  Matrix.multiplyMM(this.m_ModelViewProjectionMatrix, 0, this.m_ProjectionMatrix, 0, this.m_ModelingMatrix, 0);
278 
280  GLES20.glUniformMatrix4fv(this.m_ModelViewProjectionId, 1, false, this.m_ModelViewProjectionMatrix, 0);
281 
283  GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
284 
286  GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, this.m_RenderToTextureFBO[0]);
287 
289  GLES20.glClearColor(1.0f, 0.5f, 0.0f, 1.0f);
290  GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
291 
293  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeDiffuseTextureId);
294 
296  GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, 0);
297 
299  GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
300 
302  GLES20.glClearColor(0.0f, 0.2f, 0.3f, 1.0f);
303  GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
304 
306  this.setProjection(this.m_Width, this.m_Height);
307 
309  Matrix.multiplyMM(this.m_ModelViewProjectionMatrix, 0, this.m_ProjectionMatrix, 0, this.m_ModelingMatrix, 0);
310 
312  GLES20.glUniformMatrix4fv(this.m_ModelViewProjectionId, 1, false, this.m_ModelViewProjectionMatrix, 0);
313 
315  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeFBOTextureId);
316 
318  GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, 0);
319  }
320 
322 
323  int floatSize = Float.SIZE >> 3;
324  int shortSize = Short.SIZE >> 3;
325 
326  float cubeVerticesAttributes[] = new float[] {
328  -0.5f, -0.5f, 0.5f, /* 0 */
329  0.5f, -0.5f, 0.5f, /* 1 */
330  -0.5f, 0.5f, 0.5f, /* 2 */
331  0.5f, 0.5f, 0.5f, /* 3 */
332  -0.5f, -0.5f, -0.5f, /* 4 */
333  0.5f, -0.5f, -0.5f, /* 5 */
334  -0.5f, 0.5f, -0.5f, /* 6 */
335  0.5f, 0.5f, -0.5f, /* 7 */
336  0.5f, -0.5f, 0.5f, /* 8 */
337  0.5f, 0.5f, 0.5f, /* 9 */
338  0.5f, -0.5f, -0.5f, /* 10 */
339  -0.5f, -0.5f, -0.5f, /* 11 */
340  0.5f, 0.5f, -0.5f, /* 12 */
341  -0.5f, 0.5f, -0.5f, /* 13 */
342  -0.5f, 0.5f, -0.5f, /* 14 */
343  -0.5f, -0.5f, 0.5f, /* 15 */
344  -0.5f, 0.5f, 0.5f, /* 16 */
345  -0.5f, 0.5f, 0.5f, /* 17 */
346  0.5f, 0.5f, 0.5f, /* 18 */
347  0.5f, 0.5f, -0.5f, /* 19 */
348  -0.5f, -0.5f, 0.5f, /* 20 */
349  -0.5f, -0.5f, -0.5f, /* 21 */
350  0.5f, -0.5f, 0.5f, /* 22 */
351 
353  0.0f, 0.0f, /* 0 */
354  1.0f, 0.0f, /* 1 */
355  0.0f, 1.0f, /* 2 */
356  1.0f, 1.0f, /* 3 */
357  0.0f, 0.0f, /* 4 */
358  1.0f, 0.0f, /* 5 */
359  0.0f, 1.0f, /* 6 */
360  1.0f, 1.0f, /* 7 */
361  0.0f, 0.0f, /* 8 */
362  0.0f, 1.0f, /* 9 */
363  0.0f, 0.0f, /* 10 */
364  1.0f, 0.0f, /* 11 */
365  0.0f, 1.0f, /* 12 */
366  1.0f, 1.0f, /* 13 */
367  0.0f, 1.0f, /* 14 */
368  1.0f, 0.0f, /* 15 */
369  1.0f, 1.0f, /* 16 */
370  0.0f, 0.0f, /* 17 */
371  1.0f, 0.0f, /* 18 */
372  1.0f, 1.0f, /* 19 */
373  0.0f, 1.0f, /* 20 */
374  0.0f, 0.0f, /* 21 */
375  1.0f, 1.0f, /* 22 */
376 
378  };
379 
380  short cubeTriangleIndices[] = new short[] {
383  0, 1, 2, /* 1 */
385  2, 1, 3, /* 2 */
386 
388  8, 5, 9, /* 3 */
390  9, 5, 7, /* 4 */
391 
393  10, 11, 12, /* 5 */
395  12, 11, 13, /* 6 */
396 
398  14, 4, 15, /* 7 */
400  14, 15, 16, /* 8 */
401 
403  17, 18, 6, /* 9 */
405  6, 18, 19, /* 10 */
406 
408  20, 21, 5, /* 11 */
410  20, 5, 22 /* 12 */
411  };
412 
414  FloatBuffer vertexDataBuffer;
415  ShortBuffer indexDataBuffer;
416 
418  vertexDataBuffer = FloatBuffer.wrap(cubeVerticesAttributes);
419  indexDataBuffer = ShortBuffer.wrap(cubeTriangleIndices);
420 
422  GLES20.glGenBuffers(1, this.m_VertexAttributeVBO, 0);
423  GLES20.glGenBuffers(1, this.m_VertexAttributeIBO, 0);
424 
426  GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.m_VertexAttributeVBO[0]);
427  GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, (this.m_VertexCount * 3 * floatSize) + (this.m_VertexCount * 2 * floatSize) , vertexDataBuffer, GLES20.GL_STATIC_DRAW);
428 
430  GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_VertexAttributeIBO[0]);
431  GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.m_IndexCount * shortSize , indexDataBuffer, GLES20.GL_STATIC_DRAW);
432 
434  int[] textureIds = new int[1];
435  GLES20.glGenTextures(1, textureIds, 0);
436  this.m_CubeFBOTextureId = textureIds[0];
437 
439  GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.m_CubeFBOTextureId);
440  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
441  GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
442  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
443  GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
444  GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, this.m_FBOWidth, this.m_FBOHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
445 
448  GLES20.glGenFramebuffers(1, this.m_RenderToTextureFBO, 0);
449 
451  GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, this.m_RenderToTextureFBO[0]);
452 
454  GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, this.m_CubeFBOTextureId, 0);
455 
457  int iResult = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
458  if(iResult != GLES20.GL_FRAMEBUFFER_COMPLETE)
459  {
460  throw new RuntimeException("Error: Frame Buffer Status is not complete. Terminated.");
461  }
462 
464  GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
465  }
466 
467  public void setWidthHeight(int a_Width, int a_Height){
468  this.m_Width = a_Width;
469  this.m_Height = a_Height;
470  }
471 
472  public void setProjection(int a_Width, int a_Height) {
473 
475  GLES20.glViewport(0, 0, a_Width, a_Height);
476 
478  float aspectRatio = (float) a_Width / (float) a_Height;
479  Matrix.frustumM(this.m_ProjectionMatrix, 0, -aspectRatio, aspectRatio, -1, 1, 1, 10);
480  }
481 }
GLuint textureIds[2]
Definition: Native.cpp:151
GLfloat GLfloat f
Definition: gl2ext.h:2707
precision highp float
Definition: hiz_cull.cs:37