183 lines
6.4 KiB
C++
183 lines
6.4 KiB
C++
// ImGuiTexInspect, a texture inspector widget for dear imgui
|
|
|
|
#pragma once
|
|
#include "imgui.h"
|
|
#include "imgui_internal.h"
|
|
#include "imgui_tex_inspect.h"
|
|
|
|
namespace ImGuiTexInspect
|
|
{
|
|
//-------------------------------------------------------------------------
|
|
// [SECTION] UTILITIES
|
|
//-------------------------------------------------------------------------
|
|
// Returns true if a flag is set
|
|
template <typename TSet, typename TFlag>
|
|
static inline bool HasFlag(TSet set, TFlag flag)
|
|
{
|
|
return (set & flag) == flag;
|
|
}
|
|
|
|
// Set flag or flags in set
|
|
template <typename TSet, typename TFlag>
|
|
static inline void SetFlag(TSet &set, TFlag flags)
|
|
{
|
|
set = static_cast<TSet>(set | flags);
|
|
}
|
|
|
|
// Clear flag or flags in set
|
|
template <typename TSet, typename TFlag>
|
|
static inline void ClearFlag(TSet &set, TFlag flag)
|
|
{
|
|
set = static_cast<TSet>(set & ~flag);
|
|
}
|
|
|
|
static inline float ImFloorSigned(float f)
|
|
{
|
|
return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1);
|
|
}
|
|
|
|
// Proper modulus operator, as opposed to remainder as calculated by %
|
|
template <typename T>
|
|
static inline T Modulus(T a, T b)
|
|
{
|
|
return a - b * ImFloorSigned(a / b);
|
|
}
|
|
|
|
// Defined in recent versions of imgui_internal.h. Included here in case user is on older
|
|
// imgui version.
|
|
|
|
static inline float Round(float f)
|
|
{
|
|
return ImFloorSigned(f + 0.5f);
|
|
}
|
|
|
|
static inline ImVec2 Abs(ImVec2 v)
|
|
{
|
|
return ImVec2(ImAbs(v.x), ImAbs(v.y));
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// [SECTION] STRUCTURES
|
|
//-------------------------------------------------------------------------
|
|
struct ShaderOptions
|
|
{
|
|
float ColorTransform[16] = {}; // See CurrentInspector_SetColorMatrix for details
|
|
float ColorOffset[4] = {};
|
|
|
|
ImVec4 BackgroundColor = {0,0,0,0}; // Color used for alpha blending
|
|
float PremultiplyAlpha = 0; // If 1 then color will be multiplied by alpha in shader, before blend stage
|
|
float DisableFinalAlpha = 0; // If 1 then fragment shader will always output alpha = 1
|
|
|
|
bool ForceNearestSampling = false; // If true fragment shader will always sample from texel centers
|
|
|
|
ImVec2 GridWidth = {0,0}; // Width in UV coords of grid line
|
|
ImVec4 GridColor = {0,0,0,0};
|
|
|
|
void ResetColorTransform();
|
|
ShaderOptions();
|
|
};
|
|
|
|
struct Inspector
|
|
{
|
|
ImGuiID ID;
|
|
bool Initialized = false;
|
|
|
|
// Texture
|
|
ImTextureID Texture = ImTextureID{};
|
|
ImVec2 TextureSize = {0, 0}; // Size in texels of texture
|
|
float PixelAspectRatio = 1; // Values other than 1 not supported yet
|
|
|
|
// View State
|
|
bool IsDragging = false; // Is user currently dragging to pan view
|
|
ImVec2 PanPos = {0.5f, 0.5f}; // The UV value at the center of the current view
|
|
ImVec2 Scale = {1, 1}; // 1 pixel is 1 texel
|
|
|
|
ImVec2 PanelTopLeftPixel = {0, 0}; // Top left of view in ImGui pixel coordinates
|
|
ImVec2 PanelSize = {0, 0}; // Size of area allocated to drawing the image in pixels.
|
|
|
|
ImVec2 ViewTopLeftPixel = {0, 0}; // Position in ImGui pixel coordinates
|
|
ImVec2 ViewSize = {0, 0}; // Rendered size of current image. This could be smaller than panel size if user has zoomed out.
|
|
ImVec2 ViewSizeUV = {0, 0}; // Visible region of the texture in UV coordinates
|
|
|
|
/* Conversion transforms to go back and forth between screen pixels (what ImGui considers screen pixels) and texels*/
|
|
Transform2D TexelsToPixels;
|
|
Transform2D PixelsToTexels;
|
|
|
|
// Cached pixel data
|
|
bool HaveCurrentTexelData = false;
|
|
BufferDesc Buffer;
|
|
|
|
/* We don't actually access texel data through this pointer. We just
|
|
* manage its lifetime. The backend might have asked us to allocated a
|
|
* buffer, or it might not. The pointer we actually use to access texel
|
|
* data is in the Buffer object above (which depending on what the backend
|
|
* did might point to the same memory as this pointer)
|
|
*/
|
|
ImU8 *DataBuffer = nullptr;
|
|
size_t DataBufferSize = 0;
|
|
|
|
// Configuration
|
|
InspectorFlags Flags = 0;
|
|
|
|
// Background mode
|
|
InspectorAlphaMode AlphaMode = InspectorAlphaMode_ImGui;
|
|
ImVec4 CustomBackgroundColor = {0, 0, 0, 1};
|
|
|
|
// Scaling limits
|
|
ImVec2 ScaleMin = {0.02f, 0.02f};
|
|
ImVec2 ScaleMax = {500, 500};
|
|
|
|
// Grid
|
|
float MinimumGridSize = 4; // Don't draw the grid if lines would be closer than MinimumGridSize pixels
|
|
|
|
// Annotations
|
|
ImU32 MaxAnnotatedTexels = 0;
|
|
|
|
// Color transformation
|
|
ShaderOptions ActiveShaderOptions;
|
|
ShaderOptions CachedShaderOptions;
|
|
|
|
~Inspector();
|
|
};
|
|
|
|
//-------------------------------------------------------------------------
|
|
// [SECTION] INTERNAL FUNCTIONS
|
|
//-------------------------------------------------------------------------
|
|
|
|
Inspector *GetByKey(const Context *ctx, ImGuiID key);
|
|
Inspector *GetOrAddByKey(Context *ctx, ImGuiID key);
|
|
|
|
void SetPanPos(Inspector *inspector, ImVec2 pos);
|
|
void SetScale(Inspector *inspector, ImVec2 scale);
|
|
void SetScale(Inspector *inspector, float scaleY);
|
|
void RoundPanPos(Inspector *inspector);
|
|
|
|
ImU8 *GetBuffer(Inspector *inspector, size_t bytes);
|
|
|
|
/* GetTexelsToPixels
|
|
* Calculate a transform to convert from texel coordinates to screen pixel coordinates
|
|
* */
|
|
Transform2D GetTexelsToPixels(ImVec2 screenTopLeft, ImVec2 screenViewSize, ImVec2 uvTopLeft, ImVec2 uvViewSize, ImVec2 textureSize);
|
|
|
|
//-------------------------------------------------------------------------
|
|
// [SECTION] IMGUI UTILS
|
|
//-------------------------------------------------------------------------
|
|
/* TextVector
|
|
* Draws a single-column ImGui table with one row for each provided string
|
|
*/
|
|
void TextVector(const char *title, const char *const *strings, int n);
|
|
|
|
/* PushDisabled & PopDisabled
|
|
* Push and Pop and ImGui styles that disable and "grey out" ImGui elements
|
|
* by making them non interactive and transparent*/
|
|
void PushDisabled();
|
|
void PopDisabled();
|
|
|
|
//-------------------------------------------------------------------------
|
|
// [SECTION] BACKEND FUNCTIONS
|
|
//-------------------------------------------------------------------------
|
|
void BackEnd_SetShader(const ImDrawList *drawList, const ImDrawCmd *cmd, const Inspector *inspector);
|
|
bool BackEnd_GetData(Inspector *inspector, ImTextureID texture, int x, int y, int width, int height, BufferDesc *buffer);
|
|
|
|
} // namespace ImGuiTexInspect
|