1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2014-2015 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 STK_TEXT_BILLBOARD_HPP 19 #define STK_TEXT_BILLBOARD_HPP 20 21 #include "font/font_with_face.hpp" 22 #include "graphics/gl_headers.hpp" 23 #include "graphics/sp/sp_instanced_data.hpp" 24 #include "utils/no_copy.hpp" 25 26 #include <ISceneNode.h> 27 #include <array> 28 #include <unordered_map> 29 #include <vector> 30 31 using namespace irr; 32 using namespace scene; 33 34 class STKTextBillboard : public ISceneNode, public NoCopy, 35 FontWithFace::FontCharCollector 36 { 37 public: 38 struct GLTB 39 { 40 core::vector3df m_position; 41 video::SColor m_color; 42 short m_uv[2]; 43 }; 44 45 private: 46 struct STKTextBillboardChar 47 { 48 video::ITexture* m_texture; 49 50 core::rect<float> m_dest_rect; 51 52 core::rect<s32> m_source_rect; 53 54 // ------------------------------------------------------------------------ STKTextBillboardCharSTKTextBillboard::STKTextBillboardChar55 STKTextBillboardChar(video::ITexture* texture, 56 const core::rect<float>& dest_rect, 57 const core::rect<irr::s32>& source_rect, 58 const video::SColor* const colors) 59 { 60 m_texture = texture; 61 m_dest_rect = dest_rect; 62 m_source_rect = source_rect; 63 } 64 }; 65 66 SP::SPInstancedData m_instanced_data; 67 68 GLuint m_instanced_array = 0; 69 70 std::vector<STKTextBillboardChar>* m_chars = NULL; 71 72 video::SColor m_color_top; 73 74 video::SColor m_color_bottom; 75 76 std::unordered_map<video::ITexture*, std::vector<std::array<GLTB, 4> > > 77 m_gl_tbs; 78 79 std::unordered_map<video::ITexture*, std::pair<GLuint, GLuint> > 80 m_vao_vbos; 81 82 std::unordered_map<video::ITexture*, IMeshBuffer*> m_gl_mb; 83 84 core::aabbox3df m_bbox; 85 86 FontWithFace* m_face; 87 88 core::stringw m_text; 89 90 // ------------------------------------------------------------------------ 91 float getDefaultScale(FontWithFace* face); 92 public: 93 // ------------------------------------------------------------------------ 94 STKTextBillboard(const video::SColor& color_top, 95 const video::SColor& color_bottom, ISceneNode* parent, 96 ISceneManager* mgr, s32 id, 97 const core::vector3df& position, 98 const core::vector3df& scale = core::vector3df(1, 1, 1)); 99 // ------------------------------------------------------------------------ ~STKTextBillboard()100 ~STKTextBillboard() 101 { 102 clearBuffer(); 103 } 104 // ------------------------------------------------------------------------ clearBuffer()105 void clearBuffer() 106 { 107 #ifndef SERVER_ONLY 108 if (m_instanced_array != 0) 109 { 110 glDeleteBuffers(1, &m_instanced_array); 111 } 112 for (auto& p : m_vao_vbos) 113 { 114 glDeleteVertexArrays(1, &p.second.first); 115 glDeleteBuffers(1, &p.second.second); 116 } 117 m_vao_vbos.clear(); 118 for (auto& p : m_gl_mb) 119 { 120 p.second->drop(); 121 } 122 m_gl_mb.clear(); 123 m_gl_tbs.clear(); 124 #endif 125 } 126 // ------------------------------------------------------------------------ 127 void reload(); 128 // ------------------------------------------------------------------------ 129 virtual void collectChar(video::ITexture* texture, 130 const core::rect<float>& dest_rect, 131 const core::rect<irr::s32>& source_rect, 132 const video::SColor* const colors); 133 // ------------------------------------------------------------------------ 134 virtual void updateAbsolutePosition(); 135 // ------------------------------------------------------------------------ 136 virtual void OnRegisterSceneNode(); 137 // ------------------------------------------------------------------------ 138 virtual void render(); 139 // ------------------------------------------------------------------------ getBoundingBox() const140 virtual const core::aabbox3df& getBoundingBox() const { return m_bbox; } 141 // ------------------------------------------------------------------------ 142 void init(const core::stringw& text, FontWithFace* face); 143 // ------------------------------------------------------------------------ 144 void initLegacy(const core::stringw& text, FontWithFace* face); 145 // ------------------------------------------------------------------------ draw(video::ITexture * tex) const146 void draw(video::ITexture* tex) const 147 { 148 #ifndef SERVER_ONLY 149 glBindVertexArray(m_vao_vbos.at(tex).first); 150 for (unsigned i = 0; i < m_gl_tbs.at(tex).size(); i++) 151 { 152 glDrawArraysInstanced(GL_TRIANGLE_STRIP, i * 4, 4, 1); 153 } 154 #endif 155 } 156 // ------------------------------------------------------------------------ getAllTBTextures() const157 std::vector<video::ITexture*> getAllTBTextures() const 158 { 159 std::vector<video::ITexture*> ret; 160 for (auto& p : m_vao_vbos) 161 { 162 ret.push_back(p.first); 163 } 164 return ret; 165 } 166 // ------------------------------------------------------------------------ updateGLInstanceData() const167 void updateGLInstanceData() const 168 { 169 #ifndef SERVER_ONLY 170 glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array); 171 glBufferSubData(GL_ARRAY_BUFFER, 0, 36, m_instanced_data.getData()); 172 glBindBuffer(GL_ARRAY_BUFFER, 0); 173 #endif 174 } 175 // ------------------------------------------------------------------------ 176 static void updateAllTextBillboards(); 177 }; 178 179 #endif 180