1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include "circle.h"
19 #include "common.h"
20 #include "shader.h"
21 
22 #include <cstdlib>
23 #include <math.h>
24 
25 namespace android {
26 namespace gamecore {
27 
28 namespace {
29 
initializeVertices(int numSegments)30 GLfloat* initializeVertices(int numSegments) {
31     GLfloat* vertices = new GLfloat[2 * (numSegments + 2)];
32     vertices[0] = 0.0f;
33     vertices[1] = 0.0f;
34 
35     float dTheta = static_cast<float>(2 * M_PI / numSegments);
36     for (int i = 0; i < numSegments + 1; i++) {
37         vertices[(i + 1) * 2] = cos(dTheta * i);
38         vertices[(i + 1) * 2 + 1] = sin(dTheta * i);
39     }
40     return vertices;
41 }
42 
43 int const NUM_SEGMENTS = 36;
44 GLfloat* gVertices = initializeVertices(NUM_SEGMENTS);
45 
46 auto const gVertexShader =
47         "uniform highp float uRadius;\n"
48         "uniform highp mat4 uMvpMatrix;\n"
49         "attribute vec4 vPosition;\n"
50         "void main() {\n"
51         "  gl_Position = uMvpMatrix * (vPosition * vec4(vec3(uRadius), 1.0));"
52         "}\n";
53 
54 auto const gFragmentShader =
55         "uniform lowp vec3 uColor;\n"
56         "void main() {\n"
57         "  gl_FragColor = vec4(uColor, 1.0);\n"
58         "}\n";
59 
60 } // end of anonymous namespace
61 
Circle(float radius)62 Circle::Circle(float radius) {
63     mRadius = radius;
64     mProgram = createProgram(gVertexShader, gFragmentShader);
65     mMvpMatrixHandle = glGetUniformLocation(mProgram, "uMvpMatrix");
66     mRadiusHandle = glGetUniformLocation(mProgram, "uRadius");
67     mVPositionHandle = glGetAttribLocation(mProgram, "vPosition");
68     mColorHandle = glGetUniformLocation(mProgram, "uColor");
69     checkGlError("glGetAttribLocation");
70     LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
71          mVPositionHandle);
72 
73     setColor(0.0f, 1.0f, 0.0f);
74 }
75 
draw() const76 void Circle::draw() const {
77     Mat4 mvpMatrix = mViewProjectionMatrix * Mat4::Translation(mPosition);
78     glUseProgram(mProgram);
79     checkGlError("glUseProgram");
80 
81     glUniform3fv(mColorHandle, 1, mColor);
82     checkGlError("glUniform3fv");
83     glUniform1f(mRadiusHandle, mRadius);
84     checkGlError("glUniform1f");
85     glVertexAttribPointer(mVPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gVertices);
86     checkGlError("glVertexAttribPointer");
87     glUniformMatrix4fv(mMvpMatrixHandle, 1, GL_FALSE, mvpMatrix.Ptr());
88     checkGlError("glUniformMatrix4fv");
89     glEnableVertexAttribArray(mVPositionHandle);
90     checkGlError("glEnableVertexAttribArray");
91     glDrawArrays(GL_TRIANGLE_FAN, 0, NUM_SEGMENTS + 2);
92     checkGlError("glDrawArrays");
93 }
94 
setColor(float r,float g,float b)95 void Circle::setColor(float r, float g, float b) {
96     mColor[0] = r;
97     mColor[1] = g;
98     mColor[2] = b;
99 }
100 
getPosition() const101 const Vec3& Circle::getPosition() const {
102     return mPosition;
103 }
104 
setPosition(const Vec3 & position)105 void Circle::setPosition(const Vec3& position) {
106     mPosition = position;
107 }
108 
updateViewProjection(const Mat4 & vpMatrix)109 void Circle::updateViewProjection(const Mat4& vpMatrix) {
110     mViewProjectionMatrix = vpMatrix;
111 }
112 
113 } // end of namespace gamecore
114 } // end of namespace android
115 
116