int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); bgfx::UniformHandle s_texStipple = bgfx::createUniform("s_texStipple", bgfx::UniformType::Int1); bgfx::UniformHandle u_stipple = bgfx::createUniform("u_stipple", bgfx::UniformType::Vec4); bgfx::ProgramHandle program = loadProgram("vs_tree", "fs_tree"); bgfx::TextureHandle textureLeafs = loadTexture("leafs1.dds"); bgfx::TextureHandle textureBark = loadTexture("bark1.dds"); bgfx::TextureHandle textureStipple; const bgfx::Memory* stippleTex = bgfx::alloc(8*4); memset(stippleTex->data, 0, stippleTex->size); for (uint32_t ii = 0; ii < 32; ++ii) { stippleTex->data[knightTour[ii].m_y * 8 + knightTour[ii].m_x] = ii*4; } textureStipple = bgfx::createTexture2D(8, 4, 1 , bgfx::TextureFormat::R8 , BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIN_POINT , stippleTex ); Mesh* meshTop[3] = { meshLoad("meshes/tree1b_lod0_1.bin"), meshLoad("meshes/tree1b_lod1_1.bin"), meshLoad("meshes/tree1b_lod2_1.bin"), }; Mesh* meshTrunk[3] = { meshLoad("meshes/tree1b_lod0_2.bin"), meshLoad("meshes/tree1b_lod1_2.bin"), meshLoad("meshes/tree1b_lod2_2.bin"), }; // Imgui. imguiCreate(); const uint64_t stateCommon = 0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_CULL_CCW | BGFX_STATE_MSAA ; const uint64_t stateTransparent = stateCommon | BGFX_STATE_BLEND_ALPHA ; const uint64_t stateOpaque = stateCommon | BGFX_STATE_DEPTH_WRITE ; int32_t scrollArea = 0; bool transitions = true; int transitionFrame = 0; int currLOD = 0; int targetLOD = 0; float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.0f }; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Toggle transitions", width - width / 5 - 10, 10, width / 5, height / 6, &scrollArea); imguiSeparatorLine(); if (imguiButton(transitions ? "ON" : "OFF") ) { transitions = !transitions; } static float distance = 2.0f; imguiSlider("Distance", distance, 2.0f, 6.0f, .01f); imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/12-lod"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mesh LOD transitions."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); bgfx::dbgTextPrintf(0, 4, transitions ? 0x2f : 0x1f, transitions ? "Transitions on" : "Transitions off"); eye[2] = -distance; // Set view and projection matrix for view 0. const bgfx::HMD* hmd = bgfx::getHMD(); if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING)) { float view[16]; bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); float proj[16]; bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); bgfx::setViewTransform(0, view, proj); // Set view 0 default viewport. // // Use HMD's width/height since HMD's internal frame buffer size // might be much larger than window size. bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); } else { float view[16]; bx::mtxLookAt(view, eye, at); float proj[16]; bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewTransform(0, view, proj); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); } float mtx[16]; bx::mtxScale(mtx, 0.1f, 0.1f, 0.1f); float stipple[3]; float stippleInv[3]; const int currentLODframe = transitions ? 32-transitionFrame : 32; const int mainLOD = transitions ? currLOD : targetLOD; stipple[0] = 0.0f; stipple[1] = -1.0f; stipple[2] = (float(currentLODframe)*4.0f/255.0f) - (1.0f/255.0f); stippleInv[0] = (float(31)*4.0f/255.0f); stippleInv[1] = 1.0f; stippleInv[2] = (float(transitionFrame)*4.0f/255.0f) - (1.0f/255.0f); bgfx::setTexture(0, s_texColor, textureBark); bgfx::setTexture(1, s_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); meshSubmit(meshTrunk[mainLOD], 0, program, mtx, stateOpaque); bgfx::setTexture(0, s_texColor, textureLeafs); bgfx::setTexture(1, s_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); meshSubmit(meshTop[mainLOD], 0, program, mtx, stateTransparent); if (transitions && (transitionFrame != 0) ) { bgfx::setTexture(0, s_texColor, textureBark); bgfx::setTexture(1, s_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); meshSubmit(meshTrunk[targetLOD], 0, program, mtx, stateOpaque); bgfx::setTexture(0, s_texColor, textureLeafs); bgfx::setTexture(1, s_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); meshSubmit(meshTop[targetLOD], 0, program, mtx, stateTransparent); } int lod = 0; if (eye[2] < -2.5f) { lod = 1; } if (eye[2] < -5.0f) { lod = 2; } if (targetLOD!=lod) { if (targetLOD==currLOD) { targetLOD = lod; } } if (currLOD != targetLOD) { transitionFrame++; } if (transitionFrame>32) { currLOD = targetLOD; transitionFrame = 0; } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } imguiDestroy(); for (uint32_t ii = 0; ii < 3; ++ii) { meshUnload(meshTop[ii]); meshUnload(meshTrunk[ii]); } // Cleanup. bgfx::destroyProgram(program); bgfx::destroyUniform(s_texColor); bgfx::destroyUniform(s_texStipple); bgfx::destroyUniform(u_stipple); bgfx::destroyTexture(textureStipple); bgfx::destroyTexture(textureLeafs); bgfx::destroyTexture(textureBark); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { PosColorTexCoord0Vertex::init(); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x303030ff , 1.0f , 0 ); bgfx::TextureHandle uffizi = loadTexture("uffizi.dds", BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP); bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox"); bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum"); bgfx::ProgramHandle lumAvgProgram = loadProgram("vs_hdr_lumavg", "fs_hdr_lumavg"); bgfx::ProgramHandle blurProgram = loadProgram("vs_hdr_blur", "fs_hdr_blur"); bgfx::ProgramHandle brightProgram = loadProgram("vs_hdr_bright", "fs_hdr_bright"); bgfx::ProgramHandle meshProgram = loadProgram("vs_hdr_mesh", "fs_hdr_mesh"); bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap"); bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f); bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texLum = bgfx::createUniform("u_texLum", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texBlur = bgfx::createUniform("u_texBlur", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Uniform4fv, 16); Mesh* mesh = meshLoad("meshes/bunny.bin"); bgfx::FrameBufferHandle fbh; bgfx::TextureHandle fbtextures[] = { bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP), bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY), }; fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); bgfx::FrameBufferHandle lum[5]; lum[0] = bgfx::createFrameBuffer(128, 128, bgfx::TextureFormat::BGRA8); lum[1] = bgfx::createFrameBuffer( 64, 64, bgfx::TextureFormat::BGRA8); lum[2] = bgfx::createFrameBuffer( 16, 16, bgfx::TextureFormat::BGRA8); lum[3] = bgfx::createFrameBuffer( 4, 4, bgfx::TextureFormat::BGRA8); lum[4] = bgfx::createFrameBuffer( 1, 1, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle bright; bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle blur; blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8); void* data = load("font/droidsans.ttf"); imguiCreate(data); free(data); const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer; uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; float speed = 0.37f; float middleGray = 0.18f; float white = 1.1f; float treshold = 1.5f; int32_t scrollArea = 0; float time = 0.0f; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height || oldReset != reset) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; uint32_t msaa = (reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT; bgfx::destroyFrameBuffer(fbh); bgfx::destroyFrameBuffer(bright); bgfx::destroyFrameBuffer(blur); fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, ( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT)|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP); fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY|( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT) ); fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8); blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8); } imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea); imguiSeparatorLine(); imguiSlider("Speed", speed, 0.0f, 1.0f, 0.01f); imguiSeparator(); imguiSlider("Middle gray", middleGray, 0.1f, 1.0f, 0.01f); imguiSlider("White point", white, 0.1f, 2.0f, 0.01f); imguiSlider("Treshold", treshold, 0.1f, 2.0f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; time += (float)(frameTime*speed/freq); bgfx::setUniform(u_time, &time); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Set views. for (uint32_t ii = 0; ii < 6; ++ii) { bgfx::setViewRect(ii, 0, 0, width, height); } bgfx::setViewFrameBuffer(0, fbh); bgfx::setViewFrameBuffer(1, fbh); bgfx::setViewRect(2, 0, 0, 128, 128); bgfx::setViewFrameBuffer(2, lum[0]); bgfx::setViewRect(3, 0, 0, 64, 64); bgfx::setViewFrameBuffer(3, lum[1]); bgfx::setViewRect(4, 0, 0, 16, 16); bgfx::setViewFrameBuffer(4, lum[2]); bgfx::setViewRect(5, 0, 0, 4, 4); bgfx::setViewFrameBuffer(5, lum[3]); bgfx::setViewRect(6, 0, 0, 1, 1); bgfx::setViewFrameBuffer(6, lum[4]); bgfx::setViewRect(7, 0, 0, width/2, height/2); bgfx::setViewFrameBuffer(7, bright); bgfx::setViewRect(8, 0, 0, width/8, height/8); bgfx::setViewFrameBuffer(8, blur); bgfx::setViewRect(9, 0, 0, width, height); float view[16]; float proj[16]; bx::mtxIdentity(view); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. for (uint32_t ii = 0; ii < 10; ++ii) { bgfx::setViewTransform(ii, view, proj); } float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; float mtx[16]; bx::mtxRotateXY(mtx , 0.0f , time ); float temp[4]; bx::vec3MulMtx(temp, eye, mtx); bx::mtxLookAt(view, temp, at); bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransform(1, view, proj); bgfx::setUniform(u_mtx, mtx); // Render skybox into view 0. bgfx::setTexture(0, u_texCube, uffizi); bgfx::setProgram(skyProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); bgfx::submit(0); // Render mesh into view 1 bgfx::setTexture(0, u_texCube, uffizi); meshSubmit(mesh, 1, meshProgram, NULL); // Calculate luminance. setOffsets2x2Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setProgram(lumProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(128.0f, 128.0f, s_originBottomLeft); bgfx::submit(2); // Downscale luminance 0. setOffsets4x4Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, lum[0]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(64.0f, 64.0f, s_originBottomLeft); bgfx::submit(3); // Downscale luminance 1. setOffsets4x4Lum(u_offset, 64, 64); bgfx::setTexture(0, u_texColor, lum[1]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(16.0f, 16.0f, s_originBottomLeft); bgfx::submit(4); // Downscale luminance 2. setOffsets4x4Lum(u_offset, 16, 16); bgfx::setTexture(0, u_texColor, lum[2]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(4.0f, 4.0f, s_originBottomLeft); bgfx::submit(5); // Downscale luminance 3. setOffsets4x4Lum(u_offset, 4, 4); bgfx::setTexture(0, u_texColor, lum[3]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(1.0f, 1.0f, s_originBottomLeft); bgfx::submit(6); float tonemap[4] = { middleGray, square(white), treshold, 0.0f }; bgfx::setUniform(u_tonemap, tonemap); // Bright pass treshold is tonemap[3]. setOffsets4x4Lum(u_offset, width/2, height/2); bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setProgram(brightProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_originBottomLeft); bgfx::submit(7); // Blur bright pass vertically. bgfx::setTexture(0, u_texColor, bright); bgfx::setProgram(blurProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_originBottomLeft); bgfx::submit(8); // Blur bright pass horizontally, do tonemaping and combine. bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setTexture(2, u_texBlur, blur); bgfx::setProgram(tonemapProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, s_originBottomLeft); bgfx::submit(9); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); }
int _main_(int, char**) { uint32_t width = 800, height = 600; uint32_t debug = BGFX_DEBUG_TEXT | BGFX_DEBUG_STATS; uint32_t reset = BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X8; bool showStats = true; bgfx::init(); bgfx::reset(width, height, reset); bgfx::setDebug(debug); size_t sz = 0; void* fontdata = nullptr; if(loadfile("assets/font/droidsans.ttf", fontdata, sz)) imguiCreate(fontdata, sz); else imguiCreate(); free(fontdata); entry::MouseState mouseState; float rgb[3] = {0.3f, 0.3f, 0.3f}; bool colorwheelActivated = false; int32_t scrollArea = 0; while(!entry::processEvents(width, height, debug, reset, &mouseState)) { auto encodeColor = [&rgb]()->uint32_t{ return uint32_t(rgb[0]*255)<<24|uint32_t(rgb[1]*255)<<16|uint32_t(rgb[2]*255)<<8|0xff; }; bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, encodeColor(), 1.0f, 0); bgfx::setViewRect(0, 0, 0, width, height); bgfx::submit(0, BGFX_INVALID_HANDLE); bgfx::dbgTextPrintf(0, 1, 0x4f, "hello world"); bgfx::dbgTextPrintf(0, 2, 0x5f, "simple bgfx program"); imguiBeginFrame(mouseState.m_mx, mouseState.m_my, (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height); imguiBeginScrollArea("Test", width-350, 50, 330, 500, &scrollArea); imguiSeparatorLine(); imguiLabel("foobar"); if(imguiButton("say hi")) fprintf(stdout, "hi there\n"); imguiBool("show stats", showStats); uint32_t newDebug = BGFX_DEBUG_TEXT | (showStats ? BGFX_DEBUG_STATS : 0); if(newDebug != debug) { debug = newDebug; bgfx::setDebug(debug); } imguiColorWheel("bg color", rgb, colorwheelActivated); ImGui::ColorEdit3("bg color", rgb); imguiSeparatorLine(); if(imguiButton("quit")) break; imguiEndScrollArea(); imguiEndFrame(); bgfx::frame(); } imguiDestroy(); bgfx::shutdown(); return 0; }
void Gui::init() { imguiCreate(); }
int _main_(int _argc, char** _argv) { bx::CommandLine cmdLine(_argc, _argv); if (cmdLine.hasArg('h', "help") ) { help(); return EXIT_FAILURE; } else if (cmdLine.hasArg("associate") ) { associate(); return EXIT_FAILURE; } uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; inputAddBindings(s_bindingName[Binding::App], s_binding[Binding::App]); inputAddBindings(s_bindingName[Binding::View], s_binding[Binding::View]); View view; cmdAdd("view", cmdView, &view); bgfx::init(); bgfx::reset(width, height, reset); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x101010ff , 1.0f , 0 ); imguiCreate(); PosUvColorVertex::init(); bgfx::RendererType::Enum type = bgfx::getRendererType(); bgfx::ShaderHandle vsTexture = bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_texture"); bgfx::ShaderHandle fsTexture = bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture"); bgfx::ShaderHandle fsTextureArray = bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_array"); bgfx::ProgramHandle textureProgram = bgfx::createProgram( vsTexture , fsTexture , true ); bgfx::ProgramHandle textureArrayProgram = bgfx::createProgram( vsTexture , bgfx::isValid(fsTextureArray) ? fsTextureArray : fsTexture , true ); bgfx::ProgramHandle textureCubeProgram = bgfx::createProgram( bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_texture_cube") , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_cube") , true ); bgfx::ProgramHandle textureSDFProgram = bgfx::createProgram( vsTexture , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_sdf") , true); bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); float speed = 0.37f; float time = 0.0f; Interpolator mip(0.0f); Interpolator layer(0.0f); Interpolator zoom(1.0f); Interpolator scale(1.0f); const char* filePath = _argc < 2 ? "" : _argv[1]; bool directory = false; bx::FileInfo fi; bx::stat(filePath, fi); directory = bx::FileInfo::Directory == fi.m_type; std::string path = filePath; if (!directory) { const char* fileName = directory ? filePath : bx::baseName(filePath); path.assign(filePath, fileName); view.updateFileList(path.c_str(), fileName); } else { view.updateFileList(path.c_str() ); } int exitcode = EXIT_SUCCESS; bgfx::TextureHandle texture = BGFX_INVALID_HANDLE; if (view.m_fileList.empty() ) { exitcode = EXIT_FAILURE; if (2 > _argc) { help("File path is not specified."); } else { fprintf(stderr, "Unable to load '%s' texture.\n", filePath); } } else { uint32_t fileIndex = 0; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) , mouseState.m_mz , width , height ); static bool help = false; if (help == false && help != view.m_help) { ImGui::OpenPopup("Help"); } if (ImGui::BeginPopupModal("Help", NULL, ImGuiWindowFlags_AlwaysAutoResize) ) { ImGui::SetWindowFontScale(1.0f); ImGui::Text( "texturev, bgfx texture viewer tool " ICON_KI_WRENCH "\n" "Copyright 2011-2017 Branimir Karadzic. All rights reserved.\n" "License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause\n" ); ImGui::Separator(); ImGui::NextLine(); ImGui::Text("Key bindings:\n\n"); ImGui::PushFont(ImGui::Font::Mono); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "ESC"); ImGui::SameLine(64); ImGui::Text("Exit."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "h"); ImGui::SameLine(64); ImGui::Text("Toggle help screen."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "f"); ImGui::SameLine(64); ImGui::Text("Toggle full-screen."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "-"); ImGui::SameLine(64); ImGui::Text("Zoom out."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "="); ImGui::SameLine(64); ImGui::Text("Zoom in."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), ","); ImGui::SameLine(64); ImGui::Text("MIP level up."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "."); ImGui::SameLine(64); ImGui::Text("MIP level down."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "/"); ImGui::SameLine(64); ImGui::Text("Toggle linear/point texture sampling."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "left"); ImGui::SameLine(64); ImGui::Text("Previous layer in texture array."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "right"); ImGui::SameLine(64); ImGui::Text("Next layer in texture array."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "up"); ImGui::SameLine(64); ImGui::Text("Previous texture."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "down"); ImGui::SameLine(64); ImGui::Text("Next texture."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "r/g/b"); ImGui::SameLine(64); ImGui::Text("Toggle R, G, or B color channel."); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "a"); ImGui::SameLine(64); ImGui::Text("Toggle alpha blending."); ImGui::NextLine(); ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "s"); ImGui::SameLine(64); ImGui::Text("Toggle Multi-channel SDF rendering"); ImGui::PopFont(); ImGui::NextLine(); ImGui::Dummy(ImVec2(0.0f, 0.0f) ); ImGui::SameLine(ImGui::GetWindowWidth() - 136.0f); if (ImGui::Button("Close", ImVec2(128.0f, 0.0f) ) || !view.m_help) { view.m_help = false; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } help = view.m_help; imguiEndFrame(); if (!bgfx::isValid(texture) || view.m_fileIndex != fileIndex) { if (bgfx::isValid(texture) ) { bgfx::destroyTexture(texture); } fileIndex = view.m_fileIndex; filePath = view.m_fileList[view.m_fileIndex].c_str(); texture = loadTexture(filePath , 0 | BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_W_CLAMP , 0 , &view.m_info ); std::string title; bx::stringPrintf(title, "%s (%d x %d%s, %s)" , filePath , view.m_info.width , view.m_info.height , view.m_info.cubeMap ? " CubeMap" : "" , bgfx::getName(view.m_info.format) ); entry::WindowHandle handle = { 0 }; entry::setWindowTitle(handle, title.c_str() ); } int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); time += (float)(frameTime*speed/freq); float ortho[16]; bx::mtxOrtho(ortho, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f); bgfx::setViewTransform(0, NULL, ortho); bgfx::setViewRect(0, 0, 0, width, height); bgfx::touch(0); bgfx::dbgTextClear(); scale.set( bx::fmin( float(width) / float(view.m_info.width) , float(height) / float(view.m_info.height) ) , 0.1f ); zoom.set(view.m_zoom, 0.25); float ss = scale.getValue() * zoom.getValue(); screenQuad( int(width - view.m_info.width * ss)/2 , int(height - view.m_info.height * ss)/2 , int(view.m_info.width * ss) , int(view.m_info.height * ss) , view.m_abgr ); float mtx[16]; bx::mtxRotateXY(mtx, 0.0f, time); bgfx::setUniform(u_mtx, mtx); mip.set(float(view.m_mip), 0.5f); layer.set(float(view.m_layer), 0.25f); float params[4] = { mip.getValue(), layer.getValue(), 0.0f, 0.0f }; bgfx::setUniform(u_params, params); bgfx::setTexture(0 , s_texColor , texture , view.m_filter ? BGFX_TEXTURE_NONE : 0 | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MIP_POINT | BGFX_TEXTURE_MAG_POINT ); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | (view.m_alpha ? BGFX_STATE_BLEND_ALPHA : BGFX_STATE_NONE) ); bgfx::submit(0 , view.m_info.cubeMap ? textureCubeProgram : 1 < view.m_info.numLayers ? textureArrayProgram : view.m_sdf ? textureSDFProgram : textureProgram ); bgfx::frame(); } } if (bgfx::isValid(texture) ) { bgfx::destroyTexture(texture); } bgfx::destroyUniform(s_texColor); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_params); bgfx::destroyProgram(textureProgram); bgfx::destroyProgram(textureArrayProgram); bgfx::destroyProgram(textureCubeProgram); imguiDestroy(); bgfx::shutdown(); return exitcode; }
int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set clear color palette for index 0 bgfx::setClearColor(0, UINT32_C(0x00000000) ); // Set clear color palette for index 1 bgfx::setClearColor(1, UINT32_C(0x303030ff) ); // Set geometry pass view clear state. bgfx::setViewClear(RENDER_PASS_GEOMETRY_ID , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 1.0f , 0 , 1 ); // Set light pass view clear state. bgfx::setViewClear(RENDER_PASS_LIGHT_ID , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 1.0f , 0 , 0 ); // Create vertex stream declaration. PosNormalTangentTexcoordVertex::init(); PosTexCoord0Vertex::init(); DebugVertex::init(); calcTangents(s_cubeVertices , BX_COUNTOF(s_cubeVertices) , PosNormalTangentTexcoordVertex::ms_decl , s_cubeIndices , BX_COUNTOF(s_cubeIndices) ); // Create static vertex buffer. bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer( bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ) , PosNormalTangentTexcoordVertex::ms_decl ); // Create static index buffer. bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ) ); // Create texture sampler uniforms. bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_texNormal = bgfx::createUniform("s_texNormal", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_depth = bgfx::createUniform("s_depth", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_light = bgfx::createUniform("s_light", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv); // Create program from shaders. bgfx::ProgramHandle geomProgram = loadProgram("vs_deferred_geom", "fs_deferred_geom"); bgfx::ProgramHandle lightProgram = loadProgram("vs_deferred_light", "fs_deferred_light"); bgfx::ProgramHandle combineProgram = loadProgram("vs_deferred_combine", "fs_deferred_combine"); bgfx::ProgramHandle debugProgram = loadProgram("vs_deferred_debug", "fs_deferred_debug"); bgfx::ProgramHandle lineProgram = loadProgram("vs_deferred_debug_line", "fs_deferred_debug_line"); // Load diffuse texture. bgfx::TextureHandle textureColor = loadTexture("fieldstone-rgba.dds"); // Load normal texture. bgfx::TextureHandle textureNormal = loadTexture("fieldstone-n.dds"); bgfx::TextureHandle gbufferTex[3] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE }; bgfx::FrameBufferHandle gbuffer = BGFX_INVALID_HANDLE; bgfx::FrameBufferHandle lightBuffer = BGFX_INVALID_HANDLE; // Imgui. imguiCreate(); const int64_t timeOffset = bx::getHPCounter(); const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); const float texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer; // Get renderer capabilities info. const bgfx::Caps* caps = bgfx::getCaps(); uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; int32_t scrollArea = 0; int32_t numLights = 512; float lightAnimationSpeed = 0.3f; bool animateMesh = true; bool showScissorRects = false; bool showGBuffer = true; float view[16]; float initialPos[3] = { 0.0f, 0.0f, -15.0f }; cameraCreate(); cameraSetPosition(initialPos); cameraSetVerticalAngle(0.0f); cameraGetViewMtx(view); entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; const float deltaTime = float(frameTime/freq); float time = (float)( (now-timeOffset)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/21-deferred"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: MRT rendering and deferred shading."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); if (2 > caps->maxFBAttachments) { // When multiple render targets (MRT) is not supported by GPU, // implement alternative code path that doesn't use MRT. bool blink = uint32_t(time*3.0f)&1; bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " MRT not supported by GPU. "); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); } else { if (oldWidth != width || oldHeight != height || oldReset != reset || !bgfx::isValid(gbuffer) ) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; if (bgfx::isValid(gbuffer) ) { bgfx::destroyFrameBuffer(gbuffer); } const uint32_t samplerFlags = 0 | BGFX_TEXTURE_RT | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT | BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP ; gbufferTex[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, samplerFlags); gbufferTex[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, samplerFlags); gbufferTex[2] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D24, samplerFlags); gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(gbufferTex), gbufferTex, true); if (bgfx::isValid(lightBuffer) ) { bgfx::destroyFrameBuffer(lightBuffer); } lightBuffer = bgfx::createFrameBuffer(width, height, bgfx::TextureFormat::BGRA8, samplerFlags); } imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea); imguiSeparatorLine(); imguiSlider("Num lights", numLights, 1, 2048); if (imguiCheck("Show G-Buffer.", showGBuffer) ) { showGBuffer = !showGBuffer; } if (imguiCheck("Show light scissor.", showScissorRects) ) { showScissorRects = !showScissorRects; } if (imguiCheck("Animate mesh.", animateMesh) ) { animateMesh = !animateMesh; } imguiSlider("Lights animation speed", lightAnimationSpeed, 0.0f, 0.4f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // Update camera. cameraUpdate(deltaTime, mouseState); cameraGetViewMtx(view); // Setup views float vp[16]; float invMvp[16]; { bgfx::setViewRect(RENDER_PASS_GEOMETRY_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_LIGHT_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_COMBINE_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_DEBUG_LIGHTS_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_DEBUG_GBUFFER_ID, 0, 0, width, height); bgfx::setViewFrameBuffer(RENDER_PASS_LIGHT_ID, lightBuffer); float proj[16]; mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewFrameBuffer(RENDER_PASS_GEOMETRY_ID, gbuffer); bgfx::setViewTransform(RENDER_PASS_GEOMETRY_ID, view, proj); bx::mtxMul(vp, view, proj); bx::mtxInverse(invMvp, vp); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(RENDER_PASS_LIGHT_ID, NULL, proj); bgfx::setViewTransform(RENDER_PASS_COMBINE_ID, NULL, proj); const float aspectRatio = float(height)/float(width); const float size = 10.0f; bx::mtxOrtho(proj, -size, size, size*aspectRatio, -size*aspectRatio, 0.0f, 1000.0f); bgfx::setViewTransform(RENDER_PASS_DEBUG_GBUFFER_ID, NULL, proj); bx::mtxOrtho(proj, 0.0f, (float)width, 0.0f, (float)height, 0.0f, 1000.0f); bgfx::setViewTransform(RENDER_PASS_DEBUG_LIGHTS_ID, NULL, proj); } const uint32_t dim = 11; const float offset = (float(dim-1) * 3.0f) * 0.5f; // Draw into geometry pass. for (uint32_t yy = 0; yy < dim; ++yy) { for (uint32_t xx = 0; xx < dim; ++xx) { float mtx[16]; if (animateMesh) { bx::mtxRotateXY(mtx, time*1.023f + xx*0.21f, time*0.03f + yy*0.37f); } else { bx::mtxIdentity(mtx); } mtx[12] = -offset + float(xx)*3.0f; mtx[13] = -offset + float(yy)*3.0f; mtx[14] = 0.0f; // Set transform for draw call. bgfx::setTransform(mtx); // Set vertex and fragment shaders. bgfx::setProgram(geomProgram); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); // Bind textures. bgfx::setTexture(0, s_texColor, textureColor); bgfx::setTexture(1, s_texNormal, textureNormal); // Set render states. bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_WRITE | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_MSAA ); // Submit primitive for rendering to view 0. bgfx::submit(RENDER_PASS_GEOMETRY_ID); } } // Draw lights into light buffer. for (int32_t light = 0; light < numLights; ++light) { Sphere lightPosRadius; float lightTime = time * lightAnimationSpeed * (sinf(light/float(numLights) * bx::piHalf ) * 0.5f + 0.5f); lightPosRadius.m_center[0] = sinf( ( (lightTime + light*0.47f) + bx::piHalf*1.37f ) )*offset; lightPosRadius.m_center[1] = cosf( ( (lightTime + light*0.69f) + bx::piHalf*1.49f ) )*offset; lightPosRadius.m_center[2] = sinf( ( (lightTime + light*0.37f) + bx::piHalf*1.57f ) )*2.0f; lightPosRadius.m_radius = 2.0f; Aabb aabb; sphereToAabb(aabb, lightPosRadius); float box[8][3] = { { aabb.m_min[0], aabb.m_min[1], aabb.m_min[2] }, { aabb.m_min[0], aabb.m_min[1], aabb.m_max[2] }, { aabb.m_min[0], aabb.m_max[1], aabb.m_min[2] }, { aabb.m_min[0], aabb.m_max[1], aabb.m_max[2] }, { aabb.m_max[0], aabb.m_min[1], aabb.m_min[2] }, { aabb.m_max[0], aabb.m_min[1], aabb.m_max[2] }, { aabb.m_max[0], aabb.m_max[1], aabb.m_min[2] }, { aabb.m_max[0], aabb.m_max[1], aabb.m_max[2] }, }; float xyz[3]; bx::vec3MulMtxH(xyz, box[0], vp); float minx = xyz[0]; float miny = xyz[1]; float maxx = xyz[0]; float maxy = xyz[1]; float maxz = xyz[2]; for (uint32_t ii = 1; ii < 8; ++ii) { bx::vec3MulMtxH(xyz, box[ii], vp); minx = bx::fmin(minx, xyz[0]); miny = bx::fmin(miny, xyz[1]); maxx = bx::fmax(maxx, xyz[0]); maxy = bx::fmax(maxy, xyz[1]); maxz = bx::fmax(maxz, xyz[2]); } // Cull light if it's fully behind camera. if (maxz >= 0.0f) { float x0 = bx::fclamp( (minx * 0.5f + 0.5f) * width, 0.0f, (float)width); float y0 = bx::fclamp( (miny * 0.5f + 0.5f) * height, 0.0f, (float)height); float x1 = bx::fclamp( (maxx * 0.5f + 0.5f) * width, 0.0f, (float)width); float y1 = bx::fclamp( (maxy * 0.5f + 0.5f) * height, 0.0f, (float)height); if (showScissorRects) { bgfx::TransientVertexBuffer tvb; bgfx::TransientIndexBuffer tib; if (bgfx::allocTransientBuffers(&tvb, DebugVertex::ms_decl, 4, &tib, 8) ) { uint32_t abgr = 0x8000ff00; DebugVertex* vertex = (DebugVertex*)tvb.data; vertex->m_x = x0; vertex->m_y = y0; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x1; vertex->m_y = y0; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x1; vertex->m_y = y1; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x0; vertex->m_y = y1; vertex->m_z = 0.0f; vertex->m_abgr = abgr; uint16_t* indices = (uint16_t*)tib.data; *indices++ = 0; *indices++ = 1; *indices++ = 1; *indices++ = 2; *indices++ = 2; *indices++ = 3; *indices++ = 3; *indices++ = 0; bgfx::setProgram(lineProgram); bgfx::setVertexBuffer(&tvb); bgfx::setIndexBuffer(&tib); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_PT_LINES | BGFX_STATE_BLEND_ALPHA ); bgfx::submit(RENDER_PASS_DEBUG_LIGHTS_ID); } } uint8_t val = light&7; float lightRgbInnerR[4] = { val & 0x1 ? 1.0f : 0.25f, val & 0x2 ? 1.0f : 0.25f, val & 0x4 ? 1.0f : 0.25f, 0.8f, }; // Draw light. bgfx::setUniform(u_lightPosRadius, &lightPosRadius); bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR); bgfx::setUniform(u_mtx, invMvp); const uint16_t scissorHeight = uint16_t(y1-y0); bgfx::setScissor(uint16_t(x0), height-scissorHeight-uint16_t(y0), uint16_t(x1-x0), scissorHeight); bgfx::setTexture(0, s_normal, gbuffer, 1); bgfx::setTexture(1, s_depth, gbuffer, 2); bgfx::setProgram(lightProgram); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_BLEND_ADD ); screenSpaceQuad( (float)width, (float)height, texelHalf, s_originBottomLeft); bgfx::submit(RENDER_PASS_LIGHT_ID); } } // Combine color and light buffers. bgfx::setTexture(0, s_albedo, gbuffer, 0); bgfx::setTexture(1, s_light, lightBuffer, 0); bgfx::setProgram(combineProgram); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE ); screenSpaceQuad( (float)width, (float)height, texelHalf, s_originBottomLeft); bgfx::submit(RENDER_PASS_COMBINE_ID); if (showGBuffer) { const float aspectRatio = float(width)/float(height); // Draw debug GBuffer. for (uint32_t ii = 0; ii < BX_COUNTOF(gbufferTex); ++ii) { float mtx[16]; bx::mtxSRT(mtx , aspectRatio, 1.0f, 1.0f , 0.0f, 0.0f, 0.0f , -7.9f - BX_COUNTOF(gbufferTex)*0.1f*0.5f + ii*2.1f*aspectRatio, 4.0f, 0.0f ); bgfx::setTransform(mtx); bgfx::setProgram(debugProgram); bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh, 0, 6); bgfx::setTexture(0, s_texColor, gbufferTex[ii]); bgfx::setState(BGFX_STATE_RGB_WRITE); bgfx::submit(RENDER_PASS_DEBUG_GBUFFER_ID); } } } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. cameraDestroy(); imguiDestroy(); if (bgfx::isValid(gbuffer) ) { bgfx::destroyFrameBuffer(gbuffer); bgfx::destroyFrameBuffer(lightBuffer); } bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(geomProgram); bgfx::destroyProgram(lightProgram); bgfx::destroyProgram(combineProgram); bgfx::destroyProgram(debugProgram); bgfx::destroyProgram(lineProgram); bgfx::destroyTexture(textureColor); bgfx::destroyTexture(textureNormal); bgfx::destroyUniform(s_texColor); bgfx::destroyUniform(s_texNormal); bgfx::destroyUniform(s_albedo); bgfx::destroyUniform(s_normal); bgfx::destroyUniform(s_depth); bgfx::destroyUniform(s_light); bgfx::destroyUniform(u_lightPosRadius); bgfx::destroyUniform(u_lightRgbInnerR); bgfx::destroyUniform(u_mtx); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); // Create vertex stream declaration. PosColorVertex::init(); const bgfx::Memory* vs_drawstress; const bgfx::Memory* fs_drawstress; switch (bgfx::getRendererType() ) { case bgfx::RendererType::Direct3D9: vs_drawstress = bgfx::makeRef(vs_drawstress_dx9, sizeof(vs_drawstress_dx9) ); fs_drawstress = bgfx::makeRef(fs_drawstress_dx9, sizeof(fs_drawstress_dx9) ); break; case bgfx::RendererType::Direct3D11: case bgfx::RendererType::Direct3D12: vs_drawstress = bgfx::makeRef(vs_drawstress_dx11, sizeof(vs_drawstress_dx11) ); fs_drawstress = bgfx::makeRef(fs_drawstress_dx11, sizeof(fs_drawstress_dx11) ); break; default: vs_drawstress = bgfx::makeRef(vs_drawstress_glsl, sizeof(vs_drawstress_glsl) ); fs_drawstress = bgfx::makeRef(fs_drawstress_glsl, sizeof(fs_drawstress_glsl) ); break; } // Create program from shaders. program = bgfx::createProgram( bgfx::createShader(vs_drawstress) , bgfx::createShader(fs_drawstress) , true /* destroy shaders when program is destroyed */ ); const bgfx::Memory* mem; // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); vbh = bgfx::createVertexBuffer(mem, PosColorVertex::ms_decl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); ibh = bgfx::createIndexBuffer(mem); // Imgui. imguiCreate(); #if BX_PLATFORM_EMSCRIPTEN emscripten_set_main_loop(&loop, -1, 1); #else while (!mainloop() ); #endif // BX_PLATFORM_EMSCRIPTEN // Cleanup. imguiDestroy(); bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(program); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { // Create vertex stream declaration. PosColorVertex::init(); PosColorTexCoord0Vertex::init(); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Get renderer capabilities info. const bgfx::Caps* caps = bgfx::getCaps(); // Setup root path for binary shaders. Shader binaries are different // for each renderer. switch (caps->rendererType) { default: break; case bgfx::RendererType::OpenGL: case bgfx::RendererType::OpenGLES: s_flipV = true; break; } // Imgui. void* data = load("font/droidsans.ttf"); imguiCreate(data); free(data); const bgfx::Memory* mem; // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, PosColorVertex::ms_decl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem); // Create texture sampler uniforms. bgfx::UniformHandle u_texColor0 = bgfx::createUniform("u_texColor0", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_texColor1 = bgfx::createUniform("u_texColor1", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_color = bgfx::createUniform("u_color", bgfx::UniformType::Uniform4fv); bgfx::ProgramHandle blend = loadProgram("vs_oit", "fs_oit" ); bgfx::ProgramHandle wbSeparatePass = loadProgram("vs_oit", "fs_oit_wb_separate" ); bgfx::ProgramHandle wbSeparateBlit = loadProgram("vs_oit_blit", "fs_oit_wb_separate_blit" ); bgfx::ProgramHandle wbPass = loadProgram("vs_oit", "fs_oit_wb" ); bgfx::ProgramHandle wbBlit = loadProgram("vs_oit_blit", "fs_oit_wb_blit" ); bgfx::TextureHandle fbtextures[2] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE }; bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE; int64_t timeOffset = bx::getHPCounter(); uint32_t mode = 1; int32_t scrollArea = 0; bool frontToBack = true; bool fadeInOut = false; uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height || oldReset != reset || !bgfx::isValid(fbh) ) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; if (bgfx::isValid(fbh) ) { bgfx::destroyFrameBuffer(fbh); } fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT); fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT); fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); } imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Settings", width - width / 4 - 10, 10, width / 4, height / 3, &scrollArea); imguiSeparatorLine(); imguiLabel("Blend mode:"); mode = imguiChoose(mode , "None" , "Separate" , "MRT Independent" ); imguiSeparatorLine(); if (imguiCheck("Front to back", frontToBack) ) { frontToBack ^= true; } if (imguiCheck("Fade in/out", fadeInOut) ) { fadeInOut ^= true; } imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRectMask(0x3, 0, 0, width, height); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; float time = (float)( (now-timeOffset)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); // Reference: // Weighted, Blended Order-Independent Transparency // http://jcgt.org/published/0002/02/09/ // http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/19-oit"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Weighted, Blended Order Independent Transparency."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -7.0f }; float view[16]; float proj[16]; // Set view and projection matrix for view 0. bx::mtxLookAt(view, eye, at); bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewTransform(0, view, proj); bgfx::setViewClearMask(0x3 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x00000000 , 1.0f , 0 ); bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE; bgfx::setViewFrameBuffer(0, 0 == mode ? invalid : fbh); // Set view and projection matrix for view 1. bx::mtxIdentity(view); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(1, view, proj); for (uint32_t depth = 0; depth < 3; ++depth) { uint32_t zz = frontToBack ? 2-depth : depth; for (uint32_t yy = 0; yy < 3; ++yy) { for (uint32_t xx = 0; xx < 3; ++xx) { float color[4] = { xx*1.0f/3.0f, zz*1.0f/3.0f, yy*1.0f/3.0f, 0.5f }; if (fadeInOut && zz == 1) { color[3] = sinf(time*3.0f)*0.49f+0.5f; } bgfx::setUniform(u_color, color); BX_UNUSED(time); float mtx[16]; bx::mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); //mtxIdentity(mtx); mtx[12] = -2.5f + float(xx)*2.5f; mtx[13] = -2.5f + float(yy)*2.5f; mtx[14] = -2.5f + float(zz)*2.5f; //0.0f; // sinf(time + ( (xx+1)*(yy+1)/9.0f)*float(M_PI) )*50.0f+50.0f; //90.0f - (xx+1)*(yy+1)*10.0f; // Set transform for draw call. bgfx::setTransform(mtx); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); const uint64_t state = 0 | BGFX_STATE_CULL_CW | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_MSAA ; switch (mode) { case 0: // Set vertex and fragment shaders. bgfx::setProgram(blend); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_ALPHA ); break; case 1: // Set vertex and fragment shaders. bgfx::setProgram(wbSeparatePass); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); break; default: // Set vertex and fragment shaders. bgfx::setProgram(wbPass); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) | BGFX_STATE_BLEND_INDEPENDENT , 0 | BGFX_STATE_BLEND_FUNC_RT_1(BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_SRC_COLOR) ); break; } // Submit primitive for rendering to view 0. bgfx::submit(0); } } } if (0 != mode) { bgfx::setTexture(0, u_texColor0, fbtextures[0]); bgfx::setTexture(1, u_texColor1, fbtextures[1]); bgfx::setProgram(1 == mode ? wbSeparateBlit : wbBlit); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_SRC_ALPHA, BGFX_STATE_BLEND_SRC_ALPHA) ); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(1); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. imguiDestroy(); bgfx::destroyFrameBuffer(fbh); bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(blend); bgfx::destroyProgram(wbSeparatePass); bgfx::destroyProgram(wbSeparateBlit); bgfx::destroyProgram(wbPass); bgfx::destroyProgram(wbBlit); bgfx::destroyUniform(u_texColor0); bgfx::destroyUniform(u_texColor1); bgfx::destroyUniform(u_color); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int _argc, char** _argv) { Args args(_argc, _argv); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = 0 | BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X16 ; bgfx::init(args.m_type, args.m_pciId); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set views clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); // Imgui. imguiCreate(); // Uniforms. Uniforms uniforms; uniforms.init(); // Vertex declarations. PosColorTexCoord0Vertex::init(); LightProbe lightProbes[LightProbe::Count]; lightProbes[LightProbe::Bolonga].load("bolonga"); lightProbes[LightProbe::Kyoto ].load("kyoto"); LightProbe::Enum currentLightProbe = LightProbe::Bolonga; bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Vec4); bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Vec4); bgfx::UniformHandle s_texCube = bgfx::createUniform("s_texCube", bgfx::UniformType::Int1); bgfx::UniformHandle s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1); bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh"); bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox"); Mesh* meshBunny; meshBunny = meshLoad("meshes/bunny.bin"); Mesh* meshOrb; meshOrb = meshLoad("meshes/orb.bin"); Camera camera; Mouse mouse; struct Settings { Settings() { m_envRotCurr = 0.0f; m_envRotDest = 0.0f; m_lightDir[0] = -0.8f; m_lightDir[1] = 0.2f; m_lightDir[2] = -0.5f; m_lightCol[0] = 1.0f; m_lightCol[1] = 1.0f; m_lightCol[2] = 1.0f; m_glossiness = 0.7f; m_exposure = 0.0f; m_bgType = 3.0f; m_radianceSlider = 2.0f; m_reflectivity = 0.85f; m_rgbDiff[0] = 1.0f; m_rgbDiff[1] = 1.0f; m_rgbDiff[2] = 1.0f; m_rgbSpec[0] = 1.0f; m_rgbSpec[1] = 1.0f; m_rgbSpec[2] = 1.0f; m_lod = 0.0f; m_doDiffuse = false; m_doSpecular = false; m_doDiffuseIbl = true; m_doSpecularIbl = true; m_showLightColorWheel = true; m_showDiffColorWheel = true; m_showSpecColorWheel = true; m_metalOrSpec = 0; m_meshSelection = 0; m_crossCubemapPreview = ImguiCubemap::Latlong; } float m_envRotCurr; float m_envRotDest; float m_lightDir[3]; float m_lightCol[3]; float m_glossiness; float m_exposure; float m_radianceSlider; float m_bgType; float m_reflectivity; float m_rgbDiff[3]; float m_rgbSpec[3]; float m_lod; bool m_doDiffuse; bool m_doSpecular; bool m_doDiffuseIbl; bool m_doSpecularIbl; bool m_showLightColorWheel; bool m_showDiffColorWheel; bool m_showSpecColorWheel; uint8_t m_metalOrSpec; uint8_t m_meshSelection; ImguiCubemap::Enum m_crossCubemapPreview; }; Settings settings; int32_t leftScrollArea = 0; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) , mouseState.m_mz , uint16_t(width) , uint16_t(height) ); static int32_t rightScrollArea = 0; imguiBeginScrollArea("", width - 256 - 10, 10, 256, 700, &rightScrollArea); imguiLabel("Environment light:"); imguiIndent(); imguiBool("IBL Diffuse", settings.m_doDiffuseIbl); imguiBool("IBL Specular", settings.m_doSpecularIbl); currentLightProbe = LightProbe::Enum(imguiTabs( uint8_t(currentLightProbe) , true , ImguiAlign::LeftIndented , 16 , 2 , 2 , "Bolonga" , "Kyoto" ) ); if (imguiCube(lightProbes[currentLightProbe].m_tex, settings.m_lod, settings.m_crossCubemapPreview, true) ) { settings.m_crossCubemapPreview = ImguiCubemap::Enum( (settings.m_crossCubemapPreview+1) % ImguiCubemap::Count); } imguiSlider("Texture LOD", settings.m_lod, 0.0f, 10.1f, 0.1f); imguiUnindent(); imguiSeparator(8); imguiLabel("Directional light:"); imguiIndent(); imguiBool("Diffuse", settings.m_doDiffuse); imguiBool("Specular", settings.m_doSpecular); const bool doDirectLighting = settings.m_doDiffuse || settings.m_doSpecular; imguiSlider("Light direction X", settings.m_lightDir[0], -1.0f, 1.0f, 0.1f, doDirectLighting); imguiSlider("Light direction Y", settings.m_lightDir[1], -1.0f, 1.0f, 0.1f, doDirectLighting); imguiSlider("Light direction Z", settings.m_lightDir[2], -1.0f, 1.0f, 0.1f, doDirectLighting); imguiColorWheel("Color:", settings.m_lightCol, settings.m_showLightColorWheel, 0.6f, doDirectLighting); imguiUnindent(); imguiSeparator(8); imguiLabel("Background:"); imguiIndent(); { int32_t selection; if (0.0f == settings.m_bgType) { selection = UINT8_C(0); } else if (7.0f == settings.m_bgType) { selection = UINT8_C(2); } else { selection = UINT8_C(1); } selection = imguiTabs( uint8_t(selection) , true , ImguiAlign::LeftIndented , 16 , 2 , 3 , "Skybox" , "Radiance" , "Irradiance" ); if (0 == selection) { settings.m_bgType = 0.0f; } else if (2 == selection) { settings.m_bgType = 7.0f; } else { settings.m_bgType = settings.m_radianceSlider; } const bool isRadiance = (selection == 1); imguiSlider("Mip level", settings.m_radianceSlider, 1.0f, 6.0f, 0.1f, isRadiance); } imguiUnindent(); imguiSeparator(8); imguiLabel("Post processing:"); imguiIndent(); imguiSlider("Exposure", settings.m_exposure, -4.0f, 4.0f, 0.1f); imguiUnindent(); imguiSeparator(); imguiEndScrollArea(); imguiBeginScrollArea("", 10, 70, 256, 636, &leftScrollArea); imguiLabel("Mesh:"); imguiIndent(); settings.m_meshSelection = uint8_t(imguiChoose(settings.m_meshSelection, "Bunny", "Orbs") ); imguiUnindent(); const bool isBunny = (0 == settings.m_meshSelection); if (!isBunny) { settings.m_metalOrSpec = 0; } imguiSeparator(4); imguiLabel("Workflow:"); imguiIndent(); if (imguiCheck("Metalness", 0 == settings.m_metalOrSpec, isBunny) ) { settings.m_metalOrSpec = 0; } if (imguiCheck("Specular", 1 == settings.m_metalOrSpec, isBunny) ) { settings.m_metalOrSpec = 1; } imguiUnindent(); imguiSeparator(4); imguiLabel("Material:"); imguiIndent(); imguiSlider("Glossiness", settings.m_glossiness, 0.0f, 1.0f, 0.01f, isBunny); imguiSlider(0 == settings.m_metalOrSpec ? "Metalness" : "Diffuse - Specular", settings.m_reflectivity, 0.0f, 1.0f, 0.01f, isBunny); imguiUnindent(); imguiColorWheel("Diffuse:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel, 0.7f); imguiSeparator(); imguiColorWheel("Specular:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel, 0.7f, (1 == settings.m_metalOrSpec) && isBunny); imguiEndScrollArea(); imguiEndFrame(); uniforms.m_glossiness = settings.m_glossiness; uniforms.m_reflectivity = settings.m_reflectivity; uniforms.m_exposure = settings.m_exposure; uniforms.m_bgType = settings.m_bgType; uniforms.m_metalOrSpec = float(settings.m_metalOrSpec); uniforms.m_doDiffuse = float(settings.m_doDiffuse); uniforms.m_doSpecular = float(settings.m_doSpecular); uniforms.m_doDiffuseIbl = float(settings.m_doDiffuseIbl); uniforms.m_doSpecularIbl = float(settings.m_doSpecularIbl); bx::memCopy(uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) ); bx::memCopy(uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) ); bx::memCopy(uniforms.m_lightDir, settings.m_lightDir, 3*sizeof(float) ); bx::memCopy(uniforms.m_lightCol, settings.m_lightCol, 3*sizeof(float) ); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; const float deltaTimeSec = float(double(frameTime)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image-based lighting."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Camera. const bool mouseOverGui = imguiMouseOverArea(); mouse.update(float(mouseState.m_mx), float(mouseState.m_my), mouseState.m_mz, width, height); if (!mouseOverGui) { if (mouseState.m_buttons[entry::MouseButton::Left]) { camera.orbit(mouse.m_dx, mouse.m_dy); } else if (mouseState.m_buttons[entry::MouseButton::Right]) { camera.dolly(mouse.m_dx + mouse.m_dy); } else if (mouseState.m_buttons[entry::MouseButton::Middle]) { settings.m_envRotDest += mouse.m_dx*2.0f; } else if (0 != mouse.m_scroll) { camera.dolly(float(mouse.m_scroll)*0.05f); } } camera.update(deltaTimeSec); bx::memCopy(uniforms.m_cameraPos, camera.m_pos.curr, 3*sizeof(float) ); // View Transform 0. float view[16]; float proj[16]; bx::mtxIdentity(view); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(0, view, proj); // View Transform 1. camera.mtxLookAt(view); bx::mtxProj(proj, 45.0f, float(width)/float(height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth); bgfx::setViewTransform(1, view, proj); // View rect. bgfx::setViewRect(0, 0, 0, uint16_t(width), uint16_t(height) ); bgfx::setViewRect(1, 0, 0, uint16_t(width), uint16_t(height) ); // Env rotation. const float amount = bx::fmin(deltaTimeSec/0.12f, 1.0f); settings.m_envRotCurr = bx::flerp(settings.m_envRotCurr, settings.m_envRotDest, amount); // Env mtx. float mtxEnvView[16]; camera.envViewMtx(mtxEnvView); float mtxEnvRot[16]; bx::mtxRotateY(mtxEnvRot, settings.m_envRotCurr); bx::mtxMul(uniforms.m_mtx, mtxEnvView, mtxEnvRot); // Used for Skybox. // Submit view 0. bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); uniforms.submit(); bgfx::submit(0, programSky); // Submit view 1. bx::memCopy(uniforms.m_mtx, mtxEnvRot, 16*sizeof(float)); // Used for IBL. if (0 == settings.m_meshSelection) { // Submit bunny. float mtx[16]; bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, 0.0f, bx::pi, 0.0f, 0.0f, -0.80f, 0.0f); bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); uniforms.submit(); meshSubmit(meshBunny, 1, programMesh, mtx); } else { // Submit orbs. for (float yy = 0, yend = 5.0f; yy < yend; yy+=1.0f) { for (float xx = 0, xend = 5.0f; xx < xend; xx+=1.0f) { const float scale = 1.2f; const float spacing = 2.2f; const float yAdj = -0.8f; float mtx[16]; bx::mtxSRT(mtx , scale/xend , scale/xend , scale/xend , 0.0f , 0.0f , 0.0f , 0.0f + (xx/xend)*spacing - (1.0f + (scale-1.0f)*0.5f - 1.0f/xend) , yAdj/yend + (yy/yend)*spacing - (1.0f + (scale-1.0f)*0.5f - 1.0f/yend) , 0.0f ); uniforms.m_glossiness = xx*(1.0f/xend); uniforms.m_reflectivity = (yend-yy)*(1.0f/yend); uniforms.m_metalOrSpec = 0.0f; uniforms.submit(); bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); meshSubmit(meshOrb, 1, programMesh, mtx); } } } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } meshUnload(meshBunny); meshUnload(meshOrb); // Cleanup. bgfx::destroyProgram(programMesh); bgfx::destroyProgram(programSky); bgfx::destroyUniform(u_camPos); bgfx::destroyUniform(u_flags); bgfx::destroyUniform(u_params); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(s_texCube); bgfx::destroyUniform(s_texCubeIrr); for (uint8_t ii = 0; ii < LightProbe::Count; ++ii) { lightProbes[ii].destroy(); } uniforms.destroy(); imguiDestroy(); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int _argc, char** _argv) { Args args(_argc, _argv); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(args.m_type, args.m_pciId); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set views clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); // Imgui. imguiCreate(); // Uniforms. s_uniforms.init(); // Vertex declarations. PosColorTexCoord0Vertex::init(); LightProbe lightProbes[LightProbe::Count]; lightProbes[LightProbe::Wells ].load("wells"); lightProbes[LightProbe::Uffizi].load("uffizi"); lightProbes[LightProbe::Pisa ].load("pisa"); lightProbes[LightProbe::Ennis ].load("ennis"); lightProbes[LightProbe::Grace ].load("grace"); LightProbe::Enum currentLightProbe = LightProbe::Wells; bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Vec4); bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Vec4); bgfx::UniformHandle s_texCube = bgfx::createUniform("s_texCube", bgfx::UniformType::Int1); bgfx::UniformHandle s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1); bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh"); bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox"); Mesh* meshBunny; meshBunny = meshLoad("meshes/bunny.bin"); struct Settings { float m_speed; float m_glossiness; float m_exposure; float m_diffspec; float m_rgbDiff[3]; float m_rgbSpec[3]; bool m_diffuse; bool m_specular; bool m_diffuseIbl; bool m_specularIbl; bool m_showDiffColorWheel; bool m_showSpecColorWheel; ImguiCubemap::Enum m_crossCubemapPreview; }; Settings settings; settings.m_speed = 0.37f; settings.m_glossiness = 1.0f; settings.m_exposure = 0.0f; settings.m_diffspec = 0.65f; settings.m_rgbDiff[0] = 0.2f; settings.m_rgbDiff[1] = 0.2f; settings.m_rgbDiff[2] = 0.2f; settings.m_rgbSpec[0] = 1.0f; settings.m_rgbSpec[1] = 1.0f; settings.m_rgbSpec[2] = 1.0f; settings.m_diffuse = true; settings.m_specular = true; settings.m_diffuseIbl = true; settings.m_specularIbl = true; settings.m_showDiffColorWheel = true; settings.m_showSpecColorWheel = false; settings.m_crossCubemapPreview = ImguiCubemap::Cross; float time = 0.0f; int32_t leftScrollArea = 0; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) , mouseState.m_mz , width , height ); static int32_t rightScrollArea = 0; imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 540, &rightScrollArea); imguiLabel("Shade:"); imguiSeparator(); imguiBool("Diffuse", settings.m_diffuse); imguiBool("Specular", settings.m_specular); imguiBool("IBL Diffuse", settings.m_diffuseIbl); imguiBool("IBL Specular", settings.m_specularIbl); imguiSeparatorLine(); imguiSlider("Speed", settings.m_speed, 0.0f, 1.0f, 0.01f); imguiSeparatorLine(); imguiSeparator(); imguiSlider("Exposure", settings.m_exposure, -8.0f, 8.0f, 0.01f); imguiSeparator(); imguiLabel("Environment:"); currentLightProbe = LightProbe::Enum(imguiChoose(currentLightProbe , "Wells" , "Uffizi" , "Pisa" , "Ennis" , "Grace" ) ); static float lod = 0.0f; if (imguiCube(lightProbes[currentLightProbe].m_tex, lod, settings.m_crossCubemapPreview, true) ) { settings.m_crossCubemapPreview = ImguiCubemap::Enum( (settings.m_crossCubemapPreview+1) % ImguiCubemap::Count); } imguiSlider("Texture LOD", lod, 0.0f, 10.1f, 0.1f); imguiEndScrollArea(); imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea); imguiLabel("Material properties:"); imguiSeparator(); imguiSlider("Diffuse - Specular", settings.m_diffspec, 0.0f, 1.0f, 0.01f); imguiSlider("Glossiness" , settings.m_glossiness, 0.0f, 1.0f, 0.01f); imguiSeparator(); imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel); imguiSeparator(); imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel); imguiSeparator(); imguiLabel("Predefined materials:"); imguiSeparator(); if (imguiButton("Gold") ) { settings.m_glossiness = 0.8f; settings.m_diffspec = 1.0f; settings.m_rgbDiff[0] = 0.0f; settings.m_rgbDiff[1] = 0.0f; settings.m_rgbDiff[2] = 0.0f; settings.m_rgbSpec[0] = 1.0f; settings.m_rgbSpec[1] = 0.86f; settings.m_rgbSpec[2] = 0.58f; } if (imguiButton("Copper") ) { settings.m_glossiness = 0.67f; settings.m_diffspec = 1.0f; settings.m_rgbDiff[0] = 0.0f; settings.m_rgbDiff[1] = 0.0f; settings.m_rgbDiff[2] = 0.0f; settings.m_rgbSpec[0] = 0.98f; settings.m_rgbSpec[1] = 0.82f; settings.m_rgbSpec[2] = 0.76f; } if (imguiButton("Titanium") ) { settings.m_glossiness = 0.57f; settings.m_diffspec = 1.0f; settings.m_rgbDiff[0] = 0.0f; settings.m_rgbDiff[1] = 0.0f; settings.m_rgbDiff[2] = 0.0f; settings.m_rgbSpec[0] = 0.76f; settings.m_rgbSpec[1] = 0.73f; settings.m_rgbSpec[2] = 0.71f; } if (imguiButton("Steel") ) { settings.m_glossiness = 0.82f; settings.m_diffspec = 1.0f; settings.m_rgbDiff[0] = 0.0f; settings.m_rgbDiff[1] = 0.0f; settings.m_rgbDiff[2] = 0.0f; settings.m_rgbSpec[0] = 0.77f; settings.m_rgbSpec[1] = 0.78f; settings.m_rgbSpec[2] = 0.77f; } imguiEndScrollArea(); imguiEndFrame(); s_uniforms.m_glossiness = settings.m_glossiness; s_uniforms.m_exposure = settings.m_exposure; s_uniforms.m_diffspec = settings.m_diffspec; s_uniforms.m_flags[0] = float(settings.m_diffuse); s_uniforms.m_flags[1] = float(settings.m_specular); s_uniforms.m_flags[2] = float(settings.m_diffuseIbl); s_uniforms.m_flags[3] = float(settings.m_specularIbl); memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) ); memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) ); s_uniforms.submitPerFrameUniforms(); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; time += (float)(frameTime*settings.m_speed/freq); s_uniforms.m_camPosTime[3] = time; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image based lightning."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -3.0f }; bx::mtxRotateXY(s_uniforms.m_mtx , 0.0f , time ); float view[16]; float proj[16]; bx::mtxIdentity(view); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(0, view, proj); bx::mtxLookAt(view, eye, at); memcpy(s_uniforms.m_camPosTime, eye, 3*sizeof(float) ); bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewTransform(1, view, proj); bgfx::setViewRect(0, 0, 0, width, height); bgfx::setViewRect(1, 0, 0, width, height); // View 0. bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); s_uniforms.submitPerDrawUniforms(); bgfx::submit(0, programSky); // View 1. float mtx[16]; bx::mtxSRT(mtx , 1.0f , 1.0f , 1.0f , 0.0f , bx::pi+time , 0.0f , 0.0f , -1.0f , 0.0f ); bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); meshSubmit(meshBunny, 1, programMesh, mtx); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } meshUnload(meshBunny); // Cleanup. bgfx::destroyProgram(programMesh); bgfx::destroyProgram(programSky); bgfx::destroyUniform(u_camPos); bgfx::destroyUniform(u_flags); bgfx::destroyUniform(u_params); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(s_texCube); bgfx::destroyUniform(s_texCubeIrr); for (uint8_t ii = 0; ii < LightProbe::Count; ++ii) { lightProbes[ii].destroy(); } s_uniforms.destroy(); imguiDestroy(); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); // Imgui. imguiCreate(); char* bigText = loadText( "text/sherlock_holmes_a_scandal_in_bohemia_arthur_conan_doyle.txt"); // Init the text rendering system. FontManager* fontManager = new FontManager(512); TextBufferManager* textBufferManager = new TextBufferManager(fontManager); TrueTypeHandle font = loadTtf(fontManager, "font/special_elite.ttf"); // Create a distance field font. FontHandle fontSdf = fontManager->createFontByPixelSize(font, 0, 48, FONT_TYPE_DISTANCE); // Create a scaled down version of the same font (without adding anything to the atlas). FontHandle fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, 14); TextLineMetrics metrics(fontManager->getFontInfo(fontScaled) ); uint32_t lineCount = metrics.getLineCount(bigText); float visibleLineCount = 20.0f; const char* textBegin = 0; const char* textEnd = 0; metrics.getSubText(bigText, 0, (uint32_t)visibleLineCount, textBegin, textEnd); TextBufferHandle scrollableBuffer = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, BufferType::Transient); textBufferManager->setTextColor(scrollableBuffer, 0xFFFFFFFF); textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd); entry::MouseState mouseState; int32_t scrollArea = 0; const int32_t guiPanelWidth = 250; const int32_t guiPanelHeight = 200; float textScroll = 0.0f; float textRotation = 0.0f; float textScale = 1.0f; float textSize = 14.0f; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , mouseState.m_mz , width , height ); imguiBeginScrollArea("Text Area" , width - guiPanelWidth - 10 , 10 , guiPanelWidth , guiPanelHeight , &scrollArea ); imguiSeparatorLine(); bool recomputeVisibleText = false; recomputeVisibleText |= imguiSlider("Number of lines", visibleLineCount, 1.0f, 177.0f , 1.0f); if (imguiSlider("Font size", textSize, 6.0f, 64.0f , 1.0f) ) { fontManager->destroyFont(fontScaled); fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, (uint32_t) textSize); metrics = TextLineMetrics(fontManager->getFontInfo(fontScaled) ); recomputeVisibleText = true; } recomputeVisibleText |= imguiSlider("Scroll", textScroll, 0.0f, (lineCount-visibleLineCount) , 1.0f); imguiSlider("Rotate", textRotation, 0.0f, bx::pi*2.0f , 0.1f); recomputeVisibleText |= imguiSlider("Scale", textScale, 0.1f, 10.0f , 0.1f); if (recomputeVisibleText) { textBufferManager->clearTextBuffer(scrollableBuffer); metrics.getSubText(bigText,(uint32_t)textScroll, (uint32_t)(textScroll+visibleLineCount), textBegin, textEnd); textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd); } imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0 / freq; // Use debug font to print32_t information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/11-fontsdf"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use a single distance field font to render text of various size."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime) * toMs); float at[3] = { 0, 0, 0.0f }; float eye[3] = {0, 0, -1.0f }; float view[16]; bx::mtxLookAt(view, eye, at); const float centering = 0.5f; // Setup a top-left ortho matrix for screen space drawing. const bgfx::HMD* hmd = bgfx::getHMD(); if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) ) { float proj[16]; bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f); static float time = 0.0f; time += 0.05f; const float dist = 10.0f; const float offset0 = -proj[8] + (hmd->eye[0].viewOffset[0] / dist * proj[0]); const float offset1 = -proj[8] + (hmd->eye[1].viewOffset[0] / dist * proj[0]); float ortho[2][16]; const float viewOffset = width/4.0f; const float viewWidth = width/2.0f; bx::mtxOrtho(ortho[0], centering + viewOffset, centering + viewOffset + viewWidth, height + centering, centering, -1.0f, 1.0f, offset0); bx::mtxOrtho(ortho[1], centering + viewOffset, centering + viewOffset + viewWidth, height + centering, centering, -1.0f, 1.0f, offset1); bgfx::setViewTransform(0, view, ortho[0], BGFX_VIEW_STEREO, ortho[1]); bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); } else { float ortho[16]; bx::mtxOrtho(ortho, centering, width + centering, height + centering, centering, -1.0f, 1.0f); bgfx::setViewTransform(0, view, ortho); bgfx::setViewRect(0, 0, 0, width, height); } //very crude approximation :( float textAreaWidth = 0.5f * 66.0f * fontManager->getFontInfo(fontScaled).maxAdvanceWidth; float textRotMat[16]; float textCenterMat[16]; float textScaleMat[16]; float screenCenterMat[16]; bx::mtxRotateZ(textRotMat, textRotation); bx::mtxTranslate(textCenterMat, -(textAreaWidth * 0.5f), (-visibleLineCount)*metrics.getLineHeight()*0.5f, 0); bx::mtxScale(textScaleMat, textScale, textScale, 1.0f); bx::mtxTranslate(screenCenterMat, ( (width) * 0.5f), ( (height) * 0.5f), 0); //first translate to text center, then scale, then rotate float tmpMat[16]; bx::mtxMul(tmpMat, textCenterMat, textRotMat); float tmpMat2[16]; bx::mtxMul(tmpMat2, tmpMat, textScaleMat); float tmpMat3[16]; bx::mtxMul(tmpMat3, tmpMat2, screenCenterMat); // Set model matrix for rendering. bgfx::setTransform(tmpMat3); // Draw your text. textBufferManager->submitTextBuffer(scrollableBuffer, 0); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } imguiDestroy(); free(bigText); fontManager->destroyTtf(font); // Destroy the fonts. fontManager->destroyFont(fontSdf); fontManager->destroyFont(fontScaled); textBufferManager->destroyTextBuffer(scrollableBuffer); delete textBufferManager; delete fontManager; // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int _argc, char** _argv) { Args args(_argc, _argv); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(args.m_type, args.m_pciId); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); imguiCreate(); NVGcontext* nvg = nvgCreate(1, 0); bgfx::setViewSeq(0, true); DemoData data; loadDemoData(nvg, &data); bndSetFont(nvgCreateFont(nvg, "droidsans", "font/droidsans.ttf") ); bndSetIconImage(nvgCreateImage(nvg, "images/blender_icons16.png", 0) ); int64_t timeOffset = bx::getHPCounter(); entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { int64_t now = bx::getHPCounter(); const double freq = double(bx::getHPFrequency() ); float time = (float)( (now-timeOffset)/freq); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::touch(0); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/20-nanovg"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: NanoVG is small antialiased vector graphics rendering library."); nvgBeginFrame(nvg, width, height, 1.0f); renderDemo(nvg, float(mouseState.m_mx), float(mouseState.m_my), float(width), float(height), time, 0, &data); nvgEndFrame(nvg); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } freeDemoData(nvg, &data); nvgDelete(nvg); imguiDestroy(); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { PosColorTexCoord0Vertex::init(); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x303030ff , 1.0f , 0 ); // Setup root path for binary shaders. Shader binaries are different // for each renderer. switch (bgfx::getRendererType() ) { default: case bgfx::RendererType::Direct3D9: s_shaderPath = "shaders/dx9/"; s_texelHalf = 0.5f; break; case bgfx::RendererType::Direct3D11: s_shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::OpenGL: s_shaderPath = "shaders/glsl/"; s_flipV = true; break; case bgfx::RendererType::OpenGLES2: case bgfx::RendererType::OpenGLES3: s_shaderPath = "shaders/gles/"; s_flipV = true; break; } const bgfx::Memory* mem; mem = loadTexture("uffizi.dds"); bgfx::TextureHandle uffizi = bgfx::createTexture(mem, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP); bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f); bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texLum = bgfx::createUniform("u_texLum", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texBlur = bgfx::createUniform("u_texBlur", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Uniform4fv, 16); bgfx::UniformHandle u_weight = bgfx::createUniform("u_weight", bgfx::UniformType::Uniform4fv, 16); bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox"); bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum"); bgfx::ProgramHandle lumAvgProgram = loadProgram("vs_hdr_lumavg", "fs_hdr_lumavg"); bgfx::ProgramHandle blurProgram = loadProgram("vs_hdr_blur", "fs_hdr_blur"); bgfx::ProgramHandle brightProgram = loadProgram("vs_hdr_bright", "fs_hdr_bright"); bgfx::ProgramHandle meshProgram = loadProgram("vs_hdr_mesh", "fs_hdr_mesh"); bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap"); Mesh mesh; mesh.load("meshes/bunny.bin"); bgfx::RenderTargetHandle rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA8|BGFX_RENDER_TARGET_DEPTH); bgfx::RenderTargetHandle lum[5]; lum[0] = bgfx::createRenderTarget(128, 128, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[1] = bgfx::createRenderTarget( 64, 64, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[2] = bgfx::createRenderTarget( 16, 16, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[3] = bgfx::createRenderTarget( 4, 4, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[4] = bgfx::createRenderTarget( 1, 1, BGFX_RENDER_TARGET_COLOR_RGBA8); bgfx::RenderTargetHandle bright; bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA8); bgfx::RenderTargetHandle blur; blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA8); FILE* file = fopen("font/droidsans.ttf", "rb"); uint32_t size = (uint32_t)fsize(file); void* data = malloc(size); size_t ignore = fread(data, 1, size, file); BX_UNUSED(ignore); fclose(file); imguiCreate(data, size); free(data); float speed = 0.37f; float middleGray = 0.18f; float white = 1.1f; float treshold = 1.5f; int32_t scrollArea = 0; uint32_t oldWidth = 0; uint32_t oldHeight = 0; entry::MouseState mouseState; float time = 0.0f; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; bgfx::destroyRenderTarget(rt); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA8|BGFX_RENDER_TARGET_DEPTH); bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA8); blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA8); } imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea); imguiSeparatorLine(); imguiSlider("Speed", &speed, 0.0f, 1.0f, 0.01f); imguiSeparator(); imguiSlider("Middle gray", &middleGray, 0.1f, 1.0f, 0.01f); imguiSlider("White point", &white, 0.1f, 2.0f, 0.01f); imguiSlider("Treshold", &treshold, 0.1f, 2.0f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; time += (float)(frameTime*speed/freq); bgfx::setUniform(u_time, &time); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Set views. bgfx::setViewRectMask(0x1f, 0, 0, width, height); bgfx::setViewRenderTargetMask(0x3, rt); bgfx::setViewRect(2, 0, 0, 128, 128); bgfx::setViewRenderTarget(2, lum[0]); bgfx::setViewRect(3, 0, 0, 64, 64); bgfx::setViewRenderTarget(3, lum[1]); bgfx::setViewRect(4, 0, 0, 16, 16); bgfx::setViewRenderTarget(4, lum[2]); bgfx::setViewRect(5, 0, 0, 4, 4); bgfx::setViewRenderTarget(5, lum[3]); bgfx::setViewRect(6, 0, 0, 1, 1); bgfx::setViewRenderTarget(6, lum[4]); bgfx::setViewRect(7, 0, 0, width/2, height/2); bgfx::setViewRenderTarget(7, bright); bgfx::setViewRect(8, 0, 0, width/8, height/8); bgfx::setViewRenderTarget(8, blur); bgfx::setViewRect(9, 0, 0, width, height); float view[16]; float proj[16]; mtxIdentity(view); mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransformMask(0 |(1<<0) |(1<<2) |(1<<3) |(1<<4) |(1<<5) |(1<<6) |(1<<7) |(1<<8) |(1<<9) , view , proj ); float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; float mtx[16]; mtxRotateXY(mtx , 0.0f , time ); float temp[4]; vec3MulMtx(temp, eye, mtx); mtxLookAt(view, temp, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransformMask(1<<1, view, proj); bgfx::setUniform(u_mtx, mtx); // Render skybox into view 0. bgfx::setTexture(0, u_texCube, uffizi); bgfx::setProgram(skyProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); bgfx::submit(0); // Render mesh into view 1 bgfx::setTexture(0, u_texCube, uffizi); mesh.submit(1, meshProgram, NULL); // Calculate luminance. setOffsets2x2Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, rt); bgfx::setProgram(lumProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(128.0f, 128.0f, s_flipV); bgfx::submit(2); // Downscale luminance 0. setOffsets4x4Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, lum[0]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(64.0f, 64.0f, s_flipV); bgfx::submit(3); // Downscale luminance 1. setOffsets4x4Lum(u_offset, 64, 64); bgfx::setTexture(0, u_texColor, lum[1]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(16.0f, 16.0f, s_flipV); bgfx::submit(4); // Downscale luminance 2. setOffsets4x4Lum(u_offset, 16, 16); bgfx::setTexture(0, u_texColor, lum[2]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(4.0f, 4.0f, s_flipV); bgfx::submit(5); // Downscale luminance 3. setOffsets4x4Lum(u_offset, 4, 4); bgfx::setTexture(0, u_texColor, lum[3]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(1.0f, 1.0f, s_flipV); bgfx::submit(6); float tonemap[4] = { middleGray, square(white), treshold, 0.0f }; bgfx::setUniform(u_tonemap, tonemap); // Bright pass treshold is tonemap[3]. setOffsets4x4Lum(u_offset, width/2, height/2); bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setProgram(brightProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_flipV); bgfx::submit(7); // Blur bright pass vertically. bgfx::setTexture(0, u_texColor, bright); bgfx::setProgram(blurProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_flipV); bgfx::submit(8); // Blur bright pass horizontally, do tonemaping and combine. bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setTexture(2, u_texBlur, blur); bgfx::setProgram(tonemapProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(9); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } imguiDestroy(); // Cleanup. mesh.unload(); bgfx::destroyRenderTarget(lum[0]); bgfx::destroyRenderTarget(lum[1]); bgfx::destroyRenderTarget(lum[2]); bgfx::destroyRenderTarget(lum[3]); bgfx::destroyRenderTarget(lum[4]); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); bgfx::destroyRenderTarget(rt); bgfx::destroyProgram(meshProgram); bgfx::destroyProgram(skyProgram); bgfx::destroyProgram(tonemapProgram); bgfx::destroyProgram(lumProgram); bgfx::destroyProgram(lumAvgProgram); bgfx::destroyProgram(blurProgram); bgfx::destroyProgram(brightProgram); bgfx::destroyTexture(uffizi); bgfx::destroyUniform(u_time); bgfx::destroyUniform(u_texCube); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_texLum); bgfx::destroyUniform(u_texBlur); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_tonemap); bgfx::destroyUniform(u_offset); bgfx::destroyUniform(u_weight); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x303030ff , 1.0f , 0 ); // Setup root path for binary shaders. Shader binaries are different // for each renderer. switch (bgfx::getRendererType() ) { default: case bgfx::RendererType::Direct3D9: s_shaderPath = "shaders/dx9/"; break; case bgfx::RendererType::Direct3D11: s_shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::OpenGL: s_shaderPath = "shaders/glsl/"; s_flipV = true; break; case bgfx::RendererType::OpenGLES2: case bgfx::RendererType::OpenGLES3: s_shaderPath = "shaders/gles/"; s_flipV = true; break; } bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_stipple = bgfx::createUniform("u_stipple", bgfx::UniformType::Uniform3fv); bgfx::UniformHandle u_texStipple = bgfx::createUniform("u_texStipple", bgfx::UniformType::Uniform1iv); bgfx::ProgramHandle program = loadProgram("vs_tree", "fs_tree"); const bgfx::Memory* mem; mem = loadTexture("leafs1.dds"); bgfx::TextureHandle textureLeafs = bgfx::createTexture(mem); mem = loadTexture("bark1.dds"); bgfx::TextureHandle textureBark = bgfx::createTexture(mem); bgfx::TextureHandle textureStipple; const bgfx::Memory* stipple = bgfx::alloc(8*4); memset(stipple->data, 0, stipple->size); for (uint32_t ii = 0; ii < 32; ++ii) { stipple->data[knightTour[ii].m_y * 8 + knightTour[ii].m_x] = ii*4; } textureStipple = bgfx::createTexture2D(8, 4, 1, bgfx::TextureFormat::L8, BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIN_POINT, stipple); Mesh mesh_top[3]; mesh_top[0].load("meshes/tree1b_lod0_1.bin"); mesh_top[1].load("meshes/tree1b_lod1_1.bin"); mesh_top[2].load("meshes/tree1b_lod2_1.bin"); Mesh mesh_trunk[3]; mesh_trunk[0].load("meshes/tree1b_lod0_2.bin"); mesh_trunk[1].load("meshes/tree1b_lod1_2.bin"); mesh_trunk[2].load("meshes/tree1b_lod2_2.bin"); FILE* file = fopen("font/droidsans.ttf", "rb"); uint32_t size = (uint32_t)fsize(file); void* data = malloc(size); size_t ignore = fread(data, 1, size, file); BX_UNUSED(ignore); fclose(file); imguiCreate(data, size); free(data); int32_t scrollArea = 0; bool transitions = true; int transitionFrame = 0; int currLOD = 0; int targetLOD = 0; float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.0f }; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , 0 , width , height ); imguiBeginScrollArea("Toggle transitions", width - width / 5 - 10, 10, width / 5, height / 6, &scrollArea); imguiSeparatorLine(); if (imguiButton(transitions ? "ON" : "OFF") ) { transitions = !transitions; } static float distance = 2.0f; imguiSlider("Distance", &distance, 2.0f, 6.0f, .01f); imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to view 0. bgfx::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/12-lod"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mesh LOD transitions."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); bgfx::dbgTextPrintf(0, 4, transitions ? 0x2f : 0x1f, transitions ? "Transitions on" : "Transitions off"); eye[2] = -distance; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(0, view, proj); float mtx[16]; mtxIdentity(mtx); float stipple[3]; float stippleInv[3]; const int currentLODframe = transitions ? 32-transitionFrame : 32; const int mainLOD = transitions ? currLOD : targetLOD; stipple[0] = 0.0f; stipple[1] = -1.0f; stipple[2] = (float(currentLODframe)*4.0f/255.0f) - (1.0f/255.0f); stippleInv[0] = (float(31)*4.0f/255.0f); stippleInv[1] = 1.0f; stippleInv[2] = (float(transitionFrame)*4.0f/255.0f) - (1.0f/255.0f); bgfx::setTexture(0, u_texColor, textureBark); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); mesh_trunk[mainLOD].submit(program, mtx, false); bgfx::setTexture(0, u_texColor, textureLeafs); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); mesh_top[mainLOD].submit(program, mtx, true); if (transitions && (transitionFrame != 0) ) { bgfx::setTexture(0, u_texColor, textureBark); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); mesh_trunk[targetLOD].submit(program, mtx, false); bgfx::setTexture(0, u_texColor, textureLeafs); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); mesh_top[targetLOD].submit(program, mtx, true); } int lod = 0; if (eye[2] < -2.5f) { lod = 1; } if (eye[2] < -5.0f) { lod = 2; } if (targetLOD!=lod) { if (targetLOD==currLOD) { targetLOD = lod; } } if (currLOD != targetLOD) { transitionFrame++; } if (transitionFrame>32) { currLOD = targetLOD; transitionFrame = 0; } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } for (uint32_t ii = 0; ii < 3; ++ii) { mesh_top[ii].unload(); mesh_trunk[ii].unload(); } // Cleanup. bgfx::destroyProgram(program); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_stipple); bgfx::destroyUniform(u_texStipple); bgfx::destroyTexture(textureStipple); bgfx::destroyTexture(textureLeafs); bgfx::destroyTexture(textureBark); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); const bgfx::Caps* caps = bgfx::getCaps(); const bool computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT); if (computeSupported) { // Imgui. imguiCreate(); bgfx::VertexDecl quadVertexDecl; quadVertexDecl.begin() .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) .end(); // Create static vertex buffer. bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer( // Static data can be passed with bgfx::makeRef bgfx::makeRef(s_quadVertices, sizeof(s_quadVertices) ) , quadVertexDecl ); // Create static index buffer. bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer( // Static data can be passed with bgfx::makeRef bgfx::makeRef(s_quadIndices, sizeof(s_quadIndices) ) ); // Create particle program from shaders. bgfx::ProgramHandle particleProgram = loadProgram("vs_particle", "fs_particle"); // Setup compute buffers bgfx::VertexDecl computeVertexDecl; computeVertexDecl.begin() .add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float) .end(); const uint32_t threadGroupUpdateSize = 512; const uint32_t maxParticleCount = 32 * 1024; bgfx::DynamicVertexBufferHandle currPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); bgfx::DynamicVertexBufferHandle currPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); bgfx::DynamicVertexBufferHandle prevPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); bgfx::DynamicVertexBufferHandle prevPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE); bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 3); bgfx::ProgramHandle initInstancesProgram = bgfx::createProgram(loadShader("cs_init_instances"), true); bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(loadShader("cs_update_instances"), true); bgfx::ProgramHandle indirectProgram = BGFX_INVALID_HANDLE; bgfx::IndirectBufferHandle indirectBuffer = BGFX_INVALID_HANDLE; if (indirectSupported) { indirectProgram = bgfx::createProgram(loadShader("cs_indirect"), true); indirectBuffer = bgfx::createIndirectBuffer(2); } u_paramsDataStruct u_paramsData; InitializeParams(0, &u_paramsData); bgfx::setUniform(u_params, &u_paramsData, 3); bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write); bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write); bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1); float view[16]; float initialPos[3] = { 0.0f, 0.0f, -45.0f }; cameraCreate(); cameraSetPosition(initialPos); cameraSetVerticalAngle(0.0f); cameraGetViewMtx(view); int32_t scrollArea = 0; bool useIndirect = false; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const double freq = double(bx::getHPFrequency() ); const float deltaTime = float(frameTime/freq); if (deltaTime > 1000.0) { abort(); } // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers."); imguiBeginFrame(mouseState.m_mx , mouseState.m_my , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) , mouseState.m_mz , width , height ); imguiBeginScrollArea("Settings", width - width / 4 - 10, 10, width / 4, 500, &scrollArea); imguiSlider("Random seed", u_paramsData.baseSeed, 0, 100); int32_t shape = imguiChoose(u_paramsData.initialShape, "Point", "Sphere", "Box", "Donut"); imguiSlider("Initial speed", u_paramsData.initialSpeed, 0.0f, 300.0f, 0.1f); bool defaults = imguiButton("Reset"); imguiSeparatorLine(); imguiSlider("Particle count (x512)", u_paramsData.dispatchSize, 1, 64); imguiSlider("Gravity", u_paramsData.gravity, 0.0f, 0.3f, 0.001f); imguiSlider("Damping", u_paramsData.damping, 0.0f, 1.0f, 0.01f); imguiSlider("Max acceleration", u_paramsData.maxAccel, 0.0f, 100.0f, 0.01f); imguiSlider("Time step", u_paramsData.timeStep, 0.0f, 0.02f, 0.0001f); imguiSeparatorLine(); imguiSlider("Particle intensity", u_paramsData.particleIntensity, 0.0f, 1.0f, 0.001f); imguiSlider("Particle size", u_paramsData.particleSize, 0.0f, 1.0f, 0.001f); imguiSlider("Particle power", u_paramsData.particlePower, 0.001f, 16.0f, 0.01f); imguiSeparatorLine(); if (imguiCheck("Use draw/dispatch indirect", useIndirect, indirectSupported) ) { useIndirect = !useIndirect; } imguiEndScrollArea(); imguiEndFrame(); // Modify parameters and reset if shape is changed if (shape != u_paramsData.initialShape) { defaults = true; InitializeParams(shape, &u_paramsData); } if (defaults) { bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write); bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write); bgfx::setUniform(u_params, &u_paramsData, 3); bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1); } if (useIndirect) { bgfx::setUniform(u_params, &u_paramsData, 3); bgfx::setBuffer(0, indirectBuffer, bgfx::Access::Write); bgfx::dispatch(0, indirectProgram); } bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Read); bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Read); bgfx::setBuffer(2, prevPositionBuffer1, bgfx::Access::Write); bgfx::setBuffer(3, currPositionBuffer1, bgfx::Access::Write); bgfx::setUniform(u_params, &u_paramsData, 3); if (useIndirect) { bgfx::dispatch(0, updateInstancesProgram, indirectBuffer, 1); } else { bgfx::dispatch(0, updateInstancesProgram, u_paramsData.dispatchSize, 1, 1); } bx::xchg(currPositionBuffer0, currPositionBuffer1); bx::xchg(prevPositionBuffer0, prevPositionBuffer1); // Update camera. cameraUpdate(deltaTime, mouseState); cameraGetViewMtx(view); // Set view and projection matrix for view 0. const bgfx::HMD* hmd = bgfx::getHMD(); if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) ) { float viewHead[16]; float eye[3] = {}; bx::mtxQuatTranslationHMD(viewHead, hmd->eye[0].rotation, eye); float tmp[16]; bx::mtxMul(tmp, view, viewHead); float proj[16]; bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 10000.0f); bgfx::setViewTransform(0, tmp, proj); // Set view 0 default viewport. // // Use HMD's width/height since HMD's internal frame buffer size // might be much larger than window size. bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); } else { float proj[16]; bx::mtxProj(proj, 90.0f, float(width)/float(height), 0.1f, 10000.0f); bgfx::setViewTransform(0, view, proj); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); } // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); bgfx::setInstanceDataBuffer(currPositionBuffer0, 0, u_paramsData.dispatchSize * threadGroupUpdateSize); // Set render states. bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_ADD | BGFX_STATE_DEPTH_TEST_ALWAYS ); // Submit primitive for rendering to view 0. if (useIndirect) { bgfx::submit(0, particleProgram, indirectBuffer, 0); } else { bgfx::submit(0, particleProgram); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. cameraDestroy(); imguiDestroy(); if (indirectSupported) { bgfx::destroyProgram(indirectProgram); bgfx::destroyIndirectBuffer(indirectBuffer); } bgfx::destroyUniform(u_params); bgfx::destroyDynamicVertexBuffer(currPositionBuffer0); bgfx::destroyDynamicVertexBuffer(currPositionBuffer1); bgfx::destroyDynamicVertexBuffer(prevPositionBuffer0); bgfx::destroyDynamicVertexBuffer(prevPositionBuffer1); bgfx::destroyProgram(updateInstancesProgram); bgfx::destroyProgram(initInstancesProgram); bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(particleProgram); } else { int64_t timeOffset = bx::getHPCounter(); entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { int64_t now = bx::getHPCounter(); float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) ); bgfx::setViewRect(0, 0, 0, width, height); bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers."); bool blink = uint32_t(time*3.0f)&1; bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Compute is not supported by GPU. "); bgfx::touch(0); bgfx::frame(); } } // Shutdown bgfx. bgfx::shutdown(); return 0; }