package com.chuangzhou.vivid2D.test; import com.chuangzhou.vivid2D.render.awt.ModelLayerPanel; import com.chuangzhou.vivid2D.render.awt.ModelRenderPanel; import com.chuangzhou.vivid2D.render.awt.TransformPanel; import com.chuangzhou.vivid2D.render.model.Model2D; import com.chuangzhou.vivid2D.render.model.ModelPart; import javax.swing.*; import java.awt.*; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.util.List; /** * 简单的测试示例:创建一个 Model2D,添加几层(部件), * 然后在 JFrame 中展示 ModelLayerPanel(左侧)、ModelRenderPanel(中间渲染区) * 和模型树(右侧)以便观察变化。 */ public class ModelLayerPanelTest { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8)); System.setErr(new PrintStream(System.err, true, StandardCharsets.UTF_8)); // 创建示例模型并添加图层 Model2D model = new Model2D("示例模型"); // 调整一些初始属性(可选) ModelPart person = model.getPart("人物"); if (person != null) { try { person.setOpacity(0.85f); } catch (Exception ignored) { } } // 创建 UI JFrame frame = new JFrame("ModelLayerPanel 测试(含渲染面板和变换面板)"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setLayout(new BorderLayout()); // 左侧:图层面板(传入 renderPanel 后可在面板中绑定贴图到 GL 上下文) // 先创建一个占位 renderPanel,再把它传给 layerPanel(ModelRenderPanel 构造需要尺寸) ModelRenderPanel renderPanel = new ModelRenderPanel(model, 640, 480); ModelLayerPanel layerPanel = new ModelLayerPanel(model, renderPanel); layerPanel.setPreferredSize(new Dimension(260, 600)); frame.add(layerPanel, BorderLayout.WEST); // 中间:渲染面板 renderPanel.setPreferredSize(new Dimension(640, 480)); frame.add(renderPanel, BorderLayout.CENTER); // 创建变换面板 TransformPanel transformPanel = new TransformPanel(renderPanel); // 右侧:创建选项卡面板,包含模型树和变换面板 JTabbedPane rightTabbedPane = new JTabbedPane(); // 模型树选项卡 JTree tree = new JTree(model.toTreeNode()); JScrollPane treeScroll = new JScrollPane(tree); treeScroll.setPreferredSize(new Dimension(280, 600)); rightTabbedPane.addTab("模型结构", treeScroll); // 变换面板选项卡 JScrollPane transformScroll = new JScrollPane(transformPanel); transformScroll.setPreferredSize(new Dimension(280, 600)); rightTabbedPane.addTab("变换控制", transformScroll); rightTabbedPane.setPreferredSize(new Dimension(300, 600)); frame.add(rightTabbedPane, BorderLayout.EAST); // 底部:演示按钮(刷新树以反映面板中对模型的更改) JPanel bottom = new JPanel(new FlowLayout(FlowLayout.LEFT)); JButton refreshBtn = new JButton("刷新模型树"); refreshBtn.addActionListener(e -> { tree.setModel(new javax.swing.tree.DefaultTreeModel(model.toTreeNode())); for (int i = 0; i < tree.getRowCount(); i++) tree.expandRow(i); // 同步通知渲染面板(如果需要)去刷新模型 try { renderPanel.setModel(model); } catch (Exception ignored) { } }); bottom.add(refreshBtn); JButton printOrderBtn = new JButton("打印部件顺序(控制台)"); printOrderBtn.addActionListener(e -> { System.out.println("当前模型部件顺序:"); for (ModelPart p : model.getParts()) { System.out.println(" - " + p.getName() + " (可见=" + p.isVisible() + ", 不透明度=" + p.getOpacity() + ")"); } }); bottom.add(printOrderBtn); // 添加选中部件更新按钮 JButton updateSelectionBtn = new JButton("更新选中部件"); updateSelectionBtn.addActionListener(e -> { renderPanel.executeInGLContext(() -> { List selectedPart = renderPanel.getSelectedParts(); transformPanel.setSelectedParts(selectedPart); }); }); bottom.add(updateSelectionBtn); frame.add(bottom, BorderLayout.SOUTH); // 添加模型点击监听器,自动更新变换面板的选中部件 renderPanel.addModelClickListener((mesh, modelX, modelY, screenX, screenY) -> { if (mesh == null) return; System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY); // 自动更新变换面板的选中部件 List selectedPart = renderPanel.getSelectedParts(); transformPanel.setSelectedParts(selectedPart); // 切换到变换控制选项卡 rightTabbedPane.setSelectedIndex(1); }); // 监听窗口关闭,确保释放 GL 资源 frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent e) { // 先释放渲染面板相关 GL 资源与线程 //try { // renderPanel.dispose(); //} catch (Throwable t) { // t.printStackTrace(); //} } @Override public void windowClosed(java.awt.event.WindowEvent e) { // 进程退出(确保彻底关闭) try { renderPanel.dispose(); } catch (Throwable ignored) { } model.saveToFile("C:\\Users\\Administrator\\Desktop\\testing.model"); System.exit(0); } }); frame.setSize(1300, 700); frame.setLocationRelativeTo(null); frame.setVisible(true); }); } }