Files
window-axis-innovators-box/src/main/java/com/chuangzhou/vivid2D/test/ModelRenderTest2.java

232 lines
7.9 KiB
Java
Raw Normal View History

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 com.chuangzhou.vivid2D.render.systems.RenderSystem;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
/**
* 用于测试中心点旋转
*
* @author tzdwindows 7
*/
public class ModelRenderTest2 {
private static final int WINDOW_WIDTH = 800;
private static final int WINDOW_HEIGHT = 600;
private static final String WINDOW_TITLE = "Simple Pivot Test";
private long window;
private boolean running = true;
private Model2D testModel;
private float rotationAngle = 0f;
private int testCase = 0;
private Mesh2D squareMesh;
public static void main(String[] args) {
new ModelRenderTest2().run();
}
public void run() {
try {
init();
loop();
} catch (Throwable t) {
t.printStackTrace();
} finally {
cleanup();
}
}
private void init() {
GLFWErrorCallback.createPrint(System.err).set();
if (!GLFW.glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
window = GLFW.glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, MemoryUtil.NULL, MemoryUtil.NULL);
if (window == MemoryUtil.NULL) throw new RuntimeException("Failed to create GLFW window");
GLFWVidMode vidMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
GLFW.glfwSetWindowPos(window,
(vidMode.width() - WINDOW_WIDTH) / 2,
(vidMode.height() - WINDOW_HEIGHT) / 2);
GLFW.glfwSetKeyCallback(window, (wnd, key, scancode, action, mods) -> {
if (key == GLFW.GLFW_KEY_ESCAPE && action == GLFW.GLFW_RELEASE) running = false;
if (key == GLFW.GLFW_KEY_SPACE && action == GLFW.GLFW_RELEASE) {
testCase = (testCase + 1) % 3;
updatePivotPoint();
}
if (key == GLFW.GLFW_KEY_R && action == GLFW.GLFW_RELEASE) {
resetPosition();
}
});
GLFW.glfwSetWindowSizeCallback(window, (wnd, w, h) -> ModelRender.setViewport(w, h));
GLFW.glfwMakeContextCurrent(window);
GLFW.glfwSwapInterval(1);
GLFW.glfwShowWindow(window);
GL.createCapabilities();
createSimpleTestModel();
ModelRender.initialize();
System.out.println("Simple pivot test initialized");
System.out.println("Controls: ESC = exit | SPACE = change pivot | R = reset position");
}
/**
* Create a single square mesh with vertices centered at origin
*/
private void createSimpleTestModel() {
testModel = new Model2D("SimpleTest");
ModelPart square = testModel.createPart("square");
square.setPosition(0, 0); // center of window
square.setPivot(0, 0);
// Create 80x80 quad centered at origin
squareMesh = Mesh2D.createQuad("square_mesh", 80, 80);
// Shift vertices so center is at (0,0)
//for (int i = 0; i < squareMesh.getVertexCount(); i++) {
// Vector2f v = squareMesh.getVertex(i);
// v.sub(0, 0);
// squareMesh.setVertex(i, v.x, v.y);
//}
squareMesh.setTexture(createDiagnosticTexture());
square.addMesh(squareMesh); // do NOT bake to world coordinates
System.out.println("Simple test model created with one part only");
}
/**
* Create a diagnostic texture to see pivot visually
*/
private Texture createDiagnosticTexture() {
int width = 80, height = 80;
ByteBuffer buf = MemoryUtil.memAlloc(width * height * 4);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// center cross
if (x == width / 2 || y == height / 2) {
buf.put((byte) 255).put((byte) 255).put((byte) 255).put((byte) 255);
} else if (x < width / 2 && y < height / 2) {
buf.put((byte) 255).put((byte) 0).put((byte) 0).put((byte) 255); // top-left red
} else if (x >= width / 2 && y < height / 2) {
buf.put((byte) 0).put((byte) 255).put((byte) 0).put((byte) 255); // top-right green
} else if (x < width / 2 && y >= height / 2) {
buf.put((byte) 0).put((byte) 0).put((byte) 255).put((byte) 255); // bottom-left blue
} else {
buf.put((byte) 255).put((byte) 255).put((byte) 0).put((byte) 255); // bottom-right yellow
}
}
}
buf.flip();
Texture texture = new Texture("diagnostic", width, height, Texture.TextureFormat.RGBA, buf);
MemoryUtil.memFree(buf);
return texture;
}
private void updatePivotPoint() {
ModelPart square = testModel.getPart("square");
if (square != null) {
switch (testCase) {
case 0:
square.setPivot(0, 0);
System.out.println("Pivot: center (0,0) - should rotate around center");
break;
case 1:
square.setPivot(-40, 40); // top-left corner
System.out.println("Pivot: top-left (-40,40) - should rotate around top-left");
break;
case 2:
square.setPivot(40, -40); // bottom-right corner
System.out.println("Pivot: bottom-right (40,-40) - should rotate around bottom-right");
break;
}
}
}
private void resetPosition() {
ModelPart square = testModel.getPart("square");
if (square != null) {
square.setPosition(400, 300);
square.setRotation(0);
rotationAngle = 0;
System.out.println("Position reset");
}
}
private void loop() {
long last = System.nanoTime();
double nsPerUpdate = 1_000_000_000.0 / 60.0;
double accumulator = 0.0;
while (running && !GLFW.glfwWindowShouldClose(window)) {
long now = System.nanoTime();
accumulator += (now - last) / nsPerUpdate;
last = now;
while (accumulator >= 1.0) {
update(1.0f / 60.0f);
accumulator -= 1.0;
}
render();
GLFW.glfwSwapBuffers(window);
GLFW.glfwPollEvents();
}
}
private void update(float dt) {
rotationAngle += dt * 1.5f;
ModelPart square = testModel.getPart("square");
if (square != null) {
square.setRotation(rotationAngle);
}
testModel.update(dt);
}
private void render() {
RenderSystem.setClearColor(0.2f, 0.2f, 0.3f, 1.0f);
ModelRender.render(1.0f / 60.0f, testModel);
}
private void cleanup() {
System.out.println("Cleaning up resources...");
ModelRender.cleanup();
Texture.cleanupAll();
if (window != MemoryUtil.NULL) GLFW.glfwDestroyWindow(window);
GLFW.glfwTerminate();
GLFW.glfwSetErrorCallback(null).free();
System.out.println("Test finished");
}
}