mirror of
https://github.com/gwm17/implot.git
synced 2024-11-22 18:28:53 -05:00
[backends] make heatmap use ImPool, add ShowBackendMetrics, misc cleanup
This commit is contained in:
parent
4371c2d200
commit
aa1918ff16
|
@ -37,11 +37,13 @@ namespace Backend {
|
|||
#ifdef IMPLOT_BACKEND_ENABLED
|
||||
void* CreateContext();
|
||||
void DestroyContext();
|
||||
void ShowBackendMetrics();
|
||||
void BustPlotCache();
|
||||
void BustItemCache();
|
||||
#else
|
||||
inline void* CreateContext() { return nullptr; }
|
||||
inline void DestroyContext() {}
|
||||
inline void ShowBackendMetrics() {}
|
||||
inline void BustPlotCache() {}
|
||||
inline void BustItemCache() {}
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace Backend {
|
|||
struct HeatmapShader
|
||||
{
|
||||
GLuint ID = 0; ///< Shader ID for the heatmap shader
|
||||
|
||||
GLuint AttribLocationProjection = 0; ///< Attribute location for the projection matrix uniform
|
||||
GLuint AttribLocationMinValue = 0; ///< Attribute location for the minimum value uniform
|
||||
GLuint AttribLocationMaxValue = 0; ///< Attribute location for the maximum value uniform
|
||||
|
@ -48,6 +47,7 @@ struct HeatmapShader
|
|||
|
||||
struct HeatmapData
|
||||
{
|
||||
ImGuiID ID;
|
||||
HeatmapShader* ShaderProgram; ///< Shader to be used by this heatmap (either ShaderInt or ShaderFloat)
|
||||
GLuint HeatmapTexID; ///< Texture ID of the heatmap 2D texture
|
||||
GLuint ColormapTexID; ///< Texture ID of the colormap 1D texture
|
||||
|
@ -57,6 +57,14 @@ struct HeatmapData
|
|||
float MaxValue; ///< Maximum value of the colormap
|
||||
bool AxisLogX; ///< Whether the X axis is logarithmic or not
|
||||
bool AxisLogY; ///< Whether the Y axis is logarithmic or not
|
||||
|
||||
HeatmapData() {
|
||||
glGenTextures(1, &HeatmapTexID);
|
||||
glBindTexture(GL_TEXTURE_2D, HeatmapTexID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
};
|
||||
|
||||
struct ContextData
|
||||
|
@ -67,9 +75,8 @@ struct ContextData
|
|||
GLuint AttribLocationImGuiProjection = 0; ///< Attribute location for the projection matrix uniform (ImGui default shader)
|
||||
GLuint ImGuiShader = 0; ///< Shader ID of ImGui's default shader
|
||||
|
||||
ImVector<HeatmapData> HeatmapDataList; ///< Array of heatmap data
|
||||
ImPool<HeatmapData> Heatmaps; ///< Array of heatmap data
|
||||
ImVector<GLuint> ColormapIDs; ///< Texture IDs of the colormap textures
|
||||
ImGuiStorage ItemIDs; ///< PlotID <-> Heatmap array index table
|
||||
|
||||
ImVector<float> temp1; ///< Temporary data
|
||||
ImVector<ImS32> temp2; ///< Temporary data
|
||||
|
@ -78,24 +85,21 @@ struct ContextData
|
|||
|
||||
void* CreateContext()
|
||||
{
|
||||
return new ContextData;
|
||||
return IM_NEW(ContextData)();
|
||||
}
|
||||
|
||||
void DestroyContext()
|
||||
{
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
|
||||
for(const HeatmapData& data : Context.HeatmapDataList)
|
||||
glDeleteTextures(1, &data.HeatmapTexID);
|
||||
|
||||
for(GLuint texID : Context.ColormapIDs)
|
||||
ContextData* Context = ((ContextData*)GImPlot->backendCtx);
|
||||
// free OpenGL resources
|
||||
for(int i = 0; i < Context->Heatmaps.GetBufSize(); ++i)
|
||||
glDeleteTextures(1, &Context->Heatmaps.GetByIndex(i)->HeatmapTexID);
|
||||
for(GLuint texID : Context->ColormapIDs)
|
||||
glDeleteTextures(1, &texID);
|
||||
|
||||
glDeleteProgram(Context.ShaderInt.ID);
|
||||
glDeleteProgram(Context.ShaderFloat.ID);
|
||||
|
||||
Context.HeatmapDataList.clear();
|
||||
Context.ItemIDs.Clear();
|
||||
glDeleteProgram(Context->ShaderInt.ID);
|
||||
glDeleteProgram(Context->ShaderFloat.ID);
|
||||
Context->Heatmaps.Clear();
|
||||
IM_DELETE(Context);
|
||||
}
|
||||
|
||||
#define HEATMAP_VERTEX_SHADER_CODE \
|
||||
|
@ -214,8 +218,7 @@ static void RenderCallback(const ImDrawList*, const ImDrawCmd* cmd)
|
|||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
|
||||
int itemID = (int)(intptr_t)cmd->UserCallbackData;
|
||||
int plotIdx = Context.ItemIDs.GetInt(itemID, -1);
|
||||
HeatmapData& data = Context.HeatmapDataList[plotIdx];
|
||||
HeatmapData& data = *Context.Heatmaps.GetByKey(itemID);
|
||||
|
||||
// Get projection matrix of current shader
|
||||
float OrthoProjection[4][4];
|
||||
|
@ -239,7 +242,6 @@ static void ResetState(const ImDrawList*, const ImDrawCmd*)
|
|||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
glUseProgram(Context.ImGuiShader);
|
||||
}
|
||||
|
@ -248,12 +250,10 @@ static void SetTextureData(int itemID, const void* data, GLsizei rows, GLsizei c
|
|||
{
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
|
||||
int idx = Context.ItemIDs.GetInt(itemID, -1);
|
||||
GLuint texID = Context.HeatmapDataList[idx].HeatmapTexID;
|
||||
Context.HeatmapDataList[idx].ShaderProgram = (type == GL_FLOAT ? &Context.ShaderFloat : &Context.ShaderInt);
|
||||
HeatmapData& hm = *Context.Heatmaps.GetByKey(itemID);
|
||||
hm.ShaderProgram = (type == GL_FLOAT ? &Context.ShaderFloat : &Context.ShaderInt);
|
||||
|
||||
// Set heatmap data
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
glBindTexture(GL_TEXTURE_2D, hm.HeatmapTexID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, cols, rows, 0, format, type, data);
|
||||
}
|
||||
|
||||
|
@ -273,18 +273,6 @@ void AddColormap(const ImU32* keys, int count, bool qual)
|
|||
Context.ColormapIDs.push_back(textureID);
|
||||
}
|
||||
|
||||
static GLuint CreateHeatmapTexture()
|
||||
{
|
||||
GLuint textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return textureID;
|
||||
}
|
||||
|
||||
void SetHeatmapData(int itemID, const ImS8* values, int rows, int cols) { SetTextureData(itemID, values, rows, cols, GL_R8I, GL_RED_INTEGER, GL_BYTE); }
|
||||
void SetHeatmapData(int itemID, const ImU8* values, int rows, int cols) { SetTextureData(itemID, values, rows, cols, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE); }
|
||||
void SetHeatmapData(int itemID, const ImS16* values, int rows, int cols) { SetTextureData(itemID, values, rows, cols, GL_R16I, GL_RED_INTEGER, GL_SHORT); }
|
||||
|
@ -335,9 +323,7 @@ void SetHeatmapData(int itemID, const ImU64* values, int rows, int cols)
|
|||
void SetAxisLog(int itemID, bool x_is_log, bool y_is_log, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max)
|
||||
{
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
int idx = Context.ItemIDs.GetInt(itemID, -1);
|
||||
HeatmapData& data = Context.HeatmapDataList[idx];
|
||||
|
||||
HeatmapData& data = *Context.Heatmaps.GetByKey(itemID);
|
||||
data.AxisLogX = x_is_log;
|
||||
data.AxisLogY = y_is_log;
|
||||
data.MinBounds = bounds_min;
|
||||
|
@ -347,42 +333,48 @@ void SetAxisLog(int itemID, bool x_is_log, bool y_is_log, const ImPlotPoint& bou
|
|||
void RenderHeatmap(int itemID, ImDrawList& DrawList, const ImVec2& bounds_min, const ImVec2& bounds_max, float scale_min, float scale_max, ImPlotColormap colormap, bool reverse_y)
|
||||
{
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
int idx = Context.ItemIDs.GetInt(itemID, Context.HeatmapDataList.Size);
|
||||
|
||||
if(idx == Context.HeatmapDataList.Size)
|
||||
{
|
||||
// New entry
|
||||
Context.ItemIDs.SetInt(itemID, Context.HeatmapDataList.Size);
|
||||
Context.HeatmapDataList.push_back(HeatmapData());
|
||||
Context.HeatmapDataList[idx].HeatmapTexID = CreateHeatmapTexture();
|
||||
}
|
||||
|
||||
HeatmapData& data = Context.HeatmapDataList[idx];
|
||||
HeatmapData& data = *Context.Heatmaps.GetOrAddByKey(itemID);
|
||||
data.ID = itemID;
|
||||
data.ColormapTexID = Context.ColormapIDs[colormap];
|
||||
data.MinValue = scale_min;
|
||||
data.MaxValue = scale_max;
|
||||
|
||||
if(Context.ShaderInt.ID == 0 || Context.ShaderFloat.ID == 0)
|
||||
DrawList.AddCallback(CreateHeatmapShader, nullptr);
|
||||
|
||||
DrawList.AddCallback(RenderCallback, (void*)(intptr_t)itemID);
|
||||
DrawList.PrimReserve(6, 4);
|
||||
DrawList.PrimRectUV(bounds_min, bounds_max, ImVec2(0.0f, reverse_y ? 1.0f : 0.0f), ImVec2(1.0f, reverse_y ? 0.0f : 1.0f), 0);
|
||||
DrawList.AddCallback(ResetState, nullptr);
|
||||
}
|
||||
|
||||
void BustPlotCache()
|
||||
{
|
||||
ContextData& Context = *((ContextData*)GImPlot->backendCtx);
|
||||
|
||||
for(const HeatmapData& data : Context.HeatmapDataList)
|
||||
glDeleteTextures(1, &data.HeatmapTexID);
|
||||
|
||||
Context.HeatmapDataList.clear();
|
||||
Context.ItemIDs.Clear();
|
||||
void BustPlotCache() {
|
||||
BustItemCache();
|
||||
}
|
||||
|
||||
void BustItemCache() {}
|
||||
void BustItemCache() {
|
||||
ContextData* Context = ((ContextData*)GImPlot->backendCtx);
|
||||
for(int i = 0; i < Context->Heatmaps.GetBufSize(); ++i)
|
||||
glDeleteTextures(1, &Context->Heatmaps.GetByIndex(i)->HeatmapTexID);
|
||||
Context->Heatmaps.Clear();
|
||||
}
|
||||
|
||||
void ShowBackendMetrics() {
|
||||
ContextData* Context = ((ContextData*)GImPlot->backendCtx);
|
||||
// heatmaps
|
||||
int n_heatmaps = Context->Heatmaps.GetBufSize();
|
||||
if (ImGui::TreeNode("Heatmaps","Heatmaps (%d)",n_heatmaps)) {
|
||||
for (int i = 0; i < n_heatmaps; ++i) {
|
||||
HeatmapData& data = *Context->Heatmaps.GetByIndex(i);
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::TreeNode("Item","Item [0x%08X]", data.ID)) {
|
||||
ImGui::BulletText("HeatmapTexID: %u", data.HeatmapTexID);
|
||||
ImGui::BulletText("ColormapTexID: %u", data.ColormapTexID);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Backend
|
||||
} // namespace ImPlot
|
||||
|
|
|
@ -4067,6 +4067,12 @@ void ShowMetricsWindow(bool* p_popen) {
|
|||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
#ifdef IMPLOT_BACKEND_ENABLED
|
||||
if (ImGui::TreeNode("Backend")) {
|
||||
ImPlot::Backend::ShowBackendMetrics();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
#endif
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user