Moving imgui to the new ImmediateDrawer.

This commit is contained in:
Ben Vanik
2015-11-05 23:03:02 -08:00
parent c631b965d7
commit 4c2257a29d
10 changed files with 198 additions and 564 deletions

View File

@@ -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();

View File

@@ -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

File diff suppressed because one or more lines are too long

View 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_

View File

@@ -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;

View File

@@ -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;
}