Created
March 26, 2021 07:44
-
-
Save NoelFB/fb97a2df8d422437390104078bd01fcb to your computer and use it in GitHub Desktop.
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
#include <blah.h> | |
#include "imgui/imgui.h" | |
#define IMGUI_DEFINE_MATH_OPERATORS | |
#include "imgui/imgui_internal.h" | |
using namespace Blah; | |
namespace | |
{ | |
MeshRef mesh; | |
MaterialRef material; | |
ShaderRef shader; | |
TextureRef tex; | |
Batch batcher; | |
const ShaderData opengl_shader_data = { | |
"#version 330\n" | |
"uniform mat4 u_matrix;" | |
"layout(location=0) in vec2 a_position;\n" | |
"layout(location=1) in vec2 a_tex;\n" | |
"layout(location=2) in vec4 a_color;\n" | |
"out vec2 v_tex;\n" | |
"out vec4 v_color;\n" | |
"void main() {\n" | |
" gl_Position = u_matrix * vec4(a_position.xy, 0, 1);\n" | |
" v_tex = a_tex;" | |
" v_color = a_color;\n" | |
"}\n", | |
"#version 330\n" | |
"uniform sampler2D u_texture;\n" | |
"in vec2 v_tex;\n" | |
"in vec4 v_color;\n" | |
"out vec4 frag_color;\n" | |
"void main() {\n" | |
" frag_color = texture(u_texture, v_tex.st) * v_color;\n" | |
"}\n" | |
}; | |
const char* d3d11_shader = "" | |
"cbuffer constants : register(b0)\n" | |
"{\n" | |
" row_major float4x4 u_matrix;\n" | |
"}\n" | |
"struct vs_in\n" | |
"{\n" | |
" float2 position : POS;\n" | |
" float2 texcoord : TEX;\n" | |
" float4 color : COL;\n" | |
"};\n" | |
"struct vs_out\n" | |
"{\n" | |
" float4 position : SV_POSITION;\n" | |
" float2 texcoord : TEX;\n" | |
" float4 color : COL;\n" | |
"};\n" | |
"Texture2D u_texture : register(t0);\n" | |
"SamplerState u_sampler : register(s0);\n" | |
"vs_out vs_main(vs_in input)\n" | |
"{\n" | |
" vs_out output;\n" | |
" output.position = mul(float4(input.position, 0.0f, 1.0f), u_matrix);\n" | |
" output.texcoord = input.texcoord;\n" | |
" output.color = input.color;\n" | |
" return output;\n" | |
"}\n" | |
"float4 ps_main(vs_out input) : SV_TARGET\n" | |
"{\n" | |
" return u_texture.Sample(u_sampler, input.texcoord) * input.color;\n" | |
"}\n"; | |
const ShaderData d3d11_shader_data = { | |
d3d11_shader, | |
d3d11_shader, | |
{ | |
{ "POS", 0 }, | |
{ "TEX", 0 }, | |
{ "COL", 0 }, | |
} | |
}; | |
const VertexFormat format = VertexFormat({ | |
{ 0, VertexType::Float2, false }, | |
{ 1, VertexType::Float2, false }, | |
{ 2, VertexType::UByte4, true } | |
}); | |
} | |
void startup() | |
{ | |
// Initializes ImGui | |
ImGui::CreateContext(); | |
// Create ImGui Config | |
ImGuiIO& io = ImGui::GetIO(); (void)io; | |
io.DisplaySize.x = (float)(App::draw_width()); | |
io.DisplaySize.y = (float)(App::draw_height()); | |
io.BackendFlags = 0; | |
io.ConfigFlags = ImGuiConfigFlags_DockingEnable; | |
io.DisplayFramebufferScale = ImVec2(App::content_scale(), App::content_scale()); | |
// Key Mapping | |
{ | |
io.KeyMap[ImGuiKey_Tab] = (int)Key::Tab; | |
io.KeyMap[ImGuiKey_LeftArrow] = (int)Key::Left; | |
io.KeyMap[ImGuiKey_RightArrow] = (int)Key::Right; | |
io.KeyMap[ImGuiKey_UpArrow] = (int)Key::Up; | |
io.KeyMap[ImGuiKey_DownArrow] = (int)Key::Down; | |
io.KeyMap[ImGuiKey_PageUp] = (int)Key::PageUp; | |
io.KeyMap[ImGuiKey_PageDown] = (int)Key::PageDown; | |
io.KeyMap[ImGuiKey_Home] = (int)Key::Home; | |
io.KeyMap[ImGuiKey_End] = (int)Key::End; | |
io.KeyMap[ImGuiKey_Insert] = (int)Key::Insert; | |
io.KeyMap[ImGuiKey_Delete] = (int)Key::Delete; | |
io.KeyMap[ImGuiKey_Backspace] = (int)Key::Backspace; | |
io.KeyMap[ImGuiKey_Space] = (int)Key::Space; | |
io.KeyMap[ImGuiKey_Enter] = (int)Key::Enter; | |
io.KeyMap[ImGuiKey_Escape] = (int)Key::Escape; | |
io.KeyMap[ImGuiKey_KeyPadEnter] = (int)Key::KeypadEnter; | |
io.KeyMap[ImGuiKey_A] = (int)Key::A; | |
io.KeyMap[ImGuiKey_C] = (int)Key::C; | |
io.KeyMap[ImGuiKey_V] = (int)Key::V; | |
io.KeyMap[ImGuiKey_X] = (int)Key::X; | |
io.KeyMap[ImGuiKey_Y] = (int)Key::Y; | |
io.KeyMap[ImGuiKey_Z] = (int)Key::Z; | |
} | |
// Create Font Texture | |
{ | |
io.Fonts->AddFontDefault(); | |
unsigned char* pixels; | |
int width, height; | |
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); | |
tex = Texture::create(width, height, TextureFormat::RGBA, pixels); | |
io.Fonts->SetTexID((ImTextureID)&tex); | |
} | |
// Create Default Resources | |
{ | |
if (App::renderer() == Renderer::OpenGL) | |
shader = Shader::create(opengl_shader_data); | |
else if (App::renderer() == Renderer::D3D11) | |
shader = Shader::create(d3d11_shader_data); | |
material = Material::create(shader); | |
mesh = Mesh::create(); | |
} | |
} | |
void update() | |
{ | |
// Setup ImGui Frame Data | |
{ | |
auto draw_size = Point(App::draw_width(), App::draw_height()); | |
auto scale = App::content_scale(); | |
auto mouse = Input::mouse_draw(); | |
ImGuiIO& io = ImGui::GetIO(); | |
io.DisplaySize.x = (float)(draw_size.x / scale); | |
io.DisplaySize.y = (float)(draw_size.y / scale); | |
io.MousePos = ImVec2(mouse.x / scale, mouse.y / scale); | |
io.MouseDown[0] = Input::down(MouseButton::Left); | |
io.MouseDown[1] = Input::down(MouseButton::Right); | |
io.MouseDown[2] = Input::down(MouseButton::Middle); | |
io.MouseWheel = (float)Input::mouse_wheel().y; | |
io.MouseWheelH = (float)Input::mouse_wheel().x; | |
io.KeyCtrl = Input::ctrl(); | |
io.KeyShift = Input::shift(); | |
io.KeyAlt = Input::alt(); | |
// toggle held keys | |
for (int i = 0; i < 512; i++) | |
io.KeysDown[i] = Input::down((Key)i); | |
// add text strings | |
io.AddInputCharactersUTF8(Input::text()); | |
} | |
ImGui::NewFrame(); | |
ImGui::ShowDemoWindow(); | |
ImGui::EndFrame(); | |
} | |
void render() | |
{ | |
// render imgui | |
ImGui::Render(); | |
ImDrawData* data = ImGui::GetDrawData(); | |
// set up render call | |
RenderPass pass; | |
pass.target = App::backbuffer; | |
pass.mesh = mesh; | |
pass.material = material; | |
pass.has_scissor = true; | |
pass.blend = BlendMode(BlendOp::Add, BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha); | |
// size | |
Vec2 size = Point(App::draw_width(), App::draw_height()); | |
// apply the ortho matrix | |
Mat4x4 mat = | |
Mat4x4::create_scale(data->FramebufferScale.x, data->FramebufferScale.y, 1.0f) * | |
Mat4x4::create_ortho_offcenter(0, size.x, size.y, 0, 0.1f, 1000.0f); | |
material->set_value("u_matrix", &mat.m11, 16); | |
// draw imgui buffers to the screen | |
for (int i = 0; i < data->CmdListsCount; i++) | |
{ | |
ImDrawList* list = data->CmdLists[i]; | |
mesh->vertex_data(format, list->VtxBuffer.begin(), list->VtxBuffer.size()); | |
mesh->index_data(IndexFormat::UInt32, list->IdxBuffer.begin(), list->IdxBuffer.size()); | |
for (ImDrawCmd* cmd = list->CmdBuffer.begin(); cmd < list->CmdBuffer.end(); cmd++) | |
{ | |
// Todo: | |
// use cmd->TextureId to get the current texture we should draw | |
material->set_texture(0, tex); | |
material->set_sampler(0, TextureSampler(TextureFilter::Nearest)); | |
if (cmd->UserCallback != nullptr) | |
{ | |
cmd->UserCallback(list, cmd); | |
} | |
else | |
{ | |
pass.index_start = cmd->IdxOffset; | |
pass.index_count = cmd->ElemCount; | |
pass.scissor = Rect( | |
cmd->ClipRect.x, | |
cmd->ClipRect.y, | |
(cmd->ClipRect.z - cmd->ClipRect.x), | |
(cmd->ClipRect.w - cmd->ClipRect.y)) | |
.scale(data->FramebufferScale.x, data->FramebufferScale.y); | |
pass.perform(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment