使用Image组件加载图片
使用Image组件加载图片比较简单,但是还是有需要注意的地方
Imgui中使用图片, 我是使用OpenGL的指令生成纹理贴图,进行设置,然后加载图片使用的是SOIL库
我们生成纹理贴图的时候,需要将纹理提前生成好,然后获取纹理的ID,而不是在帧循环里面和窗口渲染一起进行生成纹理,如果将生成纹理的部分放在了帧循环里面,那么纹理在显示一会之后,图片就会黑掉,此时我猜测可能是因为生成的纹理的部分在循环里面,每一帧都回生成一个纹理,那么内存就会爆掉。然后生成纹理就失败了,此时显示不了图片了。
代码里面还使用了一个图片按钮的组件,可以将图片变成一个有响应时间的按钮,但是个人觉得效果不是很好,还不如直接使用普通按钮,然后设置按钮的悬停,点击,正常三种状态的颜色。
首先贴上创建贴图的代码:
通过这个贴图的加载,我们可以获得:MyClass::textureID,里面存储的就是我们之后要使用的贴图ID,我们把这个变量定义成类的静态成员变量。方便之后一直使用
void MyClass::CreateTexture()
{
ImGuiIO& io = ImGui::GetIO();
//unsigned int texture;
int nWidth = 0, nHeight = 0, nChannel = 0;
const char* picture = "C:\\Users\\FSY\\Desktop\\imguiOfNative\\example\\example_glfw_opengl3\\rgba.jpg";
unsigned char *result = NULL;
// 使用SOIL进行照片像素数据的加载
result = stbi_load(picture, &nWidth, &nHeight, &nChannel, SOIL_LOAD_RGBA);
if (result == NULL)
{
result_string_pointer = stbi_failure_reason();
}
else
{
result_string_pointer = "Image loaded";
}
// 使用GL指令生成贴图,获取贴图ID
glGenTextures(1, &MyClass::textureID);
glBindTexture(GL_TEXTURE_2D, MyClass::textureID);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (result)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, result);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
printf("Failed to load texture");
}
}
然后在Image组件里面就可以使用我们刚创建的贴图进行图片的加载了,我们可以通过设置参数,进行窗口背景颜色的改变。
Image函数的参数,在注释里面有解释。
void MyClass::CreateTestImage()
{
// //设置窗口的padding为0是图片控件充满窗口
//ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
//设置窗口的边框大小为0
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
// 改变窗口的背景颜色
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 100, 0.3));
ImGui::Begin("Image_Window", NULL, ImGuiWindowFlags_NoBringToFrontOnFocus);
ImTextureID image_id = (GLuint *)textureID;
// 带有背景图片的按钮,个人感觉有点丑,建议直接使用普通的按钮,然后设置背景颜色
ImVec2 pos = ImGui::GetCursorScreenPos();
if (ImGui::ImageButton(image_id, ImVec2(90, 15)))
{
printf("点击按钮了");
}
// 第一个参数:生成的纹理的id
// 第2个参数:Image的大小
// 第3,4个参数:UV的起点坐标和终点坐标,UV是被规范化到(0,1)之间的坐标
// 第5个参数:图片的色调
// 第6个参数:图片边框的颜色
ImGui::Image(image_id, ImGui::GetContentRegionAvail(), ImVec2(0.0, 0.0), ImVec2(1.0, 1.0), ImVec4(0, 0, 255, 1), ImVec4(0, 255, 0, 1));
ImGui::End();
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
}
下面是实现的效果:
但是其实还有一种效果,我暂时没有找到实现的方式,那就是将这个图片变成窗口的背景,然后其余的组件是在这个图片的上面。
如果有知道实现的大佬,求一发指导~~感激不尽~~