OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
InstancedSolidTorus.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 #include "Common.h"
22 #include "InstancedSolidTorus.h"
23 #include "Mathematics.h"
24 #include "Matrix.h"
25 #include "Shader.h"
26 #include "TorusModel.h"
27 
28 #include <GLES3/gl3.h>
29 #include <GLES3/gl3ext.h>
30 
31 #include <cmath>
32 #include <string>
33 
34 using namespace MaliSDK;
35 using std::string;
36 
37 InstancedSolidTorus::InstancedSolidTorus(float torusRadius, float circleRadius)
38 {
39  /* Initialize class fields. */
40  this->torusRadius = torusRadius;
41  this->circleRadius = circleRadius;
42 
43  /* Name of the file in which fragment shader's body is located. */
44  const string fragmentShaderPath = resourceDirectory + "Instanced_Tessellation_Instanced_shader.frag";
45 
46  /* Name of the file in which vertex shader's body is located. */
47  const string vertexShaderPath = resourceDirectory + "Instanced_Tessellation_Instanced_shader.vert";
48 
49  /* Initialize OpenGL components. */
50  setupGraphics(vertexShaderPath, fragmentShaderPath);
51 
52  /* Create control mesh and initialize uniform buffers corresponding to it. */
53  initializeControlUniformBuffers();
54  /* Create patch data and initialize vertex attribs corresponding to it. */
55  initializeVertexAttribs();
56 
57  /* Set torus color to green. */
58  setColor(0.0f, 0.7f, 0.0f, 1.0f);
59 
60  /* Configure light parameters. */
61  setLightParameters();
62 }
63 
65 {
66  GLuint buffersArray[] = {controlIndicesBufferID, controlVerticesBufferID, patchIndicesBufferID, patchVertexBufferID};
67  GLint buffersArraySize = sizeof(buffersArray) / sizeof(buffersArray[0]);
68 
69  /* Delete all buffers corresponding to this class. */
70  GL_CHECK(glDeleteBuffers(buffersArraySize, &controlIndicesBufferID));
71 }
72 
73 /* [Draw solid torus] */
74 void InstancedSolidTorus::draw(float* rotationVector)
75 {
76  /* Location of rotation vector. */
77  GLint rotationVectorLocation = GL_CHECK(glGetUniformLocation(programID, "rotationVector"));
78 
79  /* Set required OpenGL ES state. */
80  GL_CHECK(glUseProgram (programID ));
81  GL_CHECK(glBindVertexArray(vaoID ));
82  GL_CHECK(glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, patchIndicesBufferID));
83 
84  if (rotationVectorLocation != -1)
85  {
86  /* Pass rotation parameters to the shader. */
87  GL_CHECK(glUniform3fv(rotationVectorLocation, 1, rotationVector));
88  }
89  else
90  {
91  LOGE("Could not locate \"rotationVector\" uniform in program [%d]", programID);
92  }
93 
94  /* Draw patchInstancesCount instances of patchTriangleIndicesCount triangles. */
95  GL_CHECK(glDrawElementsInstanced(GL_TRIANGLES, patchTriangleIndicesCount, GL_UNSIGNED_INT, 0, patchInstancesCount));
96 }
97 /* [Draw solid torus] */
98 
100 {
101  float torusVertices [componentsCount];
102  unsigned int controlPointsIndices[controlPointsIndicesCount];
103 
104  /* Generate torus vertices which can be used to construct Bezier surfaces. */
105  TorusModel::generateBezierVertices(torusRadius, circleRadius, torusVertices);
106  /* Calculate the indices that will divide generated torus vertices into patches. */
107  TorusModel::calculateControlPointsIndices(patchDimension, patchInstancesCount, controlPointsIndicesCount, controlPointsIndices);
108 
109  GLuint controlIndicesBlockIndex = GL_CHECK(glGetUniformBlockIndex(programID, "ControlPointsIndices"));
110 
111  if (controlIndicesBlockIndex != GL_INVALID_INDEX)
112  {
113  /* Pass control points indices to corresponding uniform block. */
114  GL_CHECK(glGenBuffers (1, &controlIndicesBufferID ));
115  GL_CHECK(glBindBuffer (GL_UNIFORM_BUFFER, controlIndicesBufferID ));
116  GL_CHECK(glBufferData (GL_UNIFORM_BUFFER, sizeof(controlPointsIndices), controlPointsIndices, GL_STATIC_DRAW));
117  GL_CHECK(glUniformBlockBinding(programID, controlIndicesBlockIndex, 0 ));
118  GL_CHECK(glBindBufferBase (GL_UNIFORM_BUFFER, 0, controlIndicesBufferID ));
119  }
120  else
121  {
122  LOGE("Could not locate \"ControlPointsIndices\" uniform block in program [%d].", programID);
123  }
124 
125  GLuint controlVerticesBlockIndex = GL_CHECK(glGetUniformBlockIndex(programID, "ControlPointsVertices"));
126 
127  if (controlVerticesBlockIndex != GL_INVALID_INDEX)
128  {
129  /* Pass control points vertices to corresponding uniform block. */
130  GL_CHECK(glGenBuffers (1, &controlVerticesBufferID ));
131  GL_CHECK(glBindBuffer (GL_UNIFORM_BUFFER, controlVerticesBufferID ));
132  GL_CHECK(glBufferData (GL_UNIFORM_BUFFER, componentsCount * sizeof(float), torusVertices, GL_STATIC_DRAW));
133  GL_CHECK(glUniformBlockBinding(programID, controlVerticesBlockIndex, 1 ));
134  GL_CHECK(glBindBufferBase (GL_UNIFORM_BUFFER, 1, controlVerticesBufferID ));
135  }
136  else
137  {
138  LOGE("Could not locate \"ControlPointsVertices\" uniform block in program [%d].", programID);
139  }
140 
141  return true;
142 }
143 
145 {
146  /* Find input attribute location. */
147  GLint positionLocation = GL_CHECK(glGetAttribLocation(programID, "patchUVPosition"));
148 
149  float patchVertices [patchComponentsCount];
150  unsigned int patchTriangleIndices[patchTriangleIndicesCount];
151 
152  /* Determine input data. */
153  TorusModel::calculatePatchData(patchDensity, patchVertices, patchTriangleIndices);
154 
155  /* Generate corresponding vertex array object. */
156  GL_CHECK(glGenVertexArrays(1, &vaoID));
157  GL_CHECK(glBindVertexArray(vaoID));
158 
159  if (positionLocation != -1)
160  {
161  /* Generate a buffer for input attribute data. */
162  GL_CHECK(glGenBuffers(1, &patchVertexBufferID));
163  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, patchVertexBufferID ));
164  /* Put data to the buffer. */
165  GL_CHECK(glBufferData(GL_ARRAY_BUFFER, patchComponentsCount * sizeof(float), patchVertices, GL_STATIC_DRAW));
166  /* Set vertex attribute pointer to the beginning of the buffer. */
167  GL_CHECK(glVertexAttribPointer (positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL));
168  GL_CHECK(glEnableVertexAttribArray(positionLocation ));
169  }
170  else
171  {
172  LOGE("Could not locate \"patchUVposition\" input attribute in program [%d].", programID);
173  return false;
174  }
175 
176  /* Generate a buffer for indices used in DrawElements*() call. */
177  GL_CHECK(glGenBuffers(1, &patchIndicesBufferID ));
178  GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndicesBufferID ));
179  /* Put data to the buffer. */
180  GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, patchTriangleIndicesCount * sizeof(unsigned int), patchTriangleIndices, GL_STATIC_DRAW));
181 
182  return true;
183 }
184 
186 {
187  /* Light angle equal to 30 degrees. */
188  const float lightAngle = M_PI / 6.0f;
189  /* White ligth color. */
190  const float lightColor[] = {1.0f, 1.0f, 1.0f};
191  /* Direction of the light vector. */
192  const float lightDirection[] = {cosf(lightAngle), sinf(lightAngle), 2.0f};
193  /* Value of ambient intensity. */
194  const float ambientIntensity = 0.2f;
195 
196  /* Find light parameters locations. */
197  GLint lightColorLocation = GL_CHECK(glGetUniformLocation(programID, "light.lightColor"));
198  GLint lightDirectionLocation = GL_CHECK(glGetUniformLocation(programID, "light.lightDirection"));
199  GLint ambientIntensityLocation = GL_CHECK(glGetUniformLocation(programID, "light.ambientIntensity"));
200 
201  GL_CHECK(glUseProgram(programID));
202 
203  /* Pass light parameter data. */
204  if (lightColorLocation != -1)
205  {
206  GL_CHECK(glUniform3fv(lightColorLocation, 1, lightColor));
207  }
208  else
209  {
210  LOGE("Could not find \"light.lightColor\" uniform in program [%d]", programID);
211  }
212 
213  if (lightDirectionLocation != -1)
214  {
215  GL_CHECK(glUniform3fv(lightDirectionLocation, 1, lightDirection));
216  }
217  else
218  {
219  LOGE("Could not find \"light.lightDirection\" uniform in program [%d]", programID);
220  }
221 
222  if (ambientIntensityLocation != -1)
223  {
224  GL_CHECK(glUniform1f(ambientIntensityLocation, ambientIntensity));
225  }
226  else
227  {
228  LOGE("Could not find \"light.ambientIntensity\" uniform in program [%d]", programID);
229  }
230 }
static void calculateControlPointsIndices(unsigned int patchDimension, unsigned int patchInstancesCount, unsigned int controlPointsIndicesCount, unsigned int *controlPointsIndices)
Determines an array of indices defining a mesh of control points for instanced torus patches...
Definition: TorusModel.cpp:58
GLint positionLocation
Definition: Native.cpp:99
static void generateBezierVertices(float torusRadius, float circleRadius, float *vertices)
Generate torus vertices applying distortions to some of them.
Definition: TorusModel.cpp:315
GLuint vaoID
Definition: Native.cpp:98
void draw(float *rotationVector)
Draws instanced solid torus.
bool setupGraphics(int width, int height)
Definition: AntiAlias.cpp:71
Mathematic functions.
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint programID
Definition: AntiAlias.cpp:60
~InstancedSolidTorus(void)
Frees allocated memory.
#define M_PI
The value of pi.
Definition: Mathematics.h:37
#define GL_CHECK(x)
Definition: AstcTextures.h:59
string resourceDirectory
Definition: AntiAlias.cpp:55
GLint rotationVectorLocation
Definition: Native.cpp:102
#define LOGE(...)
Definition: AstcTextures.h:30
static void calculatePatchData(unsigned int patchDensity, float *patchVertices, unsigned int *patchTriangleIndices)
Determines patch data for an instanced torus model.
Definition: TorusModel.cpp:125
bool initializeVertexAttribs(void)
Initialize vertex attribute arrays and buffer objects coresponding to them. Make sure that programID ...
InstancedSolidTorus(float torusRadius, float circleRadius)
Instantiates a representation of a solid torus, using user-provided radius and tube radius...
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
bool initializeControlUniformBuffers(void)
Initializes control mesh data and stores it in appropriate uniform buffers.
void setLightParameters(void)
Sets directionl light parameters, such as light direction, its color and ambient intensity and passes...