Moving imgui to the new ImmediateDrawer.
This commit is contained in:
@@ -25,8 +25,8 @@ class GLImmediateTexture : public ImmediateTexture {
|
||||
GLImmediateTexture(uint32_t width, uint32_t height,
|
||||
ImmediateTextureFilter filter, bool repeat)
|
||||
: ImmediateTexture(width, height) {
|
||||
GLuint handle;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &handle);
|
||||
GLuint gl_handle;
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &gl_handle);
|
||||
|
||||
GLenum gl_filter = GL_NEAREST;
|
||||
switch (filter) {
|
||||
@@ -37,21 +37,22 @@ class GLImmediateTexture : public ImmediateTexture {
|
||||
gl_filter = GL_LINEAR;
|
||||
break;
|
||||
}
|
||||
glTextureParameteri(handle, GL_TEXTURE_MIN_FILTER, gl_filter);
|
||||
glTextureParameteri(handle, GL_TEXTURE_MAG_FILTER, gl_filter);
|
||||
glTextureParameteri(gl_handle, GL_TEXTURE_MIN_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);
|
||||
glTextureParameteri(handle, GL_TEXTURE_WRAP_T,
|
||||
glTextureParameteri(gl_handle, GL_TEXTURE_WRAP_T,
|
||||
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 {
|
||||
//
|
||||
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.
|
||||
glUseProgram(program_);
|
||||
glBindVertexArray(vao_);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
|
||||
|
||||
// Setup orthographic projection matrix and viewport.
|
||||
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);
|
||||
}
|
||||
|
||||
void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
||||
void GLImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) {
|
||||
glNamedBufferSubData(vertex_buffer_, 0,
|
||||
batch.vertex_count * sizeof(ImmediateVertex),
|
||||
batch.vertices);
|
||||
@@ -212,22 +214,26 @@ void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
||||
batch.indices);
|
||||
}
|
||||
|
||||
if (batch.scissor) {
|
||||
batch_has_index_buffer_ = !!batch.indices;
|
||||
}
|
||||
|
||||
void GLImmediateDrawer::Draw(const ImmediateDraw& draw) {
|
||||
if (draw.scissor) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(batch.scissor_rect[0], batch.scissor_rect[1],
|
||||
batch.scissor_rect[2], batch.scissor_rect[3]);
|
||||
glScissor(draw.scissor_rect[0], draw.scissor_rect[1], draw.scissor_rect[2],
|
||||
draw.scissor_rect[3]);
|
||||
} else {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
if (batch.texture_handle) {
|
||||
glBindTextureUnit(0, static_cast<GLuint>(batch.texture_handle));
|
||||
if (draw.texture_handle) {
|
||||
glBindTextureUnit(0, static_cast<GLuint>(draw.texture_handle));
|
||||
} else {
|
||||
glBindTextureUnit(0, 0);
|
||||
}
|
||||
|
||||
GLenum mode = GL_TRIANGLES;
|
||||
switch (batch.primitive_type) {
|
||||
switch (draw.primitive_type) {
|
||||
case ImmediatePrimitiveType::kLines:
|
||||
mode = GL_LINES;
|
||||
break;
|
||||
@@ -236,21 +242,25 @@ void GLImmediateDrawer::Draw(const ImmediateDrawBatch& batch) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (batch.indices) {
|
||||
glDrawElements(mode, batch.index_count, GL_UNSIGNED_SHORT, nullptr);
|
||||
if (batch_has_index_buffer_) {
|
||||
glDrawElementsBaseVertex(
|
||||
mode, draw.count, GL_UNSIGNED_SHORT,
|
||||
reinterpret_cast<void*>(draw.index_offset * sizeof(uint16_t)),
|
||||
draw.base_vertex);
|
||||
} else {
|
||||
glDrawArrays(mode, 0, batch.vertex_count);
|
||||
glDrawArrays(mode, draw.base_vertex, draw.count);
|
||||
}
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
void GLImmediateDrawer::EndDrawBatch() { glFlush(); }
|
||||
|
||||
void GLImmediateDrawer::End() {
|
||||
// Restore modified state.
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glBindTextureUnit(0, 0);
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
if (!was_current_) {
|
||||
graphics_context_->ClearCurrent();
|
||||
|
||||
@@ -32,7 +32,9 @@ class GLImmediateDrawer : public ImmediateDrawer {
|
||||
void UpdateTexture(ImmediateTexture* texture, const uint8_t* data) 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;
|
||||
|
||||
private:
|
||||
@@ -44,6 +46,7 @@ class GLImmediateDrawer : public ImmediateDrawer {
|
||||
GLuint index_buffer_ = 0;
|
||||
|
||||
bool was_current_ = false;
|
||||
bool batch_has_index_buffer_ = false;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
197
src/xenia/ui/imgui_drawer.cc
Normal file
197
src/xenia/ui/imgui_drawer.cc
Normal file
File diff suppressed because one or more lines are too long
51
src/xenia/ui/imgui_drawer.h
Normal file
51
src/xenia/ui/imgui_drawer.h
Normal file
@@ -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.
|
||||
// To avoid translations, this matches both imgui and elemental-forms vertices:
|
||||
// ImDrawVert
|
||||
// el::graphics::Renderer::Vertex
|
||||
struct ImmediateVertex {
|
||||
float x, y;
|
||||
float u, v;
|
||||
@@ -55,9 +58,6 @@ struct ImmediateVertex {
|
||||
|
||||
// All parameters required to draw an immediate-mode batch of vertices.
|
||||
struct ImmediateDrawBatch {
|
||||
// Primitive type the vertices/indices represent.
|
||||
ImmediatePrimitiveType primitive_type = ImmediatePrimitiveType::kTriangles;
|
||||
|
||||
// Vertices to draw.
|
||||
const ImmediateVertex* vertices = nullptr;
|
||||
int vertex_count = 0;
|
||||
@@ -65,6 +65,17 @@ struct ImmediateDrawBatch {
|
||||
// Optional index buffer indices.
|
||||
const uint16_t* indices = nullptr;
|
||||
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.
|
||||
// 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.
|
||||
virtual void Begin(int render_target_width, int render_target_height) = 0;
|
||||
// Issues an immediate mode draw batch.
|
||||
virtual void Draw(const ImmediateDrawBatch& batch) = 0;
|
||||
// Starts a draw batch.
|
||||
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.
|
||||
virtual void End() = 0;
|
||||
|
||||
|
||||
@@ -158,8 +158,8 @@ void MicroprofileDrawer::SetupFont() {
|
||||
}
|
||||
|
||||
// Unpack font bitmap into an RGBA texture.
|
||||
const int UNPACKED_SIZE = kFontTextureWidth * kFontTextureHeight * 4;
|
||||
uint32_t unpacked[UNPACKED_SIZE];
|
||||
const int kUnpackedSize = kFontTextureWidth * kFontTextureHeight * 4;
|
||||
uint32_t unpacked[kUnpackedSize];
|
||||
int idx = 0;
|
||||
int end = kFontTextureWidth * kFontTextureHeight / 8;
|
||||
for (int i = 0; i < end; i++) {
|
||||
@@ -175,7 +175,7 @@ void MicroprofileDrawer::SetupFont() {
|
||||
false, reinterpret_cast<uint8_t*>(unpacked));
|
||||
}
|
||||
|
||||
MicroprofileDrawer::~MicroprofileDrawer() { font_texture_.reset(); }
|
||||
MicroprofileDrawer::~MicroprofileDrawer() = default;
|
||||
|
||||
void MicroprofileDrawer::Begin() {
|
||||
graphics_context_->immediate_drawer()->Begin(window_->width(),
|
||||
@@ -202,15 +202,24 @@ ImmediateVertex* MicroprofileDrawer::BeginVertices(
|
||||
void MicroprofileDrawer::EndVertices() {}
|
||||
|
||||
void MicroprofileDrawer::Flush() {
|
||||
auto drawer = graphics_context_->immediate_drawer();
|
||||
if (!vertex_count_) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmediateDrawBatch batch;
|
||||
batch.primitive_type = current_primitive_type_;
|
||||
batch.vertices = vertices_.data();
|
||||
batch.vertex_count = vertex_count_;
|
||||
batch.texture_handle = font_texture_->handle;
|
||||
graphics_context_->immediate_drawer()->Draw(batch);
|
||||
drawer->BeginDrawBatch(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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user