1/*
2 * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#ifndef VERTEXARRAY_H
24#define VERTEXARRAY_H
25
26#include "declarations.h"
27#include "hardwarebuffer.h"
28#include <framework/util/databuffer.h>
29
30class VertexArray
31{
32 enum {
33 CACHE_MIN_VERTICES_COUNT = 48
34 };
35public:
36 VertexArray() {}
37 ~VertexArray()
38 {
39 if (m_hardwareBuffer)
40 delete m_hardwareBuffer;
41 }
42 VertexArray(VertexArray& c) : m_buffer(c.m_buffer)
43 {
44 m_hardwareBuffer = nullptr;
45 }
46 VertexArray& operator=(VertexArray& c) = delete;
47
48 inline void addVertex(float x, float y) { m_buffer << x << y; }
49 inline void addTriangle(const Point& a, const Point& b, const Point& c) {
50 addVertex(a.x, a.y);
51 addVertex(b.x, b.y);
52 addVertex(c.x, c.y);
53 }
54 inline void addRect(const Rect& rect)
55 {
56 float top = rect.top();
57 float right = rect.right() + 1;
58 float bottom = rect.bottom() + 1;
59 float left = rect.left();
60
61 addVertex(left, top);
62 addVertex(right, top);
63 addVertex(left, bottom);
64 addVertex(left, bottom);
65 addVertex(right, top);
66 addVertex(right, bottom);
67 }
68 inline void addRect(const RectF& rect)
69 {
70 float top = rect.top();
71 float right = rect.right() + 1.f;
72 float bottom = rect.bottom() + 1.f;
73 float left = rect.left();
74
75 addVertex(left, top);
76 addVertex(right, top);
77 addVertex(left, bottom);
78 addVertex(left, bottom);
79 addVertex(right, top);
80 addVertex(right, bottom);
81 }
82
83 inline void addQuad(const Rect& rect) {
84 float top = rect.top();
85 float right = rect.right()+1;
86 float bottom = rect.bottom()+1;
87 float left = rect.left();
88
89 addVertex(left, top);
90 addVertex(right, top);
91 addVertex(left, bottom);
92 addVertex(right, bottom);
93 }
94
95 inline void addUpsideDownQuad(const Rect& rect) {
96 float top = rect.top();
97 float right = rect.right()+1;
98 float bottom = rect.bottom()+1;
99 float left = rect.left();
100
101 addVertex(left, bottom);
102 addVertex(right, bottom);
103 addVertex(left, top);
104 addVertex(right, top);
105 }
106
107 void clear() { m_buffer.reset(); }
108 float *vertices() const { return m_buffer.data(); }
109 int vertexCount() const { return m_buffer.size() / 2; }
110 int size() const { return m_buffer.size(); }
111
112 // cache
113 void cache()
114 {
115 if (m_buffer.size() < CACHE_MIN_VERTICES_COUNT) return;
116 if (m_hardwareBuffer) return;
117 m_hardwareBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
118 m_hardwareBuffer->bind();
119 m_hardwareBuffer->write((void*)m_buffer.data(), m_buffer.size() * sizeof(float), HardwareBuffer::StaticDraw);
120 }
121 bool isCached() { return m_hardwareBuffer != nullptr; }
122 HardwareBuffer* getHardwareCache() { return m_hardwareBuffer; }
123
124private:
125 DataBuffer<float> m_buffer;
126 HardwareBuffer* m_hardwareBuffer = nullptr;
127};
128
129#endif
130