-
-
Save pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb to your computer and use it in GitHub Desktop.
imgui+bgfx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Derived from this Gist by Richard Gale: | |
// https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0 | |
// ImGui BFFX binding | |
// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture | |
// identifier. Read the FAQ about ImTextureID in imgui.cpp. | |
// You can copy and use unmodified imgui_impl_* files in your project. See | |
// main.cpp for an example of using this. If you use this binding you'll need to | |
// call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), | |
// ImGui::Render() and ImGui_ImplXXXX_Shutdown(). If you are new to ImGui, see | |
// examples/README.txt and documentation at the top of imgui.cpp. | |
// https://github.com/ocornut/imgui | |
#include "imgui_impl_bgfx.h" | |
#include "imgui.h" | |
// BGFX/BX | |
#include "bgfx/bgfx.h" | |
#include "bgfx/embedded_shader.h" | |
#include "bx/math.h" | |
#include "bx/timer.h" | |
// Data | |
static uint8_t g_View = 255; | |
static bgfx::TextureHandle g_FontTexture = BGFX_INVALID_HANDLE; | |
static bgfx::ProgramHandle g_ShaderHandle = BGFX_INVALID_HANDLE; | |
static bgfx::UniformHandle g_AttribLocationTex = BGFX_INVALID_HANDLE; | |
static bgfx::VertexLayout g_VertexLayout; | |
// This is the main rendering function that you have to implement and call after | |
// ImGui::Render(). Pass ImGui::GetDrawData() to this function. | |
// Note: If text or lines are blurry when integrating ImGui into your engine, | |
// in your Render function, try translating your projection matrix by | |
// (0.5f,0.5f) or (0.375f,0.375f) | |
void ImGui_Implbgfx_RenderDrawLists(ImDrawData* draw_data) | |
{ | |
// Avoid rendering when minimized, scale coordinates for retina displays | |
// (screen coordinates != framebuffer coordinates) | |
ImGuiIO& io = ImGui::GetIO(); | |
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); | |
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); | |
if (fb_width == 0 || fb_height == 0) { | |
return; | |
} | |
draw_data->ScaleClipRects(io.DisplayFramebufferScale); | |
// Setup render state: alpha-blending enabled, no face culling, | |
// no depth testing, scissor enabled | |
uint64_t state = | |
BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_MSAA | | |
BGFX_STATE_BLEND_FUNC( | |
BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); | |
const bgfx::Caps* caps = bgfx::getCaps(); | |
// Setup viewport, orthographic projection matrix | |
float ortho[16]; | |
bx::mtxOrtho( | |
ortho, 0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, 0.0f, 1000.0f, | |
0.0f, caps->homogeneousDepth); | |
bgfx::setViewTransform(g_View, NULL, ortho); | |
bgfx::setViewRect(g_View, 0, 0, (uint16_t)fb_width, (uint16_t)fb_height); | |
// Render command lists | |
for (int n = 0; n < draw_data->CmdListsCount; n++) { | |
const ImDrawList* cmd_list = draw_data->CmdLists[n]; | |
bgfx::TransientVertexBuffer tvb; | |
bgfx::TransientIndexBuffer tib; | |
uint32_t numVertices = (uint32_t)cmd_list->VtxBuffer.size(); | |
uint32_t numIndices = (uint32_t)cmd_list->IdxBuffer.size(); | |
if ((numVertices != bgfx::getAvailTransientVertexBuffer( | |
numVertices, g_VertexLayout)) || | |
(numIndices != bgfx::getAvailTransientIndexBuffer(numIndices))) { | |
// not enough space in transient buffer, quit drawing the rest... | |
break; | |
} | |
bgfx::allocTransientVertexBuffer(&tvb, numVertices, g_VertexLayout); | |
bgfx::allocTransientIndexBuffer(&tib, numIndices); | |
ImDrawVert* verts = (ImDrawVert*)tvb.data; | |
memcpy( | |
verts, cmd_list->VtxBuffer.begin(), | |
numVertices * sizeof(ImDrawVert)); | |
ImDrawIdx* indices = (ImDrawIdx*)tib.data; | |
memcpy( | |
indices, cmd_list->IdxBuffer.begin(), | |
numIndices * sizeof(ImDrawIdx)); | |
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { | |
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; | |
if (pcmd->UserCallback) { | |
pcmd->UserCallback(cmd_list, pcmd); | |
} else { | |
const uint16_t xx = (uint16_t)bx::max(pcmd->ClipRect.x, 0.0f); | |
const uint16_t yy = (uint16_t)bx::max(pcmd->ClipRect.y, 0.0f); | |
bgfx::setScissor( | |
xx, yy, (uint16_t)bx::min(pcmd->ClipRect.z, 65535.0f) - xx, | |
(uint16_t)bx::min(pcmd->ClipRect.w, 65535.0f) - yy); | |
bgfx::setState(state); | |
bgfx::TextureHandle texture = { | |
(uint16_t)((intptr_t)pcmd->TextureId & 0xffff)}; | |
bgfx::setTexture(0, g_AttribLocationTex, texture); | |
bgfx::setVertexBuffer(0, &tvb, 0, numVertices); | |
bgfx::setIndexBuffer(&tib, pcmd->IdxOffset, pcmd->ElemCount); | |
bgfx::submit(g_View, g_ShaderHandle); | |
} | |
} | |
} | |
} | |
bool ImGui_Implbgfx_CreateFontsTexture() | |
{ | |
// Build texture atlas | |
ImGuiIO& io = ImGui::GetIO(); | |
unsigned char* pixels; | |
int width, height; | |
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); | |
// Upload texture to graphics system | |
g_FontTexture = bgfx::createTexture2D( | |
(uint16_t)width, (uint16_t)height, false, 1, bgfx::TextureFormat::BGRA8, | |
0, bgfx::copy(pixels, width * height * 4)); | |
// Store our identifier | |
io.Fonts->TexID = (void*)(intptr_t)g_FontTexture.idx; | |
return true; | |
} | |
#include "fs_ocornut_imgui.bin.h" | |
#include "vs_ocornut_imgui.bin.h" | |
static const bgfx::EmbeddedShader s_embeddedShaders[] = { | |
BGFX_EMBEDDED_SHADER(vs_ocornut_imgui), | |
BGFX_EMBEDDED_SHADER(fs_ocornut_imgui), BGFX_EMBEDDED_SHADER_END()}; | |
bool ImGui_Implbgfx_CreateDeviceObjects() | |
{ | |
bgfx::RendererType::Enum type = bgfx::getRendererType(); | |
g_ShaderHandle = bgfx::createProgram( | |
bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_ocornut_imgui"), | |
bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_ocornut_imgui"), | |
true); | |
g_VertexLayout.begin() | |
.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) | |
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float) | |
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) | |
.end(); | |
g_AttribLocationTex = | |
bgfx::createUniform("g_AttribLocationTex", bgfx::UniformType::Sampler); | |
ImGui_Implbgfx_CreateFontsTexture(); | |
return true; | |
} | |
void ImGui_Implbgfx_InvalidateDeviceObjects() | |
{ | |
bgfx::destroy(g_AttribLocationTex); | |
bgfx::destroy(g_ShaderHandle); | |
if (isValid(g_FontTexture)) { | |
bgfx::destroy(g_FontTexture); | |
ImGui::GetIO().Fonts->TexID = 0; | |
g_FontTexture.idx = bgfx::kInvalidHandle; | |
} | |
} | |
void ImGui_Implbgfx_Init(int view) | |
{ | |
g_View = (uint8_t)(view & 0xff); | |
} | |
void ImGui_Implbgfx_Shutdown() | |
{ | |
ImGui_Implbgfx_InvalidateDeviceObjects(); | |
} | |
void ImGui_Implbgfx_NewFrame() | |
{ | |
if (!isValid(g_FontTexture)) { | |
ImGui_Implbgfx_CreateDeviceObjects(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Derived from this Gist by Richard Gale: | |
// https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0 | |
// ImGui BGFX binding | |
// You can copy and use unmodified imgui_impl_* files in your project. See | |
// main.cpp for an example of using this. If you use this binding you'll need to | |
// call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), | |
// ImGui::Render() and ImGui_ImplXXXX_Shutdown(). If you are new to ImGui, see | |
// examples/README.txt and documentation at the top of imgui.cpp. | |
// https://github.com/ocornut/imgui | |
void ImGui_Implbgfx_Init(int view); | |
void ImGui_Implbgfx_Shutdown(); | |
void ImGui_Implbgfx_NewFrame(); | |
void ImGui_Implbgfx_RenderDrawLists(struct ImDrawData* draw_data); | |
// Use if you want to reset your rendering device without losing ImGui state. | |
void ImGui_Implbgfx_InvalidateDeviceObjects(); | |
bool ImGui_Implbgfx_CreateDeviceObjects(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment