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 Craiknamespace android { 2196a5c4c7bab6718524de7253da8309143ab48befChris Craiknamespace uirenderer { 2296a5c4c7bab6718524de7253da8309143ab48befChris Craik 2396a5c4c7bab6718524de7253da8309143ab48befChris CraikMeshState::MeshState() 24117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik : mCurrentIndicesBuffer(0) 25117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik , mCurrentPixelBuffer(0) 26117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik , mCurrentPositionPointer(this) 2796a5c4c7bab6718524de7253da8309143ab48befChris Craik , mCurrentPositionStride(0) 2896a5c4c7bab6718524de7253da8309143ab48befChris Craik , mCurrentTexCoordsPointer(this) 2996a5c4c7bab6718524de7253da8309143ab48befChris Craik , mCurrentTexCoordsStride(0) 30117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik , mTexCoordsArrayEnabled(false) 31117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik , mQuadListIndices(0) { 32031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik glGenBuffers(1, &mUnitQuadBuffer); 33031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer); 34031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW); 35031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik mCurrentBuffer = mUnitQuadBuffer; 366c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 37182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik uint16_t regionIndices[kMaxNumberOfQuads * 6]; 382ab95d780b023152556d9f8659de734ec7b55047Chris Craik for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { 392ab95d780b023152556d9f8659de734ec7b55047Chris Craik uint16_t quad = i * 4; 402ab95d780b023152556d9f8659de734ec7b55047Chris Craik int index = i * 6; 412ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index ] = quad; // top-left 422ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index + 1] = quad + 1; // top-right 432ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index + 2] = quad + 2; // bottom-left 442ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index + 3] = quad + 2; // bottom-left 452ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index + 4] = quad + 1; // top-right 462ab95d780b023152556d9f8659de734ec7b55047Chris Craik regionIndices[index + 5] = quad + 3; // bottom-right 472ab95d780b023152556d9f8659de734ec7b55047Chris Craik } 482ab95d780b023152556d9f8659de734ec7b55047Chris Craik glGenBuffers(1, &mQuadListIndices); 492ab95d780b023152556d9f8659de734ec7b55047Chris Craik glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices); 50182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW); 512ab95d780b023152556d9f8659de734ec7b55047Chris Craik mCurrentIndicesBuffer = mQuadListIndices; 522ab95d780b023152556d9f8659de734ec7b55047Chris Craik 536c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik // position attribute always enabled 546c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glEnableVertexAttribArray(Program::kBindingPosition); 5596a5c4c7bab6718524de7253da8309143ab48befChris Craik} 5696a5c4c7bab6718524de7253da8309143ab48befChris Craik 5796a5c4c7bab6718524de7253da8309143ab48befChris CraikMeshState::~MeshState() { 58031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik glDeleteBuffers(1, &mUnitQuadBuffer); 5996a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentBuffer = 0; 6096a5c4c7bab6718524de7253da8309143ab48befChris Craik 6196a5c4c7bab6718524de7253da8309143ab48befChris Craik glDeleteBuffers(1, &mQuadListIndices); 6296a5c4c7bab6718524de7253da8309143ab48befChris Craik mQuadListIndices = 0; 63117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik} 6496a5c4c7bab6718524de7253da8309143ab48befChris Craik 65117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craikvoid MeshState::dump() { 6608fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer); 67f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer); 6808fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik ALOGD("MeshState vertices: vertex data %p, stride %d", 6908fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik mCurrentPositionPointer, mCurrentPositionStride); 7008fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik ALOGD("MeshState texCoord: data %p, stride %d", 7108fa43fdeb646f56edcd8b33d06ee7d79b203426Chris Craik mCurrentTexCoordsPointer, mCurrentTexCoordsStride); 7296a5c4c7bab6718524de7253da8309143ab48befChris Craik} 7396a5c4c7bab6718524de7253da8309143ab48befChris Craik 7496a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 7596a5c4c7bab6718524de7253da8309143ab48befChris Craik// Buffer Objects 7696a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 7796a5c4c7bab6718524de7253da8309143ab48befChris Craik 781b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindMeshBuffer(GLuint buffer) { 79117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik if (mCurrentBuffer != buffer) { 80117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glBindBuffer(GL_ARRAY_BUFFER, buffer); 81117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik mCurrentBuffer = buffer; 821b7db4000eabb570697f4c5097588acbfa4df62bChris Craik 831b7db4000eabb570697f4c5097588acbfa4df62bChris Craik // buffer has changed, so invalidate cached vertex pos/texcoord pointers 841b7db4000eabb570697f4c5097588acbfa4df62bChris Craik resetVertexPointers(); 8596a5c4c7bab6718524de7253da8309143ab48befChris Craik } 861b7db4000eabb570697f4c5097588acbfa4df62bChris Craik} 871b7db4000eabb570697f4c5097588acbfa4df62bChris Craik 881b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::unbindMeshBuffer() { 891b7db4000eabb570697f4c5097588acbfa4df62bChris Craik return bindMeshBuffer(0); 9096a5c4c7bab6718524de7253da8309143ab48befChris Craik} 9196a5c4c7bab6718524de7253da8309143ab48befChris Craik 928d2cf943d9c7292e54726399faefdec4a01c084bChris Craikvoid MeshState::genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size, 938d2cf943d9c7292e54726399faefdec4a01c084bChris Craik const void* data, GLenum usage) { 948d2cf943d9c7292e54726399faefdec4a01c084bChris Craik if (!*buffer) { 958d2cf943d9c7292e54726399faefdec4a01c084bChris Craik glGenBuffers(1, buffer); 968d2cf943d9c7292e54726399faefdec4a01c084bChris Craik } 978d2cf943d9c7292e54726399faefdec4a01c084bChris Craik bindMeshBuffer(*buffer); 988d2cf943d9c7292e54726399faefdec4a01c084bChris Craik glBufferData(GL_ARRAY_BUFFER, size, data, usage); 998d2cf943d9c7292e54726399faefdec4a01c084bChris Craik} 1008d2cf943d9c7292e54726399faefdec4a01c084bChris Craik 101fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyvvoid MeshState::updateMeshBufferSubData(GLuint buffer, GLintptr offset, 102fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyv GLsizeiptr size, const void* data) { 103fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyv bindMeshBuffer(buffer); 104fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyv glBufferSubData(GL_ARRAY_BUFFER, offset, size, data); 105fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyv} 106fd3744b7d88d0015cfb36be2b485c4b6ba0c1b58sergeyv 1078d2cf943d9c7292e54726399faefdec4a01c084bChris Craikvoid MeshState::deleteMeshBuffer(GLuint buffer) { 1088d2cf943d9c7292e54726399faefdec4a01c084bChris Craik if (buffer == mCurrentBuffer) { 1098d2cf943d9c7292e54726399faefdec4a01c084bChris Craik // GL defines that deleting the currently bound VBO rebinds to 0 (no VBO). 1108d2cf943d9c7292e54726399faefdec4a01c084bChris Craik // Reflect this in our cached value. 1118d2cf943d9c7292e54726399faefdec4a01c084bChris Craik mCurrentBuffer = 0; 1128d2cf943d9c7292e54726399faefdec4a01c084bChris Craik } 1138d2cf943d9c7292e54726399faefdec4a01c084bChris Craik glDeleteBuffers(1, &buffer); 1148d2cf943d9c7292e54726399faefdec4a01c084bChris Craik} 1158d2cf943d9c7292e54726399faefdec4a01c084bChris Craik 11696a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 11796a5c4c7bab6718524de7253da8309143ab48befChris Craik// Vertices 11896a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 11996a5c4c7bab6718524de7253da8309143ab48befChris Craik 1201b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindPositionVertexPointer(const GLvoid* vertices, GLsizei stride) { 1211b7db4000eabb570697f4c5097588acbfa4df62bChris Craik // update pos coords if !current vbo, since vertices may point into mutable memory (e.g. stack) 1221b7db4000eabb570697f4c5097588acbfa4df62bChris Craik if (mCurrentBuffer == 0 1231b7db4000eabb570697f4c5097588acbfa4df62bChris Craik || vertices != mCurrentPositionPointer 1241b7db4000eabb570697f4c5097588acbfa4df62bChris Craik || stride != mCurrentPositionStride) { 1256c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices); 12696a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentPositionPointer = vertices; 12796a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentPositionStride = stride; 12896a5c4c7bab6718524de7253da8309143ab48befChris Craik } 12996a5c4c7bab6718524de7253da8309143ab48befChris Craik} 13096a5c4c7bab6718524de7253da8309143ab48befChris Craik 1311b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindTexCoordsVertexPointer(const GLvoid* vertices, GLsizei stride) { 1321b7db4000eabb570697f4c5097588acbfa4df62bChris Craik // update tex coords if !current vbo, since vertices may point into mutable memory (e.g. stack) 1331b7db4000eabb570697f4c5097588acbfa4df62bChris Craik if (mCurrentBuffer == 0 1341b7db4000eabb570697f4c5097588acbfa4df62bChris Craik || vertices != mCurrentTexCoordsPointer 1351b7db4000eabb570697f4c5097588acbfa4df62bChris Craik || stride != mCurrentTexCoordsStride) { 1366c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices); 13796a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentTexCoordsPointer = vertices; 13896a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentTexCoordsStride = stride; 13996a5c4c7bab6718524de7253da8309143ab48befChris Craik } 14096a5c4c7bab6718524de7253da8309143ab48befChris Craik} 14196a5c4c7bab6718524de7253da8309143ab48befChris Craik 14296a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::resetVertexPointers() { 14396a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentPositionPointer = this; 14496a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentTexCoordsPointer = this; 14596a5c4c7bab6718524de7253da8309143ab48befChris Craik} 14696a5c4c7bab6718524de7253da8309143ab48befChris Craik 14796a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::enableTexCoordsVertexArray() { 14896a5c4c7bab6718524de7253da8309143ab48befChris Craik if (!mTexCoordsArrayEnabled) { 14996a5c4c7bab6718524de7253da8309143ab48befChris Craik glEnableVertexAttribArray(Program::kBindingTexCoords); 15096a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentTexCoordsPointer = this; 15196a5c4c7bab6718524de7253da8309143ab48befChris Craik mTexCoordsArrayEnabled = true; 15296a5c4c7bab6718524de7253da8309143ab48befChris Craik } 15396a5c4c7bab6718524de7253da8309143ab48befChris Craik} 15496a5c4c7bab6718524de7253da8309143ab48befChris Craik 15596a5c4c7bab6718524de7253da8309143ab48befChris Craikvoid MeshState::disableTexCoordsVertexArray() { 15696a5c4c7bab6718524de7253da8309143ab48befChris Craik if (mTexCoordsArrayEnabled) { 15796a5c4c7bab6718524de7253da8309143ab48befChris Craik glDisableVertexAttribArray(Program::kBindingTexCoords); 15896a5c4c7bab6718524de7253da8309143ab48befChris Craik mTexCoordsArrayEnabled = false; 15996a5c4c7bab6718524de7253da8309143ab48befChris Craik } 16096a5c4c7bab6718524de7253da8309143ab48befChris Craik} 16196a5c4c7bab6718524de7253da8309143ab48befChris Craik 16296a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 16396a5c4c7bab6718524de7253da8309143ab48befChris Craik// Indices 16496a5c4c7bab6718524de7253da8309143ab48befChris Craik/////////////////////////////////////////////////////////////////////////////// 16596a5c4c7bab6718524de7253da8309143ab48befChris Craik 1661b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::bindIndicesBuffer(const GLuint buffer) { 16796a5c4c7bab6718524de7253da8309143ab48befChris Craik if (mCurrentIndicesBuffer != buffer) { 16896a5c4c7bab6718524de7253da8309143ab48befChris Craik glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 16996a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentIndicesBuffer = buffer; 17096a5c4c7bab6718524de7253da8309143ab48befChris Craik } 17196a5c4c7bab6718524de7253da8309143ab48befChris Craik} 17296a5c4c7bab6718524de7253da8309143ab48befChris Craik 1731b7db4000eabb570697f4c5097588acbfa4df62bChris Craikvoid MeshState::unbindIndicesBuffer() { 17496a5c4c7bab6718524de7253da8309143ab48befChris Craik if (mCurrentIndicesBuffer) { 17596a5c4c7bab6718524de7253da8309143ab48befChris Craik glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 17696a5c4c7bab6718524de7253da8309143ab48befChris Craik mCurrentIndicesBuffer = 0; 17796a5c4c7bab6718524de7253da8309143ab48befChris Craik } 17896a5c4c7bab6718524de7253da8309143ab48befChris Craik} 17996a5c4c7bab6718524de7253da8309143ab48befChris Craik 18096a5c4c7bab6718524de7253da8309143ab48befChris Craik} /* namespace uirenderer */ 18196a5c4c7bab6718524de7253da8309143ab48befChris Craik} /* namespace android */ 18296a5c4c7bab6718524de7253da8309143ab48befChris Craik 183