refactor(render):优化渲染系统代码结构与字体加载逻辑- 简化模型点击监听器为 lambda 表达式- 移除未使用的 Mesh2D 和 ModelClickListener 导入- 使用方法引用替换匿名渲染调用- 重命名 getProgrami 方法为 getProgram

- 改进字体加载逻辑,支持多平台路径查找
- 添加字体文件不存在时的日志警告- 更新着色器程序链接与验证状态检查调用新方法名
This commit is contained in:
tzdwindows 7
2025-10-26 07:09:58 +08:00
parent 5775bc5d7e
commit 43aab9f0fd
4 changed files with 60 additions and 29 deletions

View File

@@ -1,6 +1,6 @@
#Tue Feb 04 17:20:23 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -7,9 +7,12 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.IntSupplier;
@@ -703,7 +706,7 @@ public final class RenderSystem {
public static void enableBlend() {
if (!isOnRenderThread()) {
recordRenderCall(() -> _enableBlend());
recordRenderCall(RenderSystem::_enableBlend);
} else {
_enableBlend();
}
@@ -716,7 +719,7 @@ public final class RenderSystem {
public static void disableBlend() {
if (!isOnRenderThread()) {
recordRenderCall(() -> _disableBlend());
recordRenderCall(RenderSystem::_disableBlend);
} else {
_disableBlend();
}
@@ -789,7 +792,7 @@ public final class RenderSystem {
GL20.glLinkProgram(program);
}
public static int getProgrami(int program, int pname) {
public static int getProgram(int program, int pname) {
if (!isOnRenderThread()) {
throw new IllegalStateException("Program queries must be on render thread");
}
@@ -832,18 +835,51 @@ public final class RenderSystem {
}
public static ByteBuffer loadFont(String fontFileName) throws IOException {
Path path = Path.of("C:/Windows/Fonts/" + fontFileName);
try (FileChannel fc = FileChannel.open(path, StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocateDirect((int) fc.size());
while (buffer.hasRemaining()) {
fc.read(buffer);
List<Path> possiblePaths = getFontPaths(fontFileName);
for (Path fontPath : possiblePaths) {
if (Files.exists(fontPath)) {
try (FileChannel fc = FileChannel.open(fontPath, StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocateDirect((int) fc.size());
while (buffer.hasRemaining()) {
fc.read(buffer);
}
buffer.flip();
return buffer;
}
}
buffer.flip();
return buffer;
}
logger.warn("无法加载字体: {}", fontFileName);
return null;
}
private static List<Path> getFontPaths(String fontFileName) {
String os = System.getProperty("os.name").toLowerCase();
List<Path> paths = new ArrayList<>();
if (os.contains("win")) {
paths.add(Path.of("C:/Windows/Fonts/" + fontFileName));
for (char drive = 'C'; drive <= 'E'; drive++) {
paths.add(Path.of(drive + ":/Windows/Fonts/" + fontFileName));
}
} else if (os.contains("mac")) {
paths.add(Path.of(System.getProperty("user.home"), "Library", "Fonts", fontFileName));
paths.add(Path.of("/Library", "Fonts", fontFileName));
paths.add(Path.of("/System", "Library", "Fonts", fontFileName));
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
paths.add(Path.of("/usr/share/fonts", fontFileName));
paths.add(Path.of("/usr/local/share/fonts", fontFileName));
paths.add(Path.of(System.getProperty("user.home"), ".local/share/fonts", fontFileName));
paths.add(Path.of(System.getProperty("user.home"), ".fonts", fontFileName));
paths.add(Path.of("/usr/X11R6/lib/X11/fonts", fontFileName));
} else {
paths.add(Path.of(System.getProperty("user.home"), "fonts", fontFileName));
}
return paths;
}
// 完整的程序链接方法
public static int linkProgram(int vertexShader, int fragmentShader) {
assertOnRenderThread();
@@ -852,7 +888,7 @@ public final class RenderSystem {
attachShader(program, fragmentShader);
linkProgram(program);
int status = getProgrami(program, GL20.GL_LINK_STATUS);
int status = getProgram(program, GL20.GL_LINK_STATUS);
if (status == GL11.GL_FALSE) {
String log = getProgramInfoLog(program);
deleteProgram(program);
@@ -880,7 +916,7 @@ public final class RenderSystem {
attachShader(program, fragmentShader);
linkProgram(program);
int status = getProgrami(program, GL20.GL_LINK_STATUS);
int status = getProgram(program, GL20.GL_LINK_STATUS);
if (status == GL11.GL_FALSE) {
String log = getProgramInfoLog(program);
deleteProgram(program);

View File

@@ -154,7 +154,7 @@ public class ShaderManagement {
RenderSystem.linkProgram(programId);
// 检查链接状态
if (RenderSystem.getProgrami(programId, RenderSystem.GL_LINK_STATUS) != RenderSystem.GL_TRUE) {
if (RenderSystem.getProgram(programId, RenderSystem.GL_LINK_STATUS) != RenderSystem.GL_TRUE) {
String log = RenderSystem.getProgramInfoLog(programId);
RenderSystem.deleteProgram(programId);
throw new RuntimeException("着色器程序链接失败 [" + programName + "]:\n" + log);
@@ -170,7 +170,7 @@ public class ShaderManagement {
* 自定义程序验证方法
*/
private static void validateProgram(int programId, String programName) {
int validateStatus = RenderSystem.getProgrami(programId, RenderSystem.GL_VALIDATE_STATUS);
int validateStatus = RenderSystem.getProgram(programId, RenderSystem.GL_VALIDATE_STATUS);
if (validateStatus != RenderSystem.GL_TRUE) {
String log = RenderSystem.getProgramInfoLog(programId);
logger.warn("着色器程序验证警告 [{}]: {}", programName, log);

View File

@@ -1,12 +1,10 @@
package com.chuangzhou.vivid2D.test;
import com.chuangzhou.vivid2D.render.awt.ModelClickListener;
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 com.chuangzhou.vivid2D.render.model.util.Mesh2D;
import javax.swing.*;
import java.awt.*;
@@ -108,19 +106,16 @@ public class ModelLayerPanelTest {
frame.add(bottom, BorderLayout.SOUTH);
// 添加模型点击监听器,自动更新变换面板的选中部件
renderPanel.addModelClickListener(new ModelClickListener() {
@Override
public void onModelClicked(Mesh2D mesh, float modelX, float modelY, int screenX, int screenY) {
if (mesh == null) return;
System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY);
renderPanel.addModelClickListener((mesh, modelX, modelY, screenX, screenY) -> {
if (mesh == null) return;
System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY);
// 自动更新变换面板的选中部件
List<ModelPart> selectedPart = renderPanel.getSelectedParts();
transformPanel.setSelectedParts(selectedPart);
// 自动更新变换面板的选中部件
List<ModelPart> selectedPart = renderPanel.getSelectedParts();
transformPanel.setSelectedParts(selectedPart);
// 切换到变换控制选项卡
rightTabbedPane.setSelectedIndex(1);
}
// 切换到变换控制选项卡
rightTabbedPane.setSelectedIndex(1);
});
// 监听窗口关闭,确保释放 GL 资源