1 /* 2 * Copyright 2011-2019 Branimir Karadzic. All rights reserved. 3 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 4 */ 5 6 #include "common.h" 7 #include "bgfx_utils.h" 8 #include "imgui/imgui.h" 9 10 #include <bx/rng.h> 11 12 namespace 13 { 14 15 const uint32_t kDimWidth = 11; 16 const uint32_t kDimHeight = 11; 17 18 struct PosColorVertex 19 { 20 float m_x; 21 float m_y; 22 float m_z; 23 uint32_t m_abgr; 24 init__anonbc9c2d2d0111::PosColorVertex25 static void init() 26 { 27 ms_layout 28 .begin() 29 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) 30 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) 31 .end(); 32 }; 33 34 static bgfx::VertexLayout ms_layout; 35 }; 36 37 bgfx::VertexLayout PosColorVertex::ms_layout; 38 39 static PosColorVertex s_cubeVertices[] = 40 { 41 {-1.0f, 1.0f, 1.0f, 0xff000000 }, 42 { 1.0f, 1.0f, 1.0f, 0xff0000ff }, 43 {-1.0f, -1.0f, 1.0f, 0xff00ff00 }, 44 { 1.0f, -1.0f, 1.0f, 0xff00ffff }, 45 {-1.0f, 1.0f, -1.0f, 0xffff0000 }, 46 { 1.0f, 1.0f, -1.0f, 0xffff00ff }, 47 {-1.0f, -1.0f, -1.0f, 0xffffff00 }, 48 { 1.0f, -1.0f, -1.0f, 0xffffffff }, 49 }; 50 51 static const uint16_t s_cubeTriList[] = 52 { 53 0, 1, 2, // 0 54 1, 3, 2, 55 4, 6, 5, // 2 56 5, 6, 7, 57 0, 2, 4, // 4 58 4, 2, 6, 59 1, 5, 3, // 6 60 5, 7, 3, 61 0, 4, 1, // 8 62 4, 5, 1, 63 2, 3, 6, // 10 64 6, 3, 7, 65 }; 66 67 static const uint16_t s_cubeTriStrip[] = 68 { 69 0, 1, 2, 70 3, 71 7, 72 1, 73 5, 74 0, 75 4, 76 2, 77 6, 78 7, 79 4, 80 5, 81 }; 82 83 class ExampleDynamic : public entry::AppI 84 { 85 public: ExampleDynamic(const char * _name,const char * _description,const char * _url)86 ExampleDynamic(const char* _name, const char* _description, const char* _url) 87 : entry::AppI(_name, _description, _url) 88 { 89 } 90 init(int32_t _argc,const char * const * _argv,uint32_t _width,uint32_t _height)91 void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override 92 { 93 BX_UNUSED(s_cubeTriList, s_cubeTriStrip); 94 95 Args args(_argc, _argv); 96 97 m_width = _width; 98 m_height = _height; 99 m_debug = BGFX_DEBUG_NONE; 100 m_reset = BGFX_RESET_VSYNC; 101 102 bgfx::Init init; 103 init.type = args.m_type; 104 init.vendorId = args.m_pciId; 105 init.resolution.width = m_width; 106 init.resolution.height = m_height; 107 init.resolution.reset = m_reset; 108 bgfx::init(init); 109 110 // Enable debug text. 111 bgfx::setDebug(m_debug); 112 113 // Set view 0 clear state. 114 bgfx::setViewClear(0 115 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH 116 , 0x303030ff 117 , 1.0f 118 , 0 119 ); 120 121 // Create vertex stream declaration. 122 PosColorVertex::init(); 123 124 // Create static vertex buffer. 125 for (uint32_t yy = 0; yy < kDimHeight; ++yy) 126 { 127 for (uint32_t xx = 0; xx < kDimWidth; ++xx) 128 { 129 m_vbh[yy*kDimWidth+xx] = bgfx::createDynamicVertexBuffer( 130 // Static data can be passed with bgfx::makeRef 131 bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ) 132 , PosColorVertex::ms_layout 133 ); 134 } 135 } 136 137 // Create static index buffer. 138 m_ibh = bgfx::createDynamicIndexBuffer( 139 // Static data can be passed with bgfx::makeRef 140 bgfx::makeRef(s_cubeTriStrip, sizeof(s_cubeTriStrip) ) 141 ); 142 143 // Create program from shaders. 144 m_program = loadProgram("vs_cubes", "fs_cubes"); 145 146 m_timeOffset = bx::getHPCounter(); 147 148 imguiCreate(); 149 } 150 shutdown()151 virtual int shutdown() override 152 { 153 imguiDestroy(); 154 155 // Cleanup. 156 bgfx::destroy(m_ibh); 157 for (uint32_t yy = 0; yy < kDimHeight; ++yy) 158 { 159 for (uint32_t xx = 0; xx < kDimWidth; ++xx) 160 { 161 bgfx::destroy(m_vbh[yy*kDimWidth+xx]); 162 } 163 } 164 165 bgfx::destroy(m_program); 166 167 // Shutdown bgfx. 168 bgfx::shutdown(); 169 170 return 0; 171 } 172 update()173 bool update() override 174 { 175 if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) 176 { 177 imguiBeginFrame(m_mouseState.m_mx 178 , m_mouseState.m_my 179 , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) 180 | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) 181 | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) 182 , m_mouseState.m_mz 183 , uint16_t(m_width) 184 , uint16_t(m_height) 185 ); 186 187 showExampleDialog(this); 188 189 imguiEndFrame(); 190 191 float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) ); 192 193 const bx::Vec3 at = { 0.0f, 0.0f, 0.0f }; 194 const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f }; 195 196 // Set view and projection matrix for view 0. 197 { 198 float view[16]; 199 bx::mtxLookAt(view, eye, at); 200 201 float proj[16]; 202 bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth); 203 bgfx::setViewTransform(0, view, proj); 204 205 // Set view 0 default viewport. 206 bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); 207 } 208 209 // This dummy draw call is here to make sure that view 0 is cleared 210 // if no other draw calls are submitted to view 0. 211 bgfx::touch(0); 212 213 { 214 float angle = bx::frnd(&m_mwc); 215 float mtx[16]; 216 bx::mtxRotateZ(mtx, angle); 217 218 const bgfx::Memory* mem = bgfx::copy(s_cubeVertices, sizeof(s_cubeVertices) ); 219 PosColorVertex* vertex = (PosColorVertex*)mem->data; 220 const uint32_t abgr = m_mwc.gen(); 221 for (uint32_t ii = 0; ii < BX_COUNTOF(s_cubeVertices); ++ii) 222 { 223 bx::store(&vertex[ii].m_x, bx::mul(bx::load<bx::Vec3>(&s_cubeVertices[ii].m_x), mtx) ); 224 vertex[ii].m_abgr = abgr; 225 } 226 227 uint32_t idx = m_mwc.gen() % (kDimWidth*kDimHeight); 228 bgfx::update(m_vbh[idx], 0, mem); 229 } 230 231 // Submit 11x11 cubes. 232 for (uint32_t yy = 0; yy < kDimHeight; ++yy) 233 { 234 for (uint32_t xx = 0; xx < kDimWidth; ++xx) 235 { 236 float mtx[16]; 237 bx::mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); 238 mtx[12] = -15.0f + float(xx)*3.0f; 239 mtx[13] = -15.0f + float(yy)*3.0f; 240 mtx[14] = 0.0f; 241 242 // Set model matrix for rendering. 243 bgfx::setTransform(mtx); 244 245 // Set vertex and index buffer. 246 bgfx::setVertexBuffer(0, m_vbh[yy*kDimWidth+xx]); 247 bgfx::setIndexBuffer(m_ibh); 248 249 // Set render states. 250 bgfx::setState(0 251 | BGFX_STATE_DEFAULT 252 | BGFX_STATE_PT_TRISTRIP 253 ); 254 255 // Submit primitive for rendering to view 0. 256 bgfx::submit(0, m_program); 257 } 258 } 259 260 // Advance to next frame. Rendering thread will be kicked to 261 // process submitted rendering primitives. 262 bgfx::frame(); 263 264 return true; 265 } 266 267 return false; 268 } 269 270 entry::MouseState m_mouseState; 271 272 bx::RngMwc m_mwc; 273 uint32_t m_width; 274 uint32_t m_height; 275 uint32_t m_debug; 276 uint32_t m_reset; 277 bgfx::DynamicVertexBufferHandle m_vbh[kDimWidth*kDimHeight]; 278 bgfx::DynamicIndexBufferHandle m_ibh; 279 bgfx::ProgramHandle m_program; 280 int64_t m_timeOffset; 281 }; 282 283 } // namespace 284 285 ENTRY_IMPLEMENT_MAIN( 286 ExampleDynamic 287 , "35-dynamic" 288 , "Dynamic buffers update." 289 , "https://bkaradzic.github.io/bgfx/examples.html#dynamic" 290 ); 291