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 namespace 11 { 12 13 struct PosColorVertex 14 { 15 float m_x; 16 float m_y; 17 float m_z; 18 uint32_t m_abgr; 19 init__anon19554fc80111::PosColorVertex20 static void init() 21 { 22 ms_layout 23 .begin() 24 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) 25 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) 26 .end(); 27 }; 28 29 static bgfx::VertexLayout ms_layout; 30 }; 31 32 bgfx::VertexLayout PosColorVertex::ms_layout; 33 34 static PosColorVertex s_cubeVertices[] = 35 { 36 {-1.0f, 1.0f, 1.0f, 0xff000000 }, 37 { 1.0f, 1.0f, 1.0f, 0xff0000ff }, 38 {-1.0f, -1.0f, 1.0f, 0xff00ff00 }, 39 { 1.0f, -1.0f, 1.0f, 0xff00ffff }, 40 {-1.0f, 1.0f, -1.0f, 0xffff0000 }, 41 { 1.0f, 1.0f, -1.0f, 0xffff00ff }, 42 {-1.0f, -1.0f, -1.0f, 0xffffff00 }, 43 { 1.0f, -1.0f, -1.0f, 0xffffffff }, 44 }; 45 46 static const uint16_t s_cubeTriList[] = 47 { 48 0, 1, 2, // 0 49 1, 3, 2, 50 4, 6, 5, // 2 51 5, 6, 7, 52 0, 2, 4, // 4 53 4, 2, 6, 54 1, 5, 3, // 6 55 5, 7, 3, 56 0, 4, 1, // 8 57 4, 5, 1, 58 2, 3, 6, // 10 59 6, 3, 7, 60 }; 61 62 static const uint16_t s_cubeTriStrip[] = 63 { 64 0, 1, 2, 65 3, 66 7, 67 1, 68 5, 69 0, 70 4, 71 2, 72 6, 73 7, 74 4, 75 5, 76 }; 77 78 static const uint16_t s_cubeLineList[] = 79 { 80 0, 1, 81 0, 2, 82 0, 4, 83 1, 3, 84 1, 5, 85 2, 3, 86 2, 6, 87 3, 7, 88 4, 5, 89 4, 6, 90 5, 7, 91 6, 7, 92 }; 93 94 static const uint16_t s_cubeLineStrip[] = 95 { 96 0, 2, 3, 1, 5, 7, 6, 4, 97 0, 2, 6, 4, 5, 7, 3, 1, 98 0, 99 }; 100 101 static const uint16_t s_cubePoints[] = 102 { 103 0, 1, 2, 3, 4, 5, 6, 7 104 }; 105 106 static const char* s_ptNames[] 107 { 108 "Triangle List", 109 "Triangle Strip", 110 "Lines", 111 "Line Strip", 112 "Points", 113 }; 114 115 static const uint64_t s_ptState[] 116 { 117 UINT64_C(0), 118 BGFX_STATE_PT_TRISTRIP, 119 BGFX_STATE_PT_LINES, 120 BGFX_STATE_PT_LINESTRIP, 121 BGFX_STATE_PT_POINTS, 122 }; 123 BX_STATIC_ASSERT(BX_COUNTOF(s_ptState) == BX_COUNTOF(s_ptNames) ); 124 125 class ExampleCubes : public entry::AppI 126 { 127 public: ExampleCubes(const char * _name,const char * _description,const char * _url)128 ExampleCubes(const char* _name, const char* _description, const char* _url) 129 : entry::AppI(_name, _description, _url) 130 , m_pt(0) 131 , m_r(true) 132 , m_g(true) 133 , m_b(true) 134 , m_a(true) 135 { 136 } 137 init(int32_t _argc,const char * const * _argv,uint32_t _width,uint32_t _height)138 void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override 139 { 140 Args args(_argc, _argv); 141 142 m_width = _width; 143 m_height = _height; 144 m_debug = BGFX_DEBUG_NONE; 145 m_reset = BGFX_RESET_VSYNC; 146 147 bgfx::Init init; 148 init.type = args.m_type; 149 init.vendorId = args.m_pciId; 150 init.resolution.width = m_width; 151 init.resolution.height = m_height; 152 init.resolution.reset = m_reset; 153 bgfx::init(init); 154 155 // Enable debug text. 156 bgfx::setDebug(m_debug); 157 158 // Set view 0 clear state. 159 bgfx::setViewClear(0 160 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH 161 , 0x303030ff 162 , 1.0f 163 , 0 164 ); 165 166 // Create vertex stream declaration. 167 PosColorVertex::init(); 168 169 // Create static vertex buffer. 170 m_vbh = bgfx::createVertexBuffer( 171 // Static data can be passed with bgfx::makeRef 172 bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ) 173 , PosColorVertex::ms_layout 174 ); 175 176 // Create static index buffer for triangle list rendering. 177 m_ibh[0] = bgfx::createIndexBuffer( 178 // Static data can be passed with bgfx::makeRef 179 bgfx::makeRef(s_cubeTriList, sizeof(s_cubeTriList) ) 180 ); 181 182 // Create static index buffer for triangle strip rendering. 183 m_ibh[1] = bgfx::createIndexBuffer( 184 // Static data can be passed with bgfx::makeRef 185 bgfx::makeRef(s_cubeTriStrip, sizeof(s_cubeTriStrip) ) 186 ); 187 188 // Create static index buffer for line list rendering. 189 m_ibh[2] = bgfx::createIndexBuffer( 190 // Static data can be passed with bgfx::makeRef 191 bgfx::makeRef(s_cubeLineList, sizeof(s_cubeLineList) ) 192 ); 193 194 // Create static index buffer for line strip rendering. 195 m_ibh[3] = bgfx::createIndexBuffer( 196 // Static data can be passed with bgfx::makeRef 197 bgfx::makeRef(s_cubeLineStrip, sizeof(s_cubeLineStrip) ) 198 ); 199 200 // Create static index buffer for point list rendering. 201 m_ibh[4] = bgfx::createIndexBuffer( 202 // Static data can be passed with bgfx::makeRef 203 bgfx::makeRef(s_cubePoints, sizeof(s_cubePoints) ) 204 ); 205 206 // Create program from shaders. 207 m_program = loadProgram("vs_cubes", "fs_cubes"); 208 209 m_timeOffset = bx::getHPCounter(); 210 211 imguiCreate(); 212 } 213 shutdown()214 virtual int shutdown() override 215 { 216 imguiDestroy(); 217 218 // Cleanup. 219 for (uint32_t ii = 0; ii < BX_COUNTOF(m_ibh); ++ii) 220 { 221 bgfx::destroy(m_ibh[ii]); 222 } 223 224 bgfx::destroy(m_vbh); 225 bgfx::destroy(m_program); 226 227 // Shutdown bgfx. 228 bgfx::shutdown(); 229 230 return 0; 231 } 232 update()233 bool update() override 234 { 235 if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) 236 { 237 imguiBeginFrame(m_mouseState.m_mx 238 , m_mouseState.m_my 239 , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) 240 | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) 241 | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) 242 , m_mouseState.m_mz 243 , uint16_t(m_width) 244 , uint16_t(m_height) 245 ); 246 247 showExampleDialog(this); 248 249 ImGui::SetNextWindowPos( 250 ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) 251 , ImGuiCond_FirstUseEver 252 ); 253 ImGui::SetNextWindowSize( 254 ImVec2(m_width / 5.0f, m_height / 3.5f) 255 , ImGuiCond_FirstUseEver 256 ); 257 ImGui::Begin("Settings" 258 , NULL 259 , 0 260 ); 261 262 ImGui::Checkbox("Write R", &m_r); 263 ImGui::Checkbox("Write G", &m_g); 264 ImGui::Checkbox("Write B", &m_b); 265 ImGui::Checkbox("Write A", &m_a); 266 267 ImGui::Text("Primitive topology:"); 268 ImGui::Combo("", (int*)&m_pt, s_ptNames, BX_COUNTOF(s_ptNames) ); 269 270 ImGui::End(); 271 272 imguiEndFrame(); 273 274 float time = (float)( (bx::getHPCounter()-m_timeOffset)/double(bx::getHPFrequency() ) ); 275 276 const bx::Vec3 at = { 0.0f, 0.0f, 0.0f }; 277 const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f }; 278 279 // Set view and projection matrix for view 0. 280 { 281 float view[16]; 282 bx::mtxLookAt(view, eye, at); 283 284 float proj[16]; 285 bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth); 286 bgfx::setViewTransform(0, view, proj); 287 288 // Set view 0 default viewport. 289 bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); 290 } 291 292 // This dummy draw call is here to make sure that view 0 is cleared 293 // if no other draw calls are submitted to view 0. 294 bgfx::touch(0); 295 296 bgfx::IndexBufferHandle ibh = m_ibh[m_pt]; 297 uint64_t state = 0 298 | (m_r ? BGFX_STATE_WRITE_R : 0) 299 | (m_g ? BGFX_STATE_WRITE_G : 0) 300 | (m_b ? BGFX_STATE_WRITE_B : 0) 301 | (m_a ? BGFX_STATE_WRITE_A : 0) 302 | BGFX_STATE_WRITE_Z 303 | BGFX_STATE_DEPTH_TEST_LESS 304 | BGFX_STATE_CULL_CW 305 | BGFX_STATE_MSAA 306 | s_ptState[m_pt] 307 ; 308 309 // Submit 11x11 cubes. 310 for (uint32_t yy = 0; yy < 11; ++yy) 311 { 312 for (uint32_t xx = 0; xx < 11; ++xx) 313 { 314 float mtx[16]; 315 bx::mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); 316 mtx[12] = -15.0f + float(xx)*3.0f; 317 mtx[13] = -15.0f + float(yy)*3.0f; 318 mtx[14] = 0.0f; 319 320 // Set model matrix for rendering. 321 bgfx::setTransform(mtx); 322 323 // Set vertex and index buffer. 324 bgfx::setVertexBuffer(0, m_vbh); 325 bgfx::setIndexBuffer(ibh); 326 327 // Set render states. 328 bgfx::setState(state); 329 330 // Submit primitive for rendering to view 0. 331 bgfx::submit(0, m_program); 332 } 333 } 334 335 // Advance to next frame. Rendering thread will be kicked to 336 // process submitted rendering primitives. 337 bgfx::frame(); 338 339 return true; 340 } 341 342 return false; 343 } 344 345 entry::MouseState m_mouseState; 346 347 uint32_t m_width; 348 uint32_t m_height; 349 uint32_t m_debug; 350 uint32_t m_reset; 351 bgfx::VertexBufferHandle m_vbh; 352 bgfx::IndexBufferHandle m_ibh[BX_COUNTOF(s_ptState)]; 353 bgfx::ProgramHandle m_program; 354 int64_t m_timeOffset; 355 int32_t m_pt; 356 357 bool m_r; 358 bool m_g; 359 bool m_b; 360 bool m_a; 361 }; 362 363 } // namespace 364 365 ENTRY_IMPLEMENT_MAIN( 366 ExampleCubes 367 , "01-cubes" 368 , "Rendering simple static mesh." 369 , "https://bkaradzic.github.io/bgfx/examples.html#cubes" 370 ); 371