【Dear imgui基础学习】有关Image的实现

使用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);
}

下面是实现的效果:

但是其实还有一种效果,我暂时没有找到实现的方式,那就是将这个图片变成窗口的背景,然后其余的组件是在这个图片的上面。

如果有知道实现的大佬,求一发指导~~感激不尽~~

你可能感兴趣的:(Imgui)