SuperTuxKart
Loading...
Searching...
No Matches
sp_dynamic_draw_call.hpp
1// SuperTuxKart - a fun racing game with go-kart
2// Copyright (C) 2018 SuperTuxKart-Team
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License
6// as published by the Free Software Foundation; either version 3
7// of the License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#ifndef HEADER_SP_DYNAMIC_DRAW_CALL_HPP
19#define HEADER_SP_DYNAMIC_DRAW_CALL_HPP
20
21#include "graphics/sp/sp_mesh_buffer.hpp"
22
23#include <IMeshBuffer.h>
24#include <ISceneNode.h>
25
26#include <array>
27#include <cassert>
28#include <string>
29#include <tuple>
30#include <unordered_map>
31#include <vector>
32
33using namespace irr;
34
35class Material;
36
37namespace SP
38{
39class SPShader;
40
42{
43private:
44 core::matrix4 m_trans;
45
46 scene::ISceneNode* m_parent = NULL;
47
48 core::vector2df m_texture_trans;
49
50 scene::E_PRIMITIVE_TYPE m_primitive_type;
51
52 unsigned m_gl_vbo_size = 4;
53
54 int m_update_offset = 0;
55
56 bool m_visible = true;
57
58 bool m_update_trans = false;
59
60 bool m_removing = false;
61
62 // ------------------------------------------------------------------------
63 bool initTextureDyDc();
64
65public:
66 SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
67 std::shared_ptr<SPShader> shader, Material* m);
68 // ------------------------------------------------------------------------
70 // ------------------------------------------------------------------------
71 virtual void draw(DrawCallType dct = DCT_NORMAL,
72 int material_id = -1) const
73 {
74#ifndef SERVER_ONLY
75 glBindVertexArray(m_vao[0]);
76 glDrawArraysInstanced(
77 m_primitive_type == EPT_TRIANGLES ? GL_TRIANGLES :
78 m_primitive_type == EPT_TRIANGLE_STRIP ? GL_TRIANGLE_STRIP :
79 GL_TRIANGLE_FAN, 0, getVertexCount(), 1);
80#endif
81 }
82 // ------------------------------------------------------------------------
83 virtual void uploadInstanceData()
84 {
85#ifndef SERVER_ONLY
86 if (m_texture_trans.X != 0.0f || m_texture_trans.Y != 0.0f ||
87 m_update_trans || m_parent != NULL)
88 {
89 m_update_trans = false;
90 SPInstancedData id = SPInstancedData(getAbsoluteTransformation(),
91 m_texture_trans.X, m_texture_trans.Y, 0.0f, 0);
92 glBindBuffer(GL_ARRAY_BUFFER, m_ibo);
93 glBufferSubData(GL_ARRAY_BUFFER, 0, 44, id.getData());
94 glBindBuffer(GL_ARRAY_BUFFER, 0);
95 }
96 if (m_update_offset >= 0 && !m_vertices.empty())
97 {
98 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
99 unsigned new_size = m_gl_vbo_size;
100 while (m_vertices.size() > new_size)
101 {
102 // Power of 2 allocation strategy, like std::vector in gcc
103 new_size <<= 1;
104 }
105 if (new_size != m_gl_vbo_size)
106 {
107 m_update_offset = 0;
108 m_gl_vbo_size = new_size;
109 m_vertices.reserve(m_gl_vbo_size);
110 glBufferData(GL_ARRAY_BUFFER, m_gl_vbo_size * 48,
111 m_vertices.data(), GL_DYNAMIC_DRAW);
112 }
113 else
114 {
115 const int length =
116 ((int)m_vertices.size() - m_update_offset) * 48;
117 assert(length > 0);
118 glBufferSubData(GL_ARRAY_BUFFER, m_update_offset * 48, length,
119 m_vertices.data() + m_update_offset);
120 }
121 glBindBuffer(GL_ARRAY_BUFFER, 0);
122 m_update_offset = -1;
123 }
124#endif
125 }
126 // ------------------------------------------------------------------------
127 virtual void uploadGLMesh() {}
128 // ------------------------------------------------------------------------
129 virtual void enableTextureMatrix(unsigned mat_id) {}
130 // ------------------------------------------------------------------------
131 std::vector<video::S3DVertexSkinnedMesh>& getVerticesVector()
132 { return m_vertices; }
133 // ------------------------------------------------------------------------
134 core::vector2df& getTextureTrans()
135 {
136 m_update_trans = true;
137 return m_texture_trans;
138 }
139 // ------------------------------------------------------------------------
140 void setUpdateOffset(int offset)
141 {
142 // Avoid skipping of vertex buffer update if this function is called
143 // more than once per frame
144 if (m_update_offset != -1 && offset > m_update_offset)
145 return;
146 m_update_offset = offset;
147 }
148 // ------------------------------------------------------------------------
149 bool isVisible() const { return m_visible; }
150 // ------------------------------------------------------------------------
151 void setVisible(bool val) { m_visible = val; }
152 // ------------------------------------------------------------------------
153 core::matrix4 getAbsoluteTransformation() const
154 {
155 core::matrix4 trans = m_trans;
156 if (m_parent != NULL)
157 {
158 trans = m_parent->getAbsoluteTransformation() * trans;
159 }
160 return trans;
161 }
162 // ------------------------------------------------------------------------
163 void removeFromSP() { m_removing = true; }
164 // ------------------------------------------------------------------------
165 bool isRemoving() const { return m_removing; }
166 // ------------------------------------------------------------------------
167 bool notReadyFromDrawing() const { return m_vertices.size() < 3; }
168 // ------------------------------------------------------------------------
169 void setTransformation(const core::matrix4& mat)
170 {
171 m_trans = mat;
172 m_update_trans = true;
173 }
174 // ------------------------------------------------------------------------
175 void setPosition(const core::vector3df pos)
176 {
177 m_trans.setTranslation(pos);
178 m_update_trans = true;
179 }
180 // ------------------------------------------------------------------------
181 void setRotationRadians(const core::vector3df rot)
182 {
183 m_trans.setRotationRadians(rot);
184 m_update_trans = true;
185 }
186 // ------------------------------------------------------------------------
187 void setRotationDegrees(const core::vector3df rot)
188 {
189 m_trans.setRotationDegrees(rot);
190 m_update_trans = true;
191 }
192 // ------------------------------------------------------------------------
193 void setScale(const core::vector3df scale)
194 {
195 m_trans.setScale(scale);
196 m_update_trans = true;
197 }
198 // ------------------------------------------------------------------------
199 void setParent(scene::ISceneNode* parent) { m_parent = parent; }
200
201};
202
203}
204
205#endif
Definition: material.hpp:48
Definition: sp_dynamic_draw_call.hpp:42
Definition: sp_instanced_data.hpp:32
Definition: sp_mesh_buffer.hpp:48