blob: 7820a66e0c673eb6e22fb6c86757577c0f8c67ab [file] [log] [blame]
Chris Craik96a5c4c2015-01-27 15:46:35 -08001/*
2 * Copyright (C) 2015 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#include "renderstate/MeshState.h"
17
18#include "Program.h"
19
20#include "ShadowTessellator.h"
21
22namespace android {
23namespace uirenderer {
24
25MeshState::MeshState()
26 : mCurrentPositionPointer(this)
27 , mCurrentPositionStride(0)
28 , mCurrentTexCoordsPointer(this)
29 , mCurrentTexCoordsStride(0)
30 , mTexCoordsArrayEnabled(false) {
31
32 glGenBuffers(1, &meshBuffer);
33 glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
34 glBufferData(GL_ARRAY_BUFFER, sizeof(kMeshVertices), kMeshVertices, GL_STATIC_DRAW);
35
36 mCurrentBuffer = meshBuffer;
37 mCurrentIndicesBuffer = 0;
38 mCurrentPixelBuffer = 0;
39
40 mQuadListIndices = 0;
41 mShadowStripsIndices = 0;
42}
43
44MeshState::~MeshState() {
45 glDeleteBuffers(1, &meshBuffer);
46 mCurrentBuffer = 0;
47
48 glDeleteBuffers(1, &mQuadListIndices);
49 mQuadListIndices = 0;
50
51 glDeleteBuffers(1, &mShadowStripsIndices);
52 mShadowStripsIndices = 0;
53}
54
55///////////////////////////////////////////////////////////////////////////////
56// Buffer Objects
57///////////////////////////////////////////////////////////////////////////////
58
59bool MeshState::bindMeshBuffer() {
60 return bindMeshBuffer(meshBuffer);
61}
62
63bool MeshState::bindMeshBuffer(GLuint buffer) {
64 if (!buffer) buffer = meshBuffer;
65 if (mCurrentBuffer != buffer) {
66 glBindBuffer(GL_ARRAY_BUFFER, buffer);
67 mCurrentBuffer = buffer;
68 return true;
69 }
70 return false;
71}
72
73bool MeshState::unbindMeshBuffer() {
74 if (mCurrentBuffer) {
75 glBindBuffer(GL_ARRAY_BUFFER, 0);
76 mCurrentBuffer = 0;
77 return true;
78 }
79 return false;
80}
81
82///////////////////////////////////////////////////////////////////////////////
83// Vertices
84///////////////////////////////////////////////////////////////////////////////
85
86void MeshState::bindPositionVertexPointer(const Program* currentProgram, bool force,
87 const GLvoid* vertices, GLsizei stride) {
88 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
89 GLuint slot = currentProgram->position;
90 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
91 mCurrentPositionPointer = vertices;
92 mCurrentPositionStride = stride;
93 }
94}
95
96void MeshState::bindTexCoordsVertexPointer(const Program* currentProgram, bool force,
97 const GLvoid* vertices, GLsizei stride) {
98 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
99 GLuint slot = currentProgram->texCoords;
100 glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
101 mCurrentTexCoordsPointer = vertices;
102 mCurrentTexCoordsStride = stride;
103 }
104}
105
106void MeshState::resetVertexPointers() {
107 mCurrentPositionPointer = this;
108 mCurrentTexCoordsPointer = this;
109}
110
111void MeshState::resetTexCoordsVertexPointer() {
112 mCurrentTexCoordsPointer = this;
113}
114
115void MeshState::enableTexCoordsVertexArray() {
116 if (!mTexCoordsArrayEnabled) {
117 glEnableVertexAttribArray(Program::kBindingTexCoords);
118 mCurrentTexCoordsPointer = this;
119 mTexCoordsArrayEnabled = true;
120 }
121}
122
123void MeshState::disableTexCoordsVertexArray() {
124 if (mTexCoordsArrayEnabled) {
125 glDisableVertexAttribArray(Program::kBindingTexCoords);
126 mTexCoordsArrayEnabled = false;
127 }
128}
129
130///////////////////////////////////////////////////////////////////////////////
131// Indices
132///////////////////////////////////////////////////////////////////////////////
133
134bool MeshState::bindIndicesBufferInternal(const GLuint buffer) {
135 if (mCurrentIndicesBuffer != buffer) {
136 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
137 mCurrentIndicesBuffer = buffer;
138 return true;
139 }
140 return false;
141}
142
143bool MeshState::bindQuadIndicesBuffer() {
144 if (!mQuadListIndices) {
145 std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]);
146 for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
147 uint16_t quad = i * 4;
148 int index = i * 6;
149 regionIndices[index ] = quad; // top-left
150 regionIndices[index + 1] = quad + 1; // top-right
151 regionIndices[index + 2] = quad + 2; // bottom-left
152 regionIndices[index + 3] = quad + 2; // bottom-left
153 regionIndices[index + 4] = quad + 1; // top-right
154 regionIndices[index + 5] = quad + 3; // bottom-right
155 }
156
157 glGenBuffers(1, &mQuadListIndices);
158 bool force = bindIndicesBufferInternal(mQuadListIndices);
159 glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t),
160 regionIndices.get(), GL_STATIC_DRAW);
161 return force;
162 }
163
164 return bindIndicesBufferInternal(mQuadListIndices);
165}
166
167bool MeshState::bindShadowIndicesBuffer() {
168 if (!mShadowStripsIndices) {
169 std::unique_ptr<uint16_t[]> shadowIndices(new uint16_t[MAX_SHADOW_INDEX_COUNT]);
170 ShadowTessellator::generateShadowIndices(shadowIndices.get());
171 glGenBuffers(1, &mShadowStripsIndices);
172 bool force = bindIndicesBufferInternal(mShadowStripsIndices);
173 glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t),
174 shadowIndices.get(), GL_STATIC_DRAW);
175 return force;
176 }
177
178 return bindIndicesBufferInternal(mShadowStripsIndices);
179}
180
181bool MeshState::unbindIndicesBuffer() {
182 if (mCurrentIndicesBuffer) {
183 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
184 mCurrentIndicesBuffer = 0;
185 return true;
186 }
187 return false;
188}
189
190} /* namespace uirenderer */
191} /* namespace android */
192