package com.chuangzhou.vivid2D.test; import com.chuangzhou.vivid2D.render.ModelRender; import com.chuangzhou.vivid2D.render.model.Model2D; import com.chuangzhou.vivid2D.render.model.ModelPart; import com.chuangzhou.vivid2D.render.model.util.Mesh2D; import com.chuangzhou.vivid2D.render.model.util.Texture; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import org.lwjgl.system.MemoryUtil; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; /** * Texture Render Test Class - Debug Version * @author tzdwindows 7 */ public class ModelRenderTextureTest { private long window; private Model2D model; // Window dimensions private static final int WINDOW_WIDTH = 800; private static final int WINDOW_HEIGHT = 600; // Debug flags private int frameCount = 0; private double lastFpsTime = 0; private boolean enableWireframe = false; public static void main(String[] args) { new ModelRenderTextureTest().run(); } public void run() { try { init(); loop(); } catch (Exception e) { e.printStackTrace(); } finally { cleanup(); } } private void init() { // Initialize GLFW if (!glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW"); } // Configure GLFW glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Create window window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "ModelRender Texture Test - DEBUG", MemoryUtil.NULL, MemoryUtil.NULL); if (window == MemoryUtil.NULL) { throw new RuntimeException("Failed to create the GLFW window"); } // Center window GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); glfwSetWindowPos( window, (vidMode.width() - WINDOW_WIDTH) / 2, (vidMode.height() - WINDOW_HEIGHT) / 2 ); // Set callbacks glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> { if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) { glfwSetWindowShouldClose(window, true); } if (key == GLFW_KEY_SPACE && action == GLFW_RELEASE) { enableWireframe = !enableWireframe; System.out.println("Wireframe mode: " + (enableWireframe ? "ON" : "OFF")); } if (key == GLFW_KEY_R && action == GLFW_RELEASE) { recreateModel(); } }); // Create OpenGL context glfwMakeContextCurrent(window); GL.createCapabilities(); // Show window glfwShowWindow(window); // Initialize ModelRender ModelRender.initialize(); // Create test model createTestModel(); System.out.println("=== DEBUG INFO ==="); System.out.println("Press SPACE to toggle wireframe mode"); System.out.println("Press R to recreate model"); System.out.println("Press ESC to exit"); System.out.println("=================="); } private void createTestModel() { if (model != null) { // Clean up previous model if exists System.out.println("Cleaning up previous model..."); } model = new Model2D("TextureTestModel"); try { // Load Trump image texture String texturePath = "G:\\鬼畜素材\\川普\\图片\\7(DJ0MH9}`)GJYHHADQDHYN.png"; System.out.println("Loading texture: " + texturePath); Texture texture = Texture.createFromFile("trump_texture", texturePath); model.addTexture(texture); System.out.println("Texture loaded: " + texture.getWidth() + "x" + texture.getHeight()); System.out.println("Texture ID: " + texture.getTextureId()); System.out.println("Texture format: " + texture.getFormat()); // 使用与工作示例相同的方式创建网格 // 根据纹理尺寸创建合适大小的四边形 float width = texture.getWidth() / 2.0f; // 缩小以适应屏幕 float height = texture.getHeight() / 2.0f; // 使用 Mesh2D.createQuad 方法创建网格(如果可用) Mesh2D mesh; try { // 尝试使用 createQuad 方法 mesh = Mesh2D.createQuad("trump_mesh", width, height); System.out.println("Using Mesh2D.createQuad method"); } catch (Exception e) { // 回退到手动创建顶点 System.out.println("Using manual vertex creation"); float[] vertices = { -width/2, -height/2, // bottom left width/2, -height/2, // bottom right width/2, height/2, // top right -width/2, height/2 // top left }; float[] uvs = { 0.0f, 1.0f, // bottom left 1.0f, 1.0f, // bottom right 1.0f, 0.0f, // top right 0.0f, 0.0f // top left }; int[] indices = { 0, 1, 2, // first triangle 2, 3, 0 // second triangle }; mesh = model.createMesh("trump_mesh", vertices, uvs, indices); } mesh.setTexture(texture); // Create part and add mesh ModelPart part = model.createPart("trump_part"); part.addMesh(mesh); part.setVisible(true); // 设置部件位置到屏幕中心(使用像素坐标) part.setPosition(0, 0); // 800x600 窗口的中心 System.out.println("Model created:"); System.out.println(" - Part count: " + model.getParts().size()); System.out.println(" - Mesh count: " + model.getMeshes().size()); System.out.println(" - Mesh dimensions: " + width + "x" + height); System.out.println(" - Part position: " + part.getPosition()); System.out.println(" - Mesh vertex count: " + mesh.getVertexCount()); // 测试模型保存 model.saveToFile("C:\\Users\\Administrator\\Desktop\\trump_texture.model"); } catch (Exception e) { System.err.println("Failed to create test model: " + e.getMessage()); e.printStackTrace(); createFallbackModel(); } } private void createFallbackModel() { System.out.println("Creating fallback checkerboard model..."); // 使用与工作示例相同的模式 float width = 200; float height = 200; Mesh2D mesh; try { mesh = Mesh2D.createQuad("fallback_mesh", width, height); } catch (Exception e) { // 手动创建 float[] vertices = { -width/2, -height/2, width/2, -height/2, width/2, height/2, -width/2, height/2 }; float[] uvs = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; int[] indices = { 0, 1, 2, 2, 3, 0 }; mesh = model.createMesh("fallback_mesh", vertices, uvs, indices); } // Create checkerboard texture Texture fallbackTexture = Texture.createCheckerboard( "fallback_texture", 512, 512, 32, 0xFFFF0000, // red 0xFF0000FF // blue ); model.addTexture(fallbackTexture); mesh.setTexture(fallbackTexture); ModelPart part = model.createPart("fallback_part"); part.addMesh(mesh); part.setVisible(true); part.setPosition(400, 300); System.out.println("Fallback model created with size: " + width + "x" + height); } private void recreateModel() { System.out.println("Recreating model..."); createTestModel(); } private void loop() { // Set clear color (light gray for better visibility) glClearColor(0.3f, 0.3f, 0.3f, 1.0f); double lastTime = glfwGetTime(); while (!glfwWindowShouldClose(window)) { double currentTime = glfwGetTime(); float deltaTime = (float) (currentTime - lastTime); lastTime = currentTime; // Calculate FPS frameCount++; if (currentTime - lastFpsTime >= 1.0) { System.out.printf("FPS: %d, Delta: %.3fms\n", frameCount, deltaTime * 1000); frameCount = 0; lastFpsTime = currentTime; } // Render render(deltaTime); // Swap buffers and poll events glfwSwapBuffers(window); glfwPollEvents(); } } private void render(float deltaTime) { // Clear screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set wireframe mode if enabled if (enableWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Print debug info occasionally if (frameCount % 120 == 0) { System.out.println("=== RENDER DEBUG ==="); System.out.println("Model null: " + (model == null)); if (model != null) { System.out.println("Parts: " + model.getParts().size()); System.out.println("Meshes: " + model.getMeshes().size()); if (!model.getParts().isEmpty()) { ModelPart part = model.getParts().get(0); System.out.println("First part visible: " + part.isVisible()); System.out.println("First part position: " + part.getPosition()); System.out.println("First part meshes: " + part.getMeshes().size()); } } System.out.println("==================="); } // Render using ModelRender try { ModelRender.render(deltaTime, model); } catch (Exception e) { System.err.println("Rendering error: " + e.getMessage()); e.printStackTrace(); } // Check OpenGL errors int error = glGetError(); if (error != GL_NO_ERROR) { System.err.println("OpenGL error: " + getGLErrorString(error)); } } private String getGLErrorString(int error) { switch (error) { case GL_INVALID_ENUM: return "GL_INVALID_ENUM"; case GL_INVALID_VALUE: return "GL_INVALID_VALUE"; case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION"; case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY"; default: return "Unknown Error (0x" + Integer.toHexString(error) + ")"; } } private void cleanup() { System.out.println("Cleaning up resources..."); // Cleanup ModelRender ModelRender.cleanup(); // Cleanup texture cache Texture.cleanupAll(); // Destroy window and terminate GLFW if (window != MemoryUtil.NULL) { glfwDestroyWindow(window); } glfwTerminate(); System.out.println("Cleanup completed"); } }