IMGUI重绘按钮文本按钮
bool ImGui::ImageLabelButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& image_size, const char* label, const ImVec2& label_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
const ImVec2 label_text_size = CalcTextSize(label, NULL, true);
ImVec2 label_real_size = CalcItemSize(label_size, label_text_size.x + padding.x * 2.0f, label_text_size.y + padding.y * 2.0f);
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(image_size.x + label_real_size.x, (image_size.y > label_real_size.y) ? image_size.y : label_real_size.y) + padding * 2.0f);
ItemSize(bb);
if (!ItemAdd(bb, id))
return false;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
// Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
if (bg_col.w > 0.0f)
window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Min + image_size + padding, uv0, uv1, GetColorU32(tint_col));
RenderTextClipped(bb.Min + ImVec2(image_size.x, 0) + padding, bb.Max - padding, label, NULL, &label_text_size, g.Style.ButtonTextAlign, &bb);
return pressed;
}
bool ImGui::ImageLabelButton(ImTextureID user_texture_id, const ImVec2& image_size, const char* label, const ImVec2& label_size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (window->SkipItems)
return false;
// Default to using texture ID as ID. User can still push string/integer prefixes.
PushID((void*)(intptr_t)user_texture_id);
const ImGuiID id = window->GetID("#imagelabel");
PopID();
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding;
return ImageLabelButtonEx(id, user_texture_id, image_size, label, label_size, uv0, uv1, padding, bg_col, tint_col, ImGuiButtonFlags_None);
}
使用案例
class PictureTexture {
public:
PictureTexture() {}
PictureTexture(const std::string& fname) :m_fname(fname) {}
~PictureTexture()
{
exit();
}
private:
bool m_b_init = false;
public:
std::string m_fname = (u8"");
GLuint m_texture_id = 0;
ImVec2 m_texture_size = ImVec2(0, 0);
public:
bool is_init() {
return m_b_init;
}
void init(int width, int height) {
if (m_b_init == false)
{
glGenTextures(1, &m_texture_id);
m_b_init = true;
}
cv::Mat img = cv::imread(m_fname.c_str(), cv::IMREAD_UNCHANGED);
if (!img.empty())
{
cv::Mat tmp = {};
switch (img.channels())
{
case 3: {
tmp = cv::Mat::zeros(width, height, CV_8UC3);
resize(img, tmp, tmp.size());
cv::cvtColor(tmp, tmp, cv::COLOR_BGR2RGBA);
}
break;
case 4: {
tmp = cv::Mat::zeros(width, height, CV_8UC4);
resize(img, tmp, tmp.size());
cv::cvtColor(tmp, tmp, cv::COLOR_BGRA2RGBA);
}
break;
default: break;
}
m_texture_size = ImVec2((float)tmp.rows, (float)tmp.cols);
//将texture_ID设置为2D纹理信息
glBindTexture(GL_TEXTURE_2D, m_texture_id);
//纹理放大缩小使用线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//纹理水平竖直方向外扩使用重复贴图
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//纹理水平竖直方向外扩使用边缘像素贴图(与重复贴图二选一)
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
//将图像内存用作纹理信息
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmp.cols, tmp.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp.data);
glGenerateMipmap(GL_TEXTURE_2D);
}
}
void init() {
if (m_b_init == false)
{
glGenTextures(1, &m_texture_id);
m_b_init = true;
}
cv::Mat tmp = cv::imread(m_fname.c_str(), cv::IMREAD_UNCHANGED);
if (!tmp.empty())
{
switch (tmp.channels())
{
case 3: {
cv::cvtColor(tmp, tmp, cv::COLOR_BGR2RGBA);
}
break;
case 4: {
cv::cvtColor(tmp, tmp, cv::COLOR_BGRA2RGBA);
}
break;
default: break;
}
m_texture_size = ImVec2((float)tmp.cols, (float)tmp.rows);
//将texture_ID设置为2D纹理信息
glBindTexture(GL_TEXTURE_2D, m_texture_id);
//纹理放大缩小使用线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//纹理水平竖直方向外扩使用重复贴图
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//纹理水平竖直方向外扩使用边缘像素贴图(与重复贴图二选一)
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
//将图像内存用作纹理信息
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmp.cols, tmp.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp.data);
glGenerateMipmap(GL_TEXTURE_2D);
}
}
void exit() {
if (m_b_init == true)
{
glBindTexture(GL_TEXTURE_2D, 0); // unbind texture
glDeleteTextures(1, &m_texture_id);
m_b_init = false;
}
}
};
typedef enum ImgType {
IMGTYPE_NUL = 0,
/////////////////
IMGTYPE_LOGO,
/////////////////
IMGTYPE_ROTATE,
IMGTYPE_REFOCUS,
IMGTYPE_EXPOSURE,
IMGTYPE_RESET,
/////////////////
IMGTYPE_COLORSETTING,
IMGTYPE_POSITION,
IMGTYPE_TRACKCURSOR,
IMGTYPE_TARGETCURSOR,
IMGTYPE_SCREENCONTROL,
/////////////////
IMGTYPE_MAX,
}ImgType;
std::unordered_map<ImgType, PictureTexture> m_imgMap = {
{IMGTYPE_LOGO, PictureTexture(u8"res/img/logo.png")},
};
void ShowLogo()
{
auto itLogo = m_imgMap.find(IMGTYPE_LOGO);
if (itLogo != m_imgMap.end())
{
if (!itLogo->second.is_init())
{
itLogo->second.init();
}
ImGui::Image(GLuint2ImTextureID(itLogo->second.m_texture_id), itLogo->second.m_texture_size);
}
}
void MainLoop()
{
// Main loop
while (!glfwWindowShouldClose(window))
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ShowLogo();
// Rendering
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
}