1 /*
2  * Copyright 2013 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 
17 #ifndef SF_RENDER_ENGINE_MESH_H
18 #define SF_RENDER_ENGINE_MESH_H
19 
20 #include <vector>
21 
22 #include <stdint.h>
23 
24 namespace android {
25 namespace renderengine {
26 
27 class Mesh {
28 public:
29     class Builder;
30 
31     enum Primitive {
32         TRIANGLES = 0x0004,      // GL_TRIANGLES
33         TRIANGLE_STRIP = 0x0005, // GL_TRIANGLE_STRIP
34         TRIANGLE_FAN = 0x0006    // GL_TRIANGLE_FAN
35     };
36 
37     ~Mesh() = default;
38 
39     /*
40      * VertexArray handles the stride automatically.
41      */
42     template <typename TYPE>
43     class VertexArray {
44         friend class Mesh;
45         float* mData;
46         size_t mStride;
47         size_t mOffset = 0;
VertexArray(float * data,size_t stride)48         VertexArray(float* data, size_t stride) : mData(data), mStride(stride) {}
49 
50     public:
51         // Returns a vertex array at an offset so its easier to append attributes from
52         // multiple sources.
VertexArray(VertexArray<TYPE> & other,size_t offset)53         VertexArray(VertexArray<TYPE>& other, size_t offset)
54               : mData(other.mData), mStride(other.mStride), mOffset(offset) {}
55 
56         TYPE& operator[](size_t index) {
57             return *reinterpret_cast<TYPE*>(&mData[(index + mOffset) * mStride]);
58         }
59         TYPE const& operator[](size_t index) const {
60             return *reinterpret_cast<TYPE const*>(&mData[(index + mOffset) * mStride]);
61         }
62     };
63 
64     template <typename TYPE>
getPositionArray()65     VertexArray<TYPE> getPositionArray() {
66         return VertexArray<TYPE>(getPositions(), mStride);
67     }
68 
69     template <typename TYPE>
getTexCoordArray()70     VertexArray<TYPE> getTexCoordArray() {
71         return VertexArray<TYPE>(getTexCoords(), mStride);
72     }
73 
74     template <typename TYPE>
getCropCoordArray()75     VertexArray<TYPE> getCropCoordArray() {
76         return VertexArray<TYPE>(getCropCoords(), mStride);
77     }
78 
79     template <typename TYPE>
getShadowColorArray()80     VertexArray<TYPE> getShadowColorArray() {
81         return VertexArray<TYPE>(getShadowColor(), mStride);
82     }
83 
84     template <typename TYPE>
getShadowParamsArray()85     VertexArray<TYPE> getShadowParamsArray() {
86         return VertexArray<TYPE>(getShadowParams(), mStride);
87     }
88 
getIndicesArray()89     uint16_t* getIndicesArray() { return getIndices(); }
90 
91     Primitive getPrimitive() const;
92 
93     // returns a pointer to the vertices positions
94     float const* getPositions() const;
95 
96     // returns a pointer to the vertices texture coordinates
97     float const* getTexCoords() const;
98 
99     // returns a pointer to the vertices crop coordinates
100     float const* getCropCoords() const;
101 
102     // returns a pointer to colors
103     float const* getShadowColor() const;
104 
105     // returns a pointer to the shadow params
106     float const* getShadowParams() const;
107 
108     // returns a pointer to indices
109     uint16_t const* getIndices() const;
110 
111     // number of vertices in this mesh
112     size_t getVertexCount() const;
113 
114     // dimension of vertices
115     size_t getVertexSize() const;
116 
117     // dimension of texture coordinates
118     size_t getTexCoordsSize() const;
119 
120     size_t getShadowParamsSize() const;
121 
122     size_t getShadowColorSize() const;
123 
124     size_t getIndexCount() const;
125 
126     // return stride in bytes
127     size_t getByteStride() const;
128 
129     // return stride in floats
130     size_t getStride() const;
131 
132 private:
133     Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize,
134          size_t cropCoordsSize, size_t shadowColorSize, size_t shadowParamsSize, size_t indexCount);
135     Mesh(const Mesh&);
136     Mesh& operator=(const Mesh&);
137     Mesh const& operator=(const Mesh&) const;
138 
139     float* getPositions();
140     float* getTexCoords();
141     float* getCropCoords();
142     float* getShadowColor();
143     float* getShadowParams();
144     uint16_t* getIndices();
145 
146     std::vector<float> mVertices;
147     size_t mVertexCount;
148     size_t mVertexSize;
149     size_t mTexCoordsSize;
150     size_t mCropCoordsSize;
151     size_t mShadowColorSize;
152     size_t mShadowParamsSize;
153     size_t mStride;
154     Primitive mPrimitive;
155     std::vector<uint16_t> mIndices;
156     size_t mIndexCount;
157 };
158 
159 class Mesh::Builder {
160 public:
setPrimitive(Primitive primitive)161     Builder& setPrimitive(Primitive primitive) {
162         mPrimitive = primitive;
163         return *this;
164     };
setVertices(size_t vertexCount,size_t vertexSize)165     Builder& setVertices(size_t vertexCount, size_t vertexSize) {
166         mVertexCount = vertexCount;
167         mVertexSize = vertexSize;
168         return *this;
169     };
setTexCoords(size_t texCoordsSize)170     Builder& setTexCoords(size_t texCoordsSize) {
171         mTexCoordsSize = texCoordsSize;
172         return *this;
173     };
setCropCoords(size_t cropCoordsSize)174     Builder& setCropCoords(size_t cropCoordsSize) {
175         mCropCoordsSize = cropCoordsSize;
176         return *this;
177     };
setShadowAttrs()178     Builder& setShadowAttrs() {
179         mShadowParamsSize = 3;
180         mShadowColorSize = 4;
181         return *this;
182     };
setIndices(size_t indexCount)183     Builder& setIndices(size_t indexCount) {
184         mIndexCount = indexCount;
185         return *this;
186     };
build()187     Mesh build() const {
188         return Mesh{mPrimitive,      mVertexCount,     mVertexSize,       mTexCoordsSize,
189                     mCropCoordsSize, mShadowColorSize, mShadowParamsSize, mIndexCount};
190     }
191 
192 private:
193     size_t mVertexCount = 0;
194     size_t mVertexSize = 0;
195     size_t mTexCoordsSize = 0;
196     size_t mCropCoordsSize = 0;
197     size_t mShadowColorSize = 0;
198     size_t mShadowParamsSize = 0;
199     size_t mIndexCount = 0;
200     Primitive mPrimitive;
201 };
202 
203 } // namespace renderengine
204 } // namespace android
205 #endif /* SF_RENDER_ENGINE_MESH_H */
206