/* * 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 #include 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(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