Moving imgui to the new ImmediateDrawer.
This commit is contained in:
parent
c631b965d7
commit
4c2257a29d
|
@ -28,11 +28,11 @@
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/cpu/frontend/ppc_disasm.h"
|
#include "xenia/cpu/frontend/ppc_disasm.h"
|
||||||
#include "xenia/cpu/stack_walker.h"
|
#include "xenia/cpu/stack_walker.h"
|
||||||
#include "xenia/debug/ui/imgui_renderer.h"
|
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
#include "xenia/kernel/xmodule.h"
|
#include "xenia/kernel/xmodule.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
#include "xenia/ui/gl/gl_context.h"
|
#include "xenia/ui/gl/gl_context.h"
|
||||||
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
|
|
||||||
DEFINE_bool(imgui_debug, false, "Show ImGui debugging tools.");
|
DEFINE_bool(imgui_debug, false, "Show ImGui debugging tools.");
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ bool DebugWindow::Initialize() {
|
||||||
|
|
||||||
window_->on_closed.AddListener([this](UIEvent* e) {
|
window_->on_closed.AddListener([this](UIEvent* e) {
|
||||||
// Kill now while we have a GL context.
|
// Kill now while we have a GL context.
|
||||||
imgui_renderer_.reset();
|
imgui_drawer_.reset();
|
||||||
});
|
});
|
||||||
loop_->on_quit.AddListener([this](UIEvent* e) { window_.reset(); });
|
loop_->on_quit.AddListener([this](UIEvent* e) { window_.reset(); });
|
||||||
|
|
||||||
|
@ -120,8 +120,7 @@ bool DebugWindow::Initialize() {
|
||||||
window_->set_context(std::move(context));
|
window_->set_context(std::move(context));
|
||||||
|
|
||||||
// Setup ImGui.
|
// Setup ImGui.
|
||||||
imgui_renderer_ =
|
imgui_drawer_ = std::make_unique<xe::ui::ImGuiDrawer>(window_.get());
|
||||||
std::make_unique<ImGuiRenderer>(window_.get(), window_->context());
|
|
||||||
window_->on_key_char.AddListener([](xe::ui::KeyEvent* e) {
|
window_->on_key_char.AddListener([](xe::ui::KeyEvent* e) {
|
||||||
auto& io = ImGui::GetIO();
|
auto& io = ImGui::GetIO();
|
||||||
if (e->key_code() > 0 && e->key_code() < 0x10000) {
|
if (e->key_code() > 0 && e->key_code() < 0x10000) {
|
||||||
|
|
|
@ -21,12 +21,16 @@
|
||||||
#include "xenia/ui/window.h"
|
#include "xenia/ui/window.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
class ImGuiDrawer;
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace debug {
|
namespace debug {
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
class ImGuiRenderer;
|
|
||||||
|
|
||||||
class DebugWindow : public DebugListener {
|
class DebugWindow : public DebugListener {
|
||||||
public:
|
public:
|
||||||
~DebugWindow();
|
~DebugWindow();
|
||||||
|
@ -91,7 +95,7 @@ class DebugWindow : public DebugListener {
|
||||||
Debugger* debugger_ = nullptr;
|
Debugger* debugger_ = nullptr;
|
||||||
xe::ui::Loop* loop_ = nullptr;
|
xe::ui::Loop* loop_ = nullptr;
|
||||||
std::unique_ptr<xe::ui::Window> window_;
|
std::unique_ptr<xe::ui::Window> window_;
|
||||||
std::unique_ptr<ImGuiRenderer> imgui_renderer_;
|
std::unique_ptr<xe::ui::ImGuiDrawer> imgui_drawer_;
|
||||||
uint64_t last_draw_tick_count_ = 0;
|
uint64_t last_draw_tick_count_ = 0;
|
||||||
|
|
||||||
uintptr_t capstone_handle_ = 0;
|
uintptr_t capstone_handle_ = 0;
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
|
||||||
******************************************************************************
|
|
||||||
* Copyright 2015 Ben Vanik. All rights reserved. *
|
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XENIA_DEBUG_UI_IMGUI_RENDERER_H_
|
|
||||||
#define XENIA_DEBUG_UI_IMGUI_RENDERER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "third_party/imgui/imgui.h"
|
|
||||||
#include "xenia/base/clock.h"
|
|
||||||
#include "xenia/base/logging.h"
|
|
||||||
#include "xenia/base/math.h"
|
|
||||||
#include "xenia/ui/gl/circular_buffer.h"
|
|
||||||
#include "xenia/ui/gl/gl_context.h"
|
|
||||||
#include "xenia/ui/window.h"
|
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace debug {
|
|
||||||
namespace ui {
|
|
||||||
|
|
||||||
class ImGuiRenderer {
|
|
||||||
public:
|
|
||||||
ImGuiRenderer(xe::ui::Window* window, xe::ui::GraphicsContext* context);
|
|
||||||
~ImGuiRenderer();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static ImGuiRenderer* global_renderer_;
|
|
||||||
|
|
||||||
void Initialize();
|
|
||||||
void InitializeShaders();
|
|
||||||
void InitializeFontTextures();
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
void RenderDrawLists(ImDrawData* data);
|
|
||||||
|
|
||||||
xe::ui::Window* window_ = nullptr;
|
|
||||||
xe::ui::GraphicsContext* context_ = nullptr;
|
|
||||||
|
|
||||||
GLuint program_ = 0;
|
|
||||||
GLuint vao_ = 0;
|
|
||||||
xe::ui::gl::CircularBuffer vertex_buffer_;
|
|
||||||
xe::ui::gl::CircularBuffer index_buffer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ui
|
|
||||||
} // namespace debug
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
#endif // XENIA_DEBUG_UI_IMGUI_RENDERER_H_
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
|
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
@ -25,6 +24,7 @@
|
||||||
#include "xenia/gpu/xenos.h"
|
#include "xenia/gpu/xenos.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
#include "xenia/ui/gl/gl_context.h"
|
#include "xenia/ui/gl/gl_context.h"
|
||||||
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
#include "xenia/ui/window.h"
|
#include "xenia/ui/window.h"
|
||||||
|
|
||||||
// HACK: until we have another impl, we just use gl4 directly.
|
// HACK: until we have another impl, we just use gl4 directly.
|
||||||
|
@ -2182,8 +2182,7 @@ void DrawUI(xe::ui::Window* window, TracePlayer& player, Memory* memory) {
|
||||||
DrawPacketDisassemblerUI(window, player, memory);
|
DrawPacketDisassemblerUI(window, player, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImImpl_Setup();
|
std::unique_ptr<xe::ui::ImGuiDrawer> imgui_drawer_;
|
||||||
void ImImpl_Shutdown();
|
|
||||||
|
|
||||||
int trace_viewer_main(const std::vector<std::wstring>& args) {
|
int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
// Create the emulator but don't initialize so we can setup the window.
|
// Create the emulator but don't initialize so we can setup the window.
|
||||||
|
@ -2202,6 +2201,7 @@ int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
window->on_closed.AddListener([&loop](xe::ui::UIEvent* e) {
|
window->on_closed.AddListener([&loop](xe::ui::UIEvent* e) {
|
||||||
loop->Quit();
|
loop->Quit();
|
||||||
XELOGI("User-initiated death!");
|
XELOGI("User-initiated death!");
|
||||||
|
imgui_drawer_.reset();
|
||||||
exit(1);
|
exit(1);
|
||||||
});
|
});
|
||||||
loop->on_quit.AddListener([&window](xe::ui::UIEvent* e) { window.reset(); });
|
loop->on_quit.AddListener([&window](xe::ui::UIEvent* e) { window.reset(); });
|
||||||
|
@ -2236,9 +2236,10 @@ int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
window->set_title(std::wstring(L"Xenia GPU Trace Viewer: ") + file_name);
|
window->set_title(std::wstring(L"Xenia GPU Trace Viewer: ") + file_name);
|
||||||
|
|
||||||
auto graphics_system = emulator->graphics_system();
|
auto graphics_system = emulator->graphics_system();
|
||||||
Profiler::set_window(nullptr);
|
|
||||||
|
|
||||||
TracePlayer player(loop.get(), emulator->graphics_system());
|
imgui_drawer_ = std::make_unique<xe::ui::ImGuiDrawer>(window.get());
|
||||||
|
|
||||||
|
TracePlayer player(loop.get(), graphics_system);
|
||||||
if (!player.Open(abs_path)) {
|
if (!player.Open(abs_path)) {
|
||||||
XELOGE("Could not load trace file");
|
XELOGE("Could not load trace file");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2290,11 +2291,6 @@ int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
});
|
});
|
||||||
|
|
||||||
window->on_painting.AddListener([&](xe::ui::UIEvent* e) {
|
window->on_painting.AddListener([&](xe::ui::UIEvent* e) {
|
||||||
static bool imgui_setup = false;
|
|
||||||
if (!imgui_setup) {
|
|
||||||
ImImpl_Setup();
|
|
||||||
imgui_setup = true;
|
|
||||||
}
|
|
||||||
auto& io = ImGui::GetIO();
|
auto& io = ImGui::GetIO();
|
||||||
auto current_ticks = Clock::QueryHostTickCount();
|
auto current_ticks = Clock::QueryHostTickCount();
|
||||||
static uint64_t last_ticks = 0;
|
static uint64_t last_ticks = 0;
|
||||||
|
@ -2326,7 +2322,7 @@ int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
// Wait until we are exited.
|
// Wait until we are exited.
|
||||||
loop->AwaitQuit();
|
loop->AwaitQuit();
|
||||||
|
|
||||||
ImImpl_Shutdown();
|
imgui_drawer_.reset();
|
||||||
|
|
||||||
emulator.reset();
|
emulator.reset();
|
||||||
window.reset();
|
window.reset();
|
||||||
|
@ -2334,260 +2330,6 @@ int trace_viewer_main(const std::vector<std::wstring>& args) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(benvanik): move to another file.
|
|
||||||
|
|
||||||
static int shader_handle, vert_handle, frag_handle;
|
|
||||||
static int texture_location, proj_mtx_location;
|
|
||||||
static int position_location, uv_location, colour_location;
|
|
||||||
static size_t vbo_max_size = 20000;
|
|
||||||
static unsigned int vbo_handle, vao_handle;
|
|
||||||
void ImImpl_RenderDrawLists(ImDrawData* data);
|
|
||||||
void ImImpl_Setup() {
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
const GLchar* vertex_shader =
|
|
||||||
"#version 330\n"
|
|
||||||
"uniform mat4 ProjMtx;\n"
|
|
||||||
"in vec2 Position;\n"
|
|
||||||
"in vec2 UV;\n"
|
|
||||||
"in vec4 Color;\n"
|
|
||||||
"out vec2 Frag_UV;\n"
|
|
||||||
"out vec4 Frag_Color;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" Frag_UV = UV;\n"
|
|
||||||
" Frag_Color = Color;\n"
|
|
||||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
const GLchar* fragment_shader =
|
|
||||||
"#version 330\n"
|
|
||||||
"uniform sampler2D Texture;\n"
|
|
||||||
"in vec2 Frag_UV;\n"
|
|
||||||
"in vec4 Frag_Color;\n"
|
|
||||||
"out vec4 Out_Color;\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
shader_handle = glCreateProgram();
|
|
||||||
vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(vert_handle, 1, &vertex_shader, 0);
|
|
||||||
glShaderSource(frag_handle, 1, &fragment_shader, 0);
|
|
||||||
glCompileShader(vert_handle);
|
|
||||||
glCompileShader(frag_handle);
|
|
||||||
glAttachShader(shader_handle, vert_handle);
|
|
||||||
glAttachShader(shader_handle, frag_handle);
|
|
||||||
glLinkProgram(shader_handle);
|
|
||||||
|
|
||||||
texture_location = glGetUniformLocation(shader_handle, "Texture");
|
|
||||||
proj_mtx_location = glGetUniformLocation(shader_handle, "ProjMtx");
|
|
||||||
position_location = glGetAttribLocation(shader_handle, "Position");
|
|
||||||
uv_location = glGetAttribLocation(shader_handle, "UV");
|
|
||||||
colour_location = glGetAttribLocation(shader_handle, "Color");
|
|
||||||
|
|
||||||
glGenBuffers(1, &vbo_handle);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &vao_handle);
|
|
||||||
glBindVertexArray(vao_handle);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
|
|
||||||
glEnableVertexAttribArray(position_location);
|
|
||||||
glEnableVertexAttribArray(uv_location);
|
|
||||||
glEnableVertexAttribArray(colour_location);
|
|
||||||
|
|
||||||
glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE,
|
|
||||||
sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos));
|
|
||||||
glVertexAttribPointer(uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert),
|
|
||||||
(GLvoid*)offsetof(ImDrawVert, uv));
|
|
||||||
glVertexAttribPointer(colour_location, 4, GL_UNSIGNED_BYTE, GL_TRUE,
|
|
||||||
sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col));
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glDisableVertexAttribArray(position_location);
|
|
||||||
glDisableVertexAttribArray(uv_location);
|
|
||||||
glDisableVertexAttribArray(colour_location);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(
|
|
||||||
&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo
|
|
||||||
// because it is more likely to be compatible
|
|
||||||
// with user's existing shader.
|
|
||||||
|
|
||||||
GLuint tex_id;
|
|
||||||
glCreateTextures(GL_TEXTURE_2D, 1, &tex_id);
|
|
||||||
glTextureParameteri(tex_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTextureParameteri(tex_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTextureStorage2D(tex_id, 1, GL_RGBA8, width, height);
|
|
||||||
glTextureSubImage2D(tex_id, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
|
|
||||||
pixels);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->TexID = (void*)(intptr_t)tex_id;
|
|
||||||
|
|
||||||
io.DeltaTime = 1.0f / 60.0f;
|
|
||||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
|
||||||
|
|
||||||
auto& style = ImGui::GetStyle();
|
|
||||||
style.WindowRounding = 0;
|
|
||||||
|
|
||||||
style.Colors[ImGuiCol_Text] = ImVec4(0.89f, 0.90f, 0.90f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
|
||||||
style.Colors[ImGuiCol_Border] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.60f);
|
|
||||||
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.22f);
|
|
||||||
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.00f, 1.00f, 0.00f, 0.78f);
|
|
||||||
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.58f, 0.00f, 0.61f);
|
|
||||||
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.00f, 0.40f, 0.11f, 0.59f);
|
|
||||||
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.00f, 0.68f, 0.00f, 0.68f);
|
|
||||||
style.Colors[ImGuiCol_ScrollbarGrabHovered] =
|
|
||||||
ImVec4(0.00f, 1.00f, 0.15f, 0.62f);
|
|
||||||
style.Colors[ImGuiCol_ScrollbarGrabActive] =
|
|
||||||
ImVec4(0.00f, 0.91f, 0.09f, 0.40f);
|
|
||||||
style.Colors[ImGuiCol_ComboBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.99f);
|
|
||||||
style.Colors[ImGuiCol_CheckMark] = ImVec4(0.74f, 0.90f, 0.72f, 0.50f);
|
|
||||||
style.Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
|
|
||||||
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.34f, 0.75f, 0.11f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_Button] = ImVec4(0.15f, 0.56f, 0.11f, 0.60f);
|
|
||||||
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.19f, 0.72f, 0.09f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.19f, 0.60f, 0.09f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_Header] = ImVec4(0.00f, 0.40f, 0.00f, 0.71f);
|
|
||||||
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.60f, 0.26f, 0.80f);
|
|
||||||
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.75f, 0.00f, 0.80f);
|
|
||||||
style.Colors[ImGuiCol_Column] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_ColumnHovered] = ImVec4(0.36f, 0.89f, 0.38f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_ColumnActive] = ImVec4(0.13f, 0.50f, 0.11f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f);
|
|
||||||
style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(1.00f, 1.00f, 1.00f, 0.60f);
|
|
||||||
style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(1.00f, 1.00f, 1.00f, 0.90f);
|
|
||||||
style.Colors[ImGuiCol_CloseButton] = ImVec4(0.00f, 0.72f, 0.00f, 0.96f);
|
|
||||||
style.Colors[ImGuiCol_CloseButtonHovered] =
|
|
||||||
ImVec4(0.38f, 1.00f, 0.42f, 0.60f);
|
|
||||||
style.Colors[ImGuiCol_CloseButtonActive] = ImVec4(0.56f, 1.00f, 0.64f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_PlotHistogramHovered] =
|
|
||||||
ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
|
||||||
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
|
|
||||||
style.Colors[ImGuiCol_TooltipBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f);
|
|
||||||
|
|
||||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
|
|
||||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
|
||||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
|
||||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
|
||||||
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
|
|
||||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
|
||||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
|
||||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
|
||||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
|
||||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
|
||||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
|
||||||
io.KeyMap[ImGuiKey_A] = 'A';
|
|
||||||
io.KeyMap[ImGuiKey_C] = 'C';
|
|
||||||
io.KeyMap[ImGuiKey_V] = 'V';
|
|
||||||
io.KeyMap[ImGuiKey_X] = 'X';
|
|
||||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
|
||||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
|
||||||
}
|
|
||||||
void ImImpl_Shutdown() {
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
if (vao_handle) glDeleteVertexArrays(1, &vao_handle);
|
|
||||||
if (vbo_handle) glDeleteBuffers(1, &vbo_handle);
|
|
||||||
glDetachShader(shader_handle, vert_handle);
|
|
||||||
glDetachShader(shader_handle, frag_handle);
|
|
||||||
glDeleteShader(vert_handle);
|
|
||||||
glDeleteShader(frag_handle);
|
|
||||||
glDeleteProgram(shader_handle);
|
|
||||||
auto tex_id = static_cast<GLuint>(intptr_t(io.Fonts->TexID));
|
|
||||||
glDeleteTextures(1, &tex_id);
|
|
||||||
ImGui::Shutdown();
|
|
||||||
}
|
|
||||||
void ImImpl_RenderDrawLists(ImDrawData* data) {
|
|
||||||
if (data->CmdListsCount == 0) return;
|
|
||||||
|
|
||||||
// Setup render state: alpha-blending enabled, no face culling, no depth
|
|
||||||
// testing, scissor enabled
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
// Setup orthographic projection matrix
|
|
||||||
const float width = ImGui::GetIO().DisplaySize.x;
|
|
||||||
const float height = ImGui::GetIO().DisplaySize.y;
|
|
||||||
const float ortho_projection[4][4] = {
|
|
||||||
{2.0f / width, 0.0f, 0.0f, 0.0f},
|
|
||||||
{0.0f, 2.0f / -height, 0.0f, 0.0f},
|
|
||||||
{0.0f, 0.0f, -1.0f, 0.0f},
|
|
||||||
{-1.0f, 1.0f, 0.0f, 1.0f},
|
|
||||||
};
|
|
||||||
glProgramUniform1i(shader_handle, texture_location, 0);
|
|
||||||
glProgramUniformMatrix4fv(shader_handle, proj_mtx_location, 1, GL_FALSE,
|
|
||||||
&ortho_projection[0][0]);
|
|
||||||
|
|
||||||
// Grow our buffer according to what we need
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
|
|
||||||
size_t neededBufferSize = data->TotalVtxCount * sizeof(ImDrawVert);
|
|
||||||
if (neededBufferSize > vbo_max_size) {
|
|
||||||
vbo_max_size = neededBufferSize + 5000; // Grow buffer
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_STREAM_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindVertexArray(vao_handle);
|
|
||||||
glUseProgram(shader_handle);
|
|
||||||
|
|
||||||
GLuint ib;
|
|
||||||
glGenBuffers(1, &ib);
|
|
||||||
|
|
||||||
ImTextureID prev_texture_id = 0;
|
|
||||||
for (int n = 0; n < data->CmdListsCount; n++) {
|
|
||||||
const ImDrawList* cmd_list = data->CmdLists[n];
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
(GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx),
|
|
||||||
(GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW);
|
|
||||||
// Copy and convert all vertices into a single contiguous buffer
|
|
||||||
unsigned char* buffer_data =
|
|
||||||
(unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
||||||
memcpy(buffer_data, &cmd_list->VtxBuffer[0],
|
|
||||||
cmd_list->VtxBuffer.size() * sizeof(ImDrawVert));
|
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
const ImDrawIdx* idx_buffer_offset = 0;
|
|
||||||
for (auto cmd = cmd_list->CmdBuffer.begin();
|
|
||||||
cmd != cmd_list->CmdBuffer.end(); ++cmd) {
|
|
||||||
if (cmd->TextureId != prev_texture_id) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)cmd->TextureId);
|
|
||||||
prev_texture_id = cmd->TextureId;
|
|
||||||
}
|
|
||||||
glScissor((int)cmd->ClipRect.x, (int)(height - cmd->ClipRect.w),
|
|
||||||
(int)(cmd->ClipRect.z - cmd->ClipRect.x),
|
|
||||||
(int)(cmd->ClipRect.w - cmd->ClipRect.y));
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->ElemCount, GL_UNSIGNED_SHORT,
|
|
||||||
idx_buffer_offset);
|
|
||||||
idx_buffer_offset += cmd->ElemCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
glDeleteBuffers(1, &ib);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
// Restore modified state
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glUseProgram(0);
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ class GLImmediateTexture : public ImmediateTexture {
|
||||||
GLImmediateTexture(uint32_t width, uint32_t height,
|
GLImmediateTexture(uint32_t width, uint32_t height,
|
||||||
ImmediateTextureFilter filter, bool repeat)
|
ImmediateTextureFilter filter, bool repeat)
|
||||||
: ImmediateTexture(width, height) {
|
: ImmediateTexture(width, height) {
|
||||||
GLuint handle;
|
GLuint gl_handle;
|
||||||
glCreateTextures(GL_TEXTURE_2D, 1, &handle);
|
glCreateTextures(GL_TEXTURE_2D, 1, &gl_handle);
|
||||||
|
|
||||||
GLenum gl_filter = GL_NEAREST;
|
GLenum gl_filter = GL_NEAREST;
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
|
@ -37,21 +37,22 @@ class GLImmediateTexture : public ImmediateTexture {
|
||||||
gl_filter = GL_LINEAR;
|
gl_filter = GL_LINEAR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
glTextureParameteri(handle, GL_TEXTURE_MIN_FILTER, gl_filter);
|
glTextureParameteri(gl_handle, GL_TEXTURE_MIN_FILTER, gl_filter);
|
||||||
glTextureParameteri(handle, GL_TEXTURE_MAG_FILTER, gl_filter);
|
glTextureParameteri(gl_handle, GL_TEXTURE_MAG_FILTER, gl_filter);
|
||||||
|
|
||||||
glTextureParameteri(handle, GL_TEXTURE_WRAP_S,
|
glTextureParameteri(gl_handle, GL_TEXTURE_WRAP_S,
|
||||||
repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
glTextureParameteri(handle, GL_TEXTURE_WRAP_T,
|
glTextureParameteri(gl_handle, GL_TEXTURE_WRAP_T,
|
||||||
repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTextureStorage2D(handle, 1, GL_RGBA8, width, height);
|
glTextureStorage2D(gl_handle, 1, GL_RGBA8, width, height);
|
||||||
|
|
||||||
this->handle = static_cast<uintptr_t>(handle);
|
handle = static_cast<uintptr_t>(gl_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GLImmediateTexture() override {
|
~GLImmediateTexture() override {
|
||||||
//
|
GLuint gl_handle = static_cast<GLuint>(handle);
|
||||||
|
glDeleteTextures(1, &gl_handle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,6 +192,7 @@ void GLImmediateDrawer::Begin(int render_target_width,
|
||||||
// Prepare drawing resources.
|
// Prepare drawing resources.
|
||||||
glUseProgram(program_);
|
glUseProgram(program_);
|
||||||
glBindVertexArray(vao_);
|
glBindVertexArray(vao_);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
|
||||||
|
|
||||||
// Setup orthographic projection matrix and viewport.
|
// Setup orthographic projection matrix and viewport.
|
||||||
const float ortho_projection[4][4] = {
|
const float ortho_projection[4][4] = {
|
||||||
|
@ -203,7 +205,7 @@ void GLImmediateDrawer::Begin(int render_target_width,
|
||||||
glViewport(0, 0, render_target_width, render_target_height);
|
glViewport(0, 0, render_target_width, render_target_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
void GLImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) {
|
||||||
glNamedBufferSubData(vertex_buffer_, 0,
|
glNamedBufferSubData(vertex_buffer_, 0,
|
||||||
batch.vertex_count * sizeof(ImmediateVertex),
|
batch.vertex_count * sizeof(ImmediateVertex),
|
||||||
batch.vertices);
|
batch.vertices);
|
||||||
|
@ -212,22 +214,26 @@ void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
||||||
batch.indices);
|
batch.indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch.scissor) {
|
batch_has_index_buffer_ = !!batch.indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLImmediateDrawer::Draw(const ImmediateDraw& draw) {
|
||||||
|
if (draw.scissor) {
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(batch.scissor_rect[0], batch.scissor_rect[1],
|
glScissor(draw.scissor_rect[0], draw.scissor_rect[1], draw.scissor_rect[2],
|
||||||
batch.scissor_rect[2], batch.scissor_rect[3]);
|
draw.scissor_rect[3]);
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch.texture_handle) {
|
if (draw.texture_handle) {
|
||||||
glBindTextureUnit(0, static_cast<GLuint>(batch.texture_handle));
|
glBindTextureUnit(0, static_cast<GLuint>(draw.texture_handle));
|
||||||
} else {
|
} else {
|
||||||
glBindTextureUnit(0, 0);
|
glBindTextureUnit(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum mode = GL_TRIANGLES;
|
GLenum mode = GL_TRIANGLES;
|
||||||
switch (batch.primitive_type) {
|
switch (draw.primitive_type) {
|
||||||
case ImmediatePrimitiveType::kLines:
|
case ImmediatePrimitiveType::kLines:
|
||||||
mode = GL_LINES;
|
mode = GL_LINES;
|
||||||
break;
|
break;
|
||||||
|
@ -236,21 +242,25 @@ void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch.indices) {
|
if (batch_has_index_buffer_) {
|
||||||
glDrawElements(mode, batch.index_count, GL_UNSIGNED_SHORT, nullptr);
|
glDrawElementsBaseVertex(
|
||||||
|
mode, draw.count, GL_UNSIGNED_SHORT,
|
||||||
|
reinterpret_cast<void*>(draw.index_offset * sizeof(uint16_t)),
|
||||||
|
draw.base_vertex);
|
||||||
} else {
|
} else {
|
||||||
glDrawArrays(mode, 0, batch.vertex_count);
|
glDrawArrays(mode, draw.base_vertex, draw.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
glFlush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLImmediateDrawer::EndDrawBatch() { glFlush(); }
|
||||||
|
|
||||||
void GLImmediateDrawer::End() {
|
void GLImmediateDrawer::End() {
|
||||||
// Restore modified state.
|
// Restore modified state.
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glBindTextureUnit(0, 0);
|
glBindTextureUnit(0, 0);
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
if (!was_current_) {
|
if (!was_current_) {
|
||||||
graphics_context_->ClearCurrent();
|
graphics_context_->ClearCurrent();
|
||||||
|
|
|
@ -32,7 +32,9 @@ class GLImmediateDrawer : public ImmediateDrawer {
|
||||||
void UpdateTexture(ImmediateTexture* texture, const uint8_t* data) override;
|
void UpdateTexture(ImmediateTexture* texture, const uint8_t* data) override;
|
||||||
|
|
||||||
void Begin(int render_target_width, int render_target_height) override;
|
void Begin(int render_target_width, int render_target_height) override;
|
||||||
void Draw(const ImmediateDrawBatch& batch) override;
|
void BeginDrawBatch(const ImmediateDrawBatch& batch) override;
|
||||||
|
void Draw(const ImmediateDraw& draw) override;
|
||||||
|
void EndDrawBatch() override;
|
||||||
void End() override;
|
void End() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -44,6 +46,7 @@ class GLImmediateDrawer : public ImmediateDrawer {
|
||||||
GLuint index_buffer_ = 0;
|
GLuint index_buffer_ = 0;
|
||||||
|
|
||||||
bool was_current_ = false;
|
bool was_current_ = false;
|
||||||
|
bool batch_has_index_buffer_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2015 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_IMGUI_DRAWER_H_
|
||||||
|
#define XENIA_UI_IMGUI_DRAWER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/ui/immediate_drawer.h"
|
||||||
|
|
||||||
|
struct ImDrawData;
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
class GraphicsContext;
|
||||||
|
class Window;
|
||||||
|
|
||||||
|
class ImGuiDrawer {
|
||||||
|
public:
|
||||||
|
ImGuiDrawer(Window* window);
|
||||||
|
~ImGuiDrawer();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Initialize();
|
||||||
|
void SetupFont();
|
||||||
|
|
||||||
|
void RenderDrawLists(ImDrawData* data);
|
||||||
|
|
||||||
|
static ImGuiDrawer* global_drawer_;
|
||||||
|
|
||||||
|
Window* window_ = nullptr;
|
||||||
|
GraphicsContext* graphics_context_ = nullptr;
|
||||||
|
|
||||||
|
std::vector<ImmediateVertex> vertices_;
|
||||||
|
std::vector<uint16_t> indices_;
|
||||||
|
|
||||||
|
std::unique_ptr<ImmediateTexture> font_texture_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_UI_IMGUI_DRAWER_H_
|
|
@ -47,6 +47,9 @@ enum class ImmediatePrimitiveType {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simple vertex used by the immediate mode drawer.
|
// Simple vertex used by the immediate mode drawer.
|
||||||
|
// To avoid translations, this matches both imgui and elemental-forms vertices:
|
||||||
|
// ImDrawVert
|
||||||
|
// el::graphics::Renderer::Vertex
|
||||||
struct ImmediateVertex {
|
struct ImmediateVertex {
|
||||||
float x, y;
|
float x, y;
|
||||||
float u, v;
|
float u, v;
|
||||||
|
@ -55,9 +58,6 @@ struct ImmediateVertex {
|
||||||
|
|
||||||
// All parameters required to draw an immediate-mode batch of vertices.
|
// All parameters required to draw an immediate-mode batch of vertices.
|
||||||
struct ImmediateDrawBatch {
|
struct ImmediateDrawBatch {
|
||||||
// Primitive type the vertices/indices represent.
|
|
||||||
ImmediatePrimitiveType primitive_type = ImmediatePrimitiveType::kTriangles;
|
|
||||||
|
|
||||||
// Vertices to draw.
|
// Vertices to draw.
|
||||||
const ImmediateVertex* vertices = nullptr;
|
const ImmediateVertex* vertices = nullptr;
|
||||||
int vertex_count = 0;
|
int vertex_count = 0;
|
||||||
|
@ -65,6 +65,17 @@ struct ImmediateDrawBatch {
|
||||||
// Optional index buffer indices.
|
// Optional index buffer indices.
|
||||||
const uint16_t* indices = nullptr;
|
const uint16_t* indices = nullptr;
|
||||||
int index_count = 0;
|
int index_count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImmediateDraw {
|
||||||
|
// Primitive type the vertices/indices represent.
|
||||||
|
ImmediatePrimitiveType primitive_type = ImmediatePrimitiveType::kTriangles;
|
||||||
|
// Total number of elements to draw.
|
||||||
|
int count = 0;
|
||||||
|
// Starting offset in the index buffer.
|
||||||
|
int index_offset = 0;
|
||||||
|
// Base vertex of elements, if using an index buffer.
|
||||||
|
int base_vertex = 0;
|
||||||
|
|
||||||
// Texture used when drawing, or nullptr if color only.
|
// Texture used when drawing, or nullptr if color only.
|
||||||
// This is most commonly the handle of an ImmediateTexture.
|
// This is most commonly the handle of an ImmediateTexture.
|
||||||
|
@ -91,8 +102,12 @@ class ImmediateDrawer {
|
||||||
|
|
||||||
// Begins drawing in immediate mode using the given projection matrix.
|
// Begins drawing in immediate mode using the given projection matrix.
|
||||||
virtual void Begin(int render_target_width, int render_target_height) = 0;
|
virtual void Begin(int render_target_width, int render_target_height) = 0;
|
||||||
// Issues an immediate mode draw batch.
|
// Starts a draw batch.
|
||||||
virtual void Draw(const ImmediateDrawBatch& batch) = 0;
|
virtual void BeginDrawBatch(const ImmediateDrawBatch& batch) = 0;
|
||||||
|
// Draws one set of a batch.
|
||||||
|
virtual void Draw(const ImmediateDraw& draw) = 0;
|
||||||
|
// Ends a draw batch.
|
||||||
|
virtual void EndDrawBatch() = 0;
|
||||||
// Ends drawing in immediate mode and flushes contents.
|
// Ends drawing in immediate mode and flushes contents.
|
||||||
virtual void End() = 0;
|
virtual void End() = 0;
|
||||||
|
|
||||||
|
|
|
@ -158,8 +158,8 @@ void MicroprofileDrawer::SetupFont() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack font bitmap into an RGBA texture.
|
// Unpack font bitmap into an RGBA texture.
|
||||||
const int UNPACKED_SIZE = kFontTextureWidth * kFontTextureHeight * 4;
|
const int kUnpackedSize = kFontTextureWidth * kFontTextureHeight * 4;
|
||||||
uint32_t unpacked[UNPACKED_SIZE];
|
uint32_t unpacked[kUnpackedSize];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
int end = kFontTextureWidth * kFontTextureHeight / 8;
|
int end = kFontTextureWidth * kFontTextureHeight / 8;
|
||||||
for (int i = 0; i < end; i++) {
|
for (int i = 0; i < end; i++) {
|
||||||
|
@ -175,7 +175,7 @@ void MicroprofileDrawer::SetupFont() {
|
||||||
false, reinterpret_cast<uint8_t*>(unpacked));
|
false, reinterpret_cast<uint8_t*>(unpacked));
|
||||||
}
|
}
|
||||||
|
|
||||||
MicroprofileDrawer::~MicroprofileDrawer() { font_texture_.reset(); }
|
MicroprofileDrawer::~MicroprofileDrawer() = default;
|
||||||
|
|
||||||
void MicroprofileDrawer::Begin() {
|
void MicroprofileDrawer::Begin() {
|
||||||
graphics_context_->immediate_drawer()->Begin(window_->width(),
|
graphics_context_->immediate_drawer()->Begin(window_->width(),
|
||||||
|
@ -202,15 +202,24 @@ ImmediateVertex* MicroprofileDrawer::BeginVertices(
|
||||||
void MicroprofileDrawer::EndVertices() {}
|
void MicroprofileDrawer::EndVertices() {}
|
||||||
|
|
||||||
void MicroprofileDrawer::Flush() {
|
void MicroprofileDrawer::Flush() {
|
||||||
|
auto drawer = graphics_context_->immediate_drawer();
|
||||||
if (!vertex_count_) {
|
if (!vertex_count_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmediateDrawBatch batch;
|
ImmediateDrawBatch batch;
|
||||||
batch.primitive_type = current_primitive_type_;
|
|
||||||
batch.vertices = vertices_.data();
|
batch.vertices = vertices_.data();
|
||||||
batch.vertex_count = vertex_count_;
|
batch.vertex_count = vertex_count_;
|
||||||
batch.texture_handle = font_texture_->handle;
|
drawer->BeginDrawBatch(batch);
|
||||||
graphics_context_->immediate_drawer()->Draw(batch);
|
|
||||||
|
ImmediateDraw draw;
|
||||||
|
draw.primitive_type = current_primitive_type_;
|
||||||
|
draw.count = vertex_count_;
|
||||||
|
draw.texture_handle = font_texture_->handle;
|
||||||
|
drawer->Draw(draw);
|
||||||
|
|
||||||
|
drawer->EndDrawBatch();
|
||||||
|
|
||||||
vertex_count_ = 0;
|
vertex_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue