MeshState.cpp revision 1b7db4000eabb570697f4c5097588acbfa4df62b
196a5c4c7bab6718524de7253da8309143ab48befChris Craik/*
296a5c4c7bab6718524de7253da8309143ab48befChris Craik * Copyright (C) 2015 The Android Open Source Project
396a5c4c7bab6718524de7253da8309143ab48befChris Craik *
496a5c4c7bab6718524de7253da8309143ab48befChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
596a5c4c7bab6718524de7253da8309143ab48befChris Craik * you may not use this file except in compliance with the License.
696a5c4c7bab6718524de7253da8309143ab48befChris Craik * You may obtain a copy of the License at
796a5c4c7bab6718524de7253da8309143ab48befChris Craik *
896a5c4c7bab6718524de7253da8309143ab48befChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
996a5c4c7bab6718524de7253da8309143ab48befChris Craik *
1096a5c4c7bab6718524de7253da8309143ab48befChris Craik * Unless required by applicable law or agreed to in writing, software
1196a5c4c7bab6718524de7253da8309143ab48befChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
1296a5c4c7bab6718524de7253da8309143ab48befChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1396a5c4c7bab6718524de7253da8309143ab48befChris Craik * See the License for the specific language governing permissions and
1496a5c4c7bab6718524de7253da8309143ab48befChris Craik * limitations under the License.
1596a5c4c7bab6718524de7253da8309143ab48befChris Craik */
1696a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "renderstate/MeshState.h"
1796a5c4c7bab6718524de7253da8309143ab48befChris Craik
1896a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "Program.h"
1996a5c4c7bab6718524de7253da8309143ab48befChris Craik
2096a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "ShadowTessellator.h"
2196a5c4c7bab6718524de7253da8309143ab48befChris Craik
2296a5c4c7bab6718524de7253da8309143ab48befChris Craiknamespace android {
2396a5c4c7bab6718524de7253da8309143ab48befChris Craiknamespace uirenderer {
2496a5c4c7bab6718524de7253da8309143ab48befChris Craik
2596a5c4c7bab6718524de7253da8309143ab48befChris CraikMeshState::MeshState()
26117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        : mCurrentIndicesBuffer(0)
27117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        , mCurrentPixelBuffer(0)
28117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        , mCurrentPositionPointer(this)
2996a5c4c7bab6718524de7253da8309143ab48befChris Craik        , mCurrentPositionStride(0)
3096a5c4c7bab6718524de7253da8309143ab48befChris Craik        , mCurrentTexCoordsPointer(this)
3196a5c4c7bab6718524de7253da8309143ab48befChris Craik        , mCurrentTexCoordsStride(0)
32117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        , mTexCoordsArrayEnabled(false)
33117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        , mQuadListIndices(0) {
34031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    glGenBuffers(1, &mUnitQuadBuffer);
35031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
36031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
37031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    mCurrentBuffer = mUnitQuadBuffer;
386c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik
39182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik    uint16_t regionIndices[kMaxNumberOfQuads * 6];
402ab95d780b023152556d9f8659de734ec7b55047Chris Craik    for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
412ab95d780b023152556d9f8659de734ec7b55047Chris Craik        uint16_t quad = i * 4;
422ab95d780b023152556d9f8659de734ec7b55047Chris Craik        int index = i * 6;
432ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index    ] = quad;       // top-left
442ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index + 1] = quad + 1;   // top-right
452ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index + 2] = quad + 2;   // bottom-left
462ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index + 3] = quad + 2;   // bottom-left
472ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index + 4] = quad + 1;   // top-right
482ab95d780b023152556d9f8659de734ec7b55047Chris Craik        regionIndices[index + 5] = quad + 3;   // bottom-right
492ab95d780b023152556d9f8659de734ec7b55047Chris Craik    }
502ab95d780b023152556d9f8659de734ec7b55047Chris Craik    glGenBuffers(1, &mQuadListIndices);
512ab95d780b023152556d9f8659de734ec7b55047Chris Craik    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices);
52182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW);
532ab95d780b023152556d9f8659de734ec7b55047Chris Craik    mCurrentIndicesBuffer = mQuadListIndices;
542ab95d780b023152556d9f8659de734ec7b55047Chris Craik
556c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik    // position attribute always enabled
566c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik    glEnableVertexAttribArray(Program::kBindingPosition);
5796a5c4c7bab6718524de7253da8309143ab48befChris Craik}
5896a5c4c7bab6718524de7253da8309143ab48befChris Craik
5996a5c4c7bab6718524de7253da8309143ab48befChris CraikMeshState::~MeshState() {
60031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik    glDeleteBuffers(1, &mUnitQuadBuffer);
6196a5c4c7bab6718524de7253da8309143ab48befChris Craik    mCurrentBuffer = 0;
6296a5c4c7bab6718524de7253da8309143ab48befChris Craik
6396a5c4c7bab6718524de7253da8309143ab48befChris Craik    glDeleteBuffers(1, &mQuadListIndices);
6496a5c4c7bab6718524de7253da8309143ab48befChris Craik    mQuadListIndices = 0;
65117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik}
6696a5c4c7bab6718524de7253da8309143ab48befChris Craik
67117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craikvoid MeshState::dump() {
6808fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik    ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
69f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik    ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer);
7008fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik    ALOGD("MeshState vertices: vertex data %p, stride %d",
7108fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik            mCurrentPositionPointer, mCurrentPositionStride);
7208fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik    ALOGD("MeshState texCoord: data %p, stride %d",
7308fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik            mCurrentTexCoordsPointer, mCurrentTexCoordsStride);
7496a5c4c7bab6718524de7253da8309143ab48befChris Craik}
7596a5c4c7bab6718524de7253da8309143ab48befChris Craik
7696a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
7796a5c4c7bab6718524de7253da8309143ab48befChris Craik// Buffer Objects
7896a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
7996a5c4c7bab6718524de7253da8309143ab48befChris Craik
801b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindMeshBuffer(GLuint buffer) {
81117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik    if (mCurrentBuffer != buffer) {
82117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        glBindBuffer(GL_ARRAY_BUFFER, buffer);
83117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik        mCurrentBuffer = buffer;
841b7db4000eabb570697f4c5097588acbfa4df62bChris Craik
851b7db4000eabb570697f4c5097588acbfa4df62bChris Craik        // buffer has changed, so invalidate cached vertex pos/texcoord pointers
861b7db4000eabb570697f4c5097588acbfa4df62bChris Craik        resetVertexPointers();
8796a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
881b7db4000eabb570697f4c5097588acbfa4df62bChris Craik}
891b7db4000eabb570697f4c5097588acbfa4df62bChris Craik
901b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::unbindMeshBuffer() {
911b7db4000eabb570697f4c5097588acbfa4df62bChris Craik    return bindMeshBuffer(0);
9296a5c4c7bab6718524de7253da8309143ab48befChris Craik}
9396a5c4c7bab6718524de7253da8309143ab48befChris Craik
948d2cf943d9c7292e54726399faefdec4a01c084bChris Craikvoid MeshState::genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size,
958d2cf943d9c7292e54726399faefdec4a01c084bChris Craik        const void* data, GLenum usage) {
968d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    if (!*buffer) {
978d2cf943d9c7292e54726399faefdec4a01c084bChris Craik        glGenBuffers(1, buffer);
988d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    }
998d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    bindMeshBuffer(*buffer);
1008d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    glBufferData(GL_ARRAY_BUFFER, size, data, usage);
1018d2cf943d9c7292e54726399faefdec4a01c084bChris Craik}
1028d2cf943d9c7292e54726399faefdec4a01c084bChris Craik
1038d2cf943d9c7292e54726399faefdec4a01c084bChris Craikvoid MeshState::deleteMeshBuffer(GLuint buffer) {
1048d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    if (buffer == mCurrentBuffer) {
1058d2cf943d9c7292e54726399faefdec4a01c084bChris Craik        // GL defines that deleting the currently bound VBO rebinds to 0 (no VBO).
1068d2cf943d9c7292e54726399faefdec4a01c084bChris Craik        // Reflect this in our cached value.
1078d2cf943d9c7292e54726399faefdec4a01c084bChris Craik        mCurrentBuffer = 0;
1088d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    }
1098d2cf943d9c7292e54726399faefdec4a01c084bChris Craik    glDeleteBuffers(1, &buffer);
1108d2cf943d9c7292e54726399faefdec4a01c084bChris Craik}
1118d2cf943d9c7292e54726399faefdec4a01c084bChris Craik
11296a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
11396a5c4c7bab6718524de7253da8309143ab48befChris Craik// Vertices
11496a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
11596a5c4c7bab6718524de7253da8309143ab48befChris Craik
1161b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindPositionVertexPointer(const GLvoid* vertices, GLsizei stride) {
1171b7db4000eabb570697f4c5097588acbfa4df62bChris Craik    // update pos coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
1181b7db4000eabb570697f4c5097588acbfa4df62bChris Craik    if (mCurrentBuffer == 0
1191b7db4000eabb570697f4c5097588acbfa4df62bChris Craik            || vertices != mCurrentPositionPointer
1201b7db4000eabb570697f4c5097588acbfa4df62bChris Craik            || stride != mCurrentPositionStride) {
1216c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik        glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
12296a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentPositionPointer = vertices;
12396a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentPositionStride = stride;
12496a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
12596a5c4c7bab6718524de7253da8309143ab48befChris Craik}
12696a5c4c7bab6718524de7253da8309143ab48befChris Craik
1271b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindTexCoordsVertexPointer(const GLvoid* vertices, GLsizei stride) {
1281b7db4000eabb570697f4c5097588acbfa4df62bChris Craik    // update tex coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
1291b7db4000eabb570697f4c5097588acbfa4df62bChris Craik    if (mCurrentBuffer == 0
1301b7db4000eabb570697f4c5097588acbfa4df62bChris Craik            || vertices != mCurrentTexCoordsPointer
1311b7db4000eabb570697f4c5097588acbfa4df62bChris Craik            || stride != mCurrentTexCoordsStride) {
1326c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik        glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
13396a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentTexCoordsPointer = vertices;
13496a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentTexCoordsStride = stride;
13596a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
13696a5c4c7bab6718524de7253da8309143ab48befChris Craik}
13796a5c4c7bab6718524de7253da8309143ab48befChris Craik
13896a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::resetVertexPointers() {
13996a5c4c7bab6718524de7253da8309143ab48befChris Craik    mCurrentPositionPointer = this;
14096a5c4c7bab6718524de7253da8309143ab48befChris Craik    mCurrentTexCoordsPointer = this;
14196a5c4c7bab6718524de7253da8309143ab48befChris Craik}
14296a5c4c7bab6718524de7253da8309143ab48befChris Craik
14396a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::enableTexCoordsVertexArray() {
14496a5c4c7bab6718524de7253da8309143ab48befChris Craik    if (!mTexCoordsArrayEnabled) {
14596a5c4c7bab6718524de7253da8309143ab48befChris Craik        glEnableVertexAttribArray(Program::kBindingTexCoords);
14696a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentTexCoordsPointer = this;
14796a5c4c7bab6718524de7253da8309143ab48befChris Craik        mTexCoordsArrayEnabled = true;
14896a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
14996a5c4c7bab6718524de7253da8309143ab48befChris Craik}
15096a5c4c7bab6718524de7253da8309143ab48befChris Craik
15196a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::disableTexCoordsVertexArray() {
15296a5c4c7bab6718524de7253da8309143ab48befChris Craik    if (mTexCoordsArrayEnabled) {
15396a5c4c7bab6718524de7253da8309143ab48befChris Craik        glDisableVertexAttribArray(Program::kBindingTexCoords);
15496a5c4c7bab6718524de7253da8309143ab48befChris Craik        mTexCoordsArrayEnabled = false;
15596a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
15696a5c4c7bab6718524de7253da8309143ab48befChris Craik}
15796a5c4c7bab6718524de7253da8309143ab48befChris Craik
15896a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
15996a5c4c7bab6718524de7253da8309143ab48befChris Craik// Indices
16096a5c4c7bab6718524de7253da8309143ab48befChris Craik///////////////////////////////////////////////////////////////////////////////
16196a5c4c7bab6718524de7253da8309143ab48befChris Craik
1621b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindIndicesBuffer(const GLuint buffer) {
16396a5c4c7bab6718524de7253da8309143ab48befChris Craik    if (mCurrentIndicesBuffer != buffer) {
16496a5c4c7bab6718524de7253da8309143ab48befChris Craik        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
16596a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentIndicesBuffer = buffer;
16696a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
16796a5c4c7bab6718524de7253da8309143ab48befChris Craik}
16896a5c4c7bab6718524de7253da8309143ab48befChris Craik
1691b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::unbindIndicesBuffer() {
17096a5c4c7bab6718524de7253da8309143ab48befChris Craik    if (mCurrentIndicesBuffer) {
17196a5c4c7bab6718524de7253da8309143ab48befChris Craik        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
17296a5c4c7bab6718524de7253da8309143ab48befChris Craik        mCurrentIndicesBuffer = 0;
17396a5c4c7bab6718524de7253da8309143ab48befChris Craik    }
17496a5c4c7bab6718524de7253da8309143ab48befChris Craik}
17596a5c4c7bab6718524de7253da8309143ab48befChris Craik
17696a5c4c7bab6718524de7253da8309143ab48befChris Craik} /* namespace uirenderer */
17796a5c4c7bab6718524de7253da8309143ab48befChris Craik} /* namespace android */
17896a5c4c7bab6718524de7253da8309143ab48befChris Craik
179