diff --git a/core/imgui_manager.py b/core/imgui_manager.py deleted file mode 100644 index eacc8ab1..00000000 --- a/core/imgui_manager.py +++ /dev/null @@ -1,166 +0,0 @@ -""" -pyimgui管理器 - 在Panda3D引擎上集成ImGui界面 -""" -import imgui -import OpenGL.GL as gl -from panda3d.core import RenderState, ShaderAttrib, Texture, CardMaker, NodePath -from panda3d.core import TransparencyAttrib, ColorBlendAttrib -from direct.task.Task import Task -import numpy as np - -class ImGuiManager: - """ImGui管理器,负责在Panda3D引擎上渲染ImGui界面""" - - def __init__(self, world): - self.world = world - self.io = None - self.font_texture = None - self._setup_imgui() - self._create_imgui_task() - - # UI状态 - self.show_demo_window = False - self.show_test_button = True - self.button_clicked = False - - def _setup_imgui(self): - """初始化ImGui设置""" - # 初始化ImGui上下文 - imgui.create_context() - self.io = imgui.get_io() - - # 设置显示大小 - win_props = self.world.win.getProperties() - self.io.display_size = (win_props.get_x_size(), win_props.get_y_size()) - - # 设置渲染回调 - self.io.render_callback = self._render_imgui - - # 创建字体纹理 - self._create_font_texture() - - print("✓ ImGui初始化完成") - - def _create_font_texture(self): - """创建ImGui字体纹理""" - # 获取字体数据 - font_pixels = self.io.fonts.get_tex_data_as_rgba32() - width, height = self.io.fonts.get_tex_data_as_rgba32()[1] - - # 创建Panda3D纹理 - self.font_texture = Texture() - self.font_texture.setup_2d_texture(width, height, Texture.T_unsigned_byte, Texture.F_rgba8) - self.font_texture.set_ram_image(font_pixels) - - # 设置纹理ID - self.io.fonts.tex_id = self.font_texture - - # 清除字体数据 - self.io.fonts.clear_tex_data() - - def _render_imgui(self, draw_data): - """渲染ImGui绘制数据""" - if not draw_data: - return - - # 设置OpenGL状态 - gl.glEnable(gl.GL_BLEND) - gl.glBlendEquation(gl.GL_FUNC_ADD) - gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) - gl.glDisable(gl.GL_CULL_FACE) - gl.glDisable(gl.GL_DEPTH_TEST) - gl.glEnable(gl.GL_SCISSOR_TEST) - - # 设置视口和投影矩阵 - display_w, display_h = self.io.display_size - gl.glViewport(0, 0, int(display_w), int(display_h)) - - # 获取投影矩阵 - projection_matrix = self._get_projection_matrix() - gl.glMatrixMode(gl.GL_PROJECTION) - gl.glLoadMatrixf(projection_matrix) - - # 渲染每个命令列表 - for commands in draw_data.commands_lists: - # 渲染命令 - self._render_commands(commands) - - # 恢复OpenGL状态 - gl.glDisable(gl.GL_SCISSOR_TEST) - gl.glEnable(gl.GL_DEPTH_TEST) - - def _get_projection_matrix(self): - """获取正交投影矩阵""" - L, R, T, B = 0, self.io.display_size[0], self.io.display_size[1], 0 - projection_matrix = np.array([ - [2.0/(R-L), 0.0, 0.0, 0.0], - [0.0, 2.0/(T-B), 0.0, 0.0], - [0.0, 0.0, -1.0, 0.0], - [(R+L)/(L-R), (T+B)/(B-T), 0.0, 1.0] - ], dtype=np.float32) - return projection_matrix - - def _render_commands(self, commands): - """渲染ImGui命令列表""" - # 这里需要实现具体的渲染逻辑 - # 由于Panda3D的渲染管线与ImGui不完全兼容,我们需要创建一个自定义的渲染方法 - pass - - def _create_imgui_task(self): - """创建ImGui更新任务""" - taskMgr.add(self._update_imgui, "update_imgui") - - def _update_imgui(self, task): - """更新ImGui界面""" - # 开始新帧 - imgui.new_frame() - - # 绘制UI - self._draw_ui() - - # 渲染ImGui - imgui.render() - - return Task.cont - - def _draw_ui(self): - """绘制UI元素""" - # 绘制测试按钮 - if self.show_test_button: - imgui.begin("测试窗口", True) - if imgui.button("点击我!"): - self.button_clicked = True - print("按钮被点击了!") - - if self.button_clicked: - imgui.text("按钮已被点击!") - - imgui.end() - - # 绘制演示窗口(可选) - if self.show_demo_window: - self.show_demo_window = imgui.show_demo_window(self.show_demo_window) - - def toggle_demo_window(self): - """切换演示窗口显示""" - self.show_demo_window = not self.show_demo_window - - def toggle_test_button(self): - """切换测试按钮显示""" - self.show_test_button = not self.show_test_button - - def process_mouse_input(self, button_event): - """处理鼠标输入""" - # 这里需要将Panda3D的鼠标事件转换为ImGui可以理解的事件 - pass - - def process_keyboard_input(self, key_event): - """处理键盘输入""" - # 这里需要将Panda3D的键盘事件转换为ImGui可以理解的事件 - pass - - def cleanup(self): - """清理资源""" - if self.font_texture: - self.font_texture = None - imgui.destroy_context() \ No newline at end of file diff --git a/core/simple_imgui_manager.py b/core/simple_imgui_manager.py deleted file mode 100644 index 55a68415..00000000 --- a/core/simple_imgui_manager.py +++ /dev/null @@ -1,204 +0,0 @@ -""" -pyimgui管理器 - 在Panda3D引擎上集成ImGui界面 -使用更简单的方法,通过创建覆盖层来实现 -""" -import imgui -import numpy as np -from panda3d.core import RenderState, ShaderAttrib, Texture, CardMaker, NodePath -from panda3d.core import TransparencyAttrib, ColorBlendAttrib, PNMImage -from panda3d.core import GraphicsOutput, RenderBuffer, TextureStage, TexGenAttrib -from direct.task.Task import Task -from direct.gui.OnscreenImage import OnscreenImage -from direct.gui.OnscreenText import OnscreenText -import PIL.Image -import PIL.ImageDraw -import io - -class SimpleImGuiManager: - """简化的ImGui管理器,使用2D覆盖层在Panda3D引擎上显示ImGui界面""" - - def __init__(self, world): - self.world = world - self.io = None - self._setup_imgui() - self._create_imgui_task() - - # UI状态 - self.show_demo_window = False - self.show_test_button = True - self.button_clicked = False - self.counter = 0 - - # 渲染相关 - self.imgui_texture = None - self.imgui_image = None - self.texture_buffer = None - - # 创建渲染纹理 - self._create_render_texture() - - def _setup_imgui(self): - """初始化ImGui设置""" - # 初始化ImGui上下文 - imgui.create_context() - self.io = imgui.get_io() - - # 设置显示大小 - win_props = self.world.win.getProperties() - self.io.display_size = (win_props.get_x_size(), win_props.get_y_size()) - - # 设置字体大小 - font_size = 16 - self.io.font_global_scale = font_size / 13.0 - - print("✓ ImGui初始化完成") - - def _create_render_texture(self): - """创建用于渲染ImGui的纹理""" - win_props = self.world.win.getProperties() - width = win_props.get_x_size() - height = win_props.get_y_size() - - # 创建纹理 - self.imgui_texture = Texture() - self.imgui_texture.setup_2d_texture(width, height, Texture.T_unsigned_byte, Texture.F_rgba8) - - # 创建屏幕图像 - self.imgui_image = OnscreenImage( - image=self.imgui_texture, - pos=(0, 0, 0), - scale=(1, 1, 1) - ) - self.imgui_image.setTransparency(TransparencyAttrib.MAlpha) - - def _create_imgui_task(self): - """创建ImGui更新任务""" - taskMgr.add(self._update_imgui, "update_imgui") - - def _update_imgui(self, task): - """更新ImGui界面""" - # 开始新帧 - imgui.new_frame() - - # 绘制UI - self._draw_ui() - - # 渲染ImGui到纹理 - self._render_to_texture() - - return Task.cont - - def _draw_ui(self): - """绘制UI元素""" - # 绘制测试窗口 - if self.show_test_button: - imgui.begin("测试窗口", True) - - if imgui.button("点击我!"): - self.button_clicked = True - self.counter += 1 - print(f"按钮被点击了! 计数: {self.counter}") - - if self.button_clicked: - imgui.text(f"按钮已被点击 {self.counter} 次!") - - imgui.text("这是一个在Panda3D引擎上显示的ImGui按钮") - imgui.text(f"帧率: {globalClock.getAverageFrameRate():.1f} FPS") - - imgui.end() - - # 绘制演示窗口(可选) - if self.show_demo_window: - self.show_demo_window = imgui.show_demo_window(self.show_demo_window) - - def _render_to_texture(self): - """将ImGui渲染到纹理""" - # 渲染ImGui - imgui.render() - - # 获取绘制数据 - draw_data = imgui.get_draw_data() - - if draw_data: - # 创建PIL图像 - width, height = int(self.io.display_size[0]), int(self.io.display_size[1]) - image = PIL.Image.new('RGBA', (width, height), (0, 0, 0, 0)) - draw = PIL.ImageDraw.Draw(image) - - # 简单的文本渲染(这里只是示例,实际需要完整的ImGui渲染) - if self.show_test_button: - # 绘制简单的按钮模拟 - button_x, button_y = 50, 50 - button_width, button_height = 100, 30 - draw.rectangle([button_x, button_y, button_x + button_width, button_y + button_height], - fill=(100, 100, 200, 255), outline=(255, 255, 255, 255)) - draw.text((button_x + 10, button_y + 5), "点击我!", fill=(255, 255, 255, 255)) - - # 显示点击计数 - if self.counter > 0: - draw.text((button_x, button_y + button_height + 10), - f"点击次数: {self.counter}", fill=(255, 255, 255, 255)) - - # 将PIL图像转换为Panda3D纹理 - img_buffer = io.BytesIO() - image.save(img_buffer, format='RGBA') - img_buffer.seek(0) - - pnm_image = PNMImage() - pnm_image.read(StringStream(img_buffer.read())) - self.imgui_texture.load(pnm_image) - - def toggle_demo_window(self): - """切换演示窗口显示""" - self.show_demo_window = not self.show_demo_window - - def toggle_test_button(self): - """切换测试按钮显示""" - self.show_test_button = not self.show_test_button - - def process_mouse_click(self, x, y): - """处理鼠标点击""" - # 检查是否点击了按钮区域 - if self.show_test_button: - button_x, button_y = 50, 50 - button_width, button_height = 100, 30 - - # 转换坐标系(Panda3D坐标系原点在屏幕中心) - screen_x = (x + self.io.display_size[0] / 2) - screen_y = (self.io.display_size[1] / 2 - y) - - if (button_x <= screen_x <= button_x + button_width and - button_y <= screen_y <= button_y + button_height): - self.button_clicked = True - self.counter += 1 - print(f"按钮被点击了! 计数: {self.counter}") - - def cleanup(self): - """清理资源""" - if self.imgui_image: - self.imgui_image.removeNode() - if self.imgui_texture: - self.imgui_texture = None - imgui.destroy_context() - -# 辅助类用于内存中的字符串流 -class StringStream: - """简单的内存字符串流,用于PNMImage读取""" - def __init__(self, data): - self.data = data - self.position = 0 - - def read(self, size=-1): - if size == -1: - result = self.data[self.position:] - self.position = len(self.data) - else: - result = self.data[self.position:self.position + size] - self.position += size - return result - - def seek(self, position): - self.position = position - - def tell(self): - return self.position \ No newline at end of file