blob: c2b72d99b0240af13c1e0badfe18903fbdda236a [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "circle.h"
#include "common.h"
#include "shader.h"
#include <cstdlib>
#include <math.h>
namespace android {
namespace gamecore {
namespace {
GLfloat* initializeVertices(int numSegments) {
GLfloat* vertices = new GLfloat[2 * (numSegments + 2)];
vertices[0] = 0.0f;
vertices[1] = 0.0f;
float dTheta = static_cast<float>(2 * M_PI / numSegments);
for (int i = 0; i < numSegments + 1; i++) {
vertices[(i + 1) * 2] = cos(dTheta * i);
vertices[(i + 1) * 2 + 1] = sin(dTheta * i);
}
return vertices;
}
int const NUM_SEGMENTS = 36;
GLfloat* gVertices = initializeVertices(NUM_SEGMENTS);
auto const gVertexShader =
"uniform highp float uRadius;\n"
"uniform highp mat4 uMvpMatrix;\n"
"attribute vec4 vPosition;\n"
"void main() {\n"
" gl_Position = uMvpMatrix * (vPosition * vec4(vec3(uRadius), 1.0));"
"}\n";
auto const gFragmentShader =
"uniform lowp vec3 uColor;\n"
"void main() {\n"
" gl_FragColor = vec4(uColor, 1.0);\n"
"}\n";
} // end of anonymous namespace
Circle::Circle(float radius) {
mRadius = radius;
mProgram = createProgram(gVertexShader, gFragmentShader);
mMvpMatrixHandle = glGetUniformLocation(mProgram, "uMvpMatrix");
mRadiusHandle = glGetUniformLocation(mProgram, "uRadius");
mVPositionHandle = glGetAttribLocation(mProgram, "vPosition");
mColorHandle = glGetUniformLocation(mProgram, "uColor");
checkGlError("glGetAttribLocation");
LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
mVPositionHandle);
setColor(0.0f, 1.0f, 0.0f);
}
void Circle::draw() const {
Mat4 mvpMatrix = mViewProjectionMatrix * Mat4::Translation(mPosition);
glUseProgram(mProgram);
checkGlError("glUseProgram");
glUniform3fv(mColorHandle, 1, mColor);
checkGlError("glUniform3fv");
glUniform1f(mRadiusHandle, mRadius);
checkGlError("glUniform1f");
glVertexAttribPointer(mVPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gVertices);
checkGlError("glVertexAttribPointer");
glUniformMatrix4fv(mMvpMatrixHandle, 1, GL_FALSE, mvpMatrix.Ptr());
checkGlError("glUniformMatrix4fv");
glEnableVertexAttribArray(mVPositionHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLE_FAN, 0, NUM_SEGMENTS + 2);
checkGlError("glDrawArrays");
}
void Circle::setColor(float r, float g, float b) {
mColor[0] = r;
mColor[1] = g;
mColor[2] = b;
}
const Vec3& Circle::getPosition() const {
return mPosition;
}
void Circle::setPosition(const Vec3& position) {
mPosition = position;
}
void Circle::updateViewProjection(const Mat4& vpMatrix) {
mViewProjectionMatrix = vpMatrix;
}
} // end of namespace gamecore
} // end of namespace android