GitHub - steelswing/lib-gizmo-java: Java Native Wrapper (JNI) for LibGizmo
package net.steelswing.libgizmo; import java.nio.FloatBuffer; import java.nio.IntBuffer; import net.steelswing.libgizmo.glu.GLU; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL21; import org.lwjgl.system.MemoryStack; /** * File: Test.java * Created on 15 авг. 2023 г., 07:40:31 * * @author LWJGL2 */ public class Test { private long window; private int width, height; private LibGizmo gizmo; private int mouseX, mouseY; private static FloatBuffer objectMatrix = BufferUtils.createFloatBuffer(16); static { objectMatrix.put(new float[]{-0.3210f, 0.0000f, 0.9471f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, -0.9471f, 0.0000f, -0.3210f, 0.0000f, -137.1790f, 16.4949f, 375.4003f, 1.0000f}); objectMatrix.flip(); } public void run() { init(); loop(); // Free the window callbacks and destroy the window GLFW.glfwDestroyWindow(window); // Terminate GLFW and free the error callback GLFW.glfwTerminate(); GLFW.glfwSetErrorCallback(null).free(); } private void init() { // Setup an error callback. The default implementation // will print the error message in System.err. GLFWErrorCallback.createPrint(System.err).set(); // Initialize GLFW. Most GLFW functions will not work before doing this. if (!GLFW.glfwInit()) { throw new IllegalStateException("Unable to initialize GLFW"); } // Configure GLFW GLFW.glfwDefaultWindowHints(); // optional, the current window hints are already the default GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); // the window will stay hidden after creation GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE); // the window will be resizable // Create the window window = GLFW.glfwCreateWindow(1280, 720, "Hello World!", 0, 0); if (window == 0) { throw new RuntimeException("Failed to create the GLFW window"); } // Setup a key callback. It will be called every time a key is pressed, repeated or released. GLFW.glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> { if (key == GLFW.GLFW_KEY_ESCAPE && action == GLFW.GLFW_RELEASE) { GLFW.glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop } }); // Get the thread stack and push a new frame try (MemoryStack stack = MemoryStack.stackPush()) { IntBuffer pWidth = stack.mallocInt(1); // int* IntBuffer pHeight = stack.mallocInt(1); // int* // Get the window size passed to glfwCreateWindow GLFW.glfwGetWindowSize(window, pWidth, pHeight); // Get the resolution of the primary monitor GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()); // Center the window GLFW.glfwSetWindowPos( window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2 ); } // the stack frame is popped automatically // Make the OpenGL context current GLFW.glfwMakeContextCurrent(window); // Enable v-sync GLFW.glfwSwapInterval(1); // Make the window visible GLFW.glfwShowWindow(window); } private void loop() { // This line is critical for LWJGL's interoperation with GLFW's // OpenGL context, or any context that is managed externally. // LWJGL detects the context that is current in the current thread, // creates the GLCapabilities instance and makes the OpenGL // bindings available for use. GL.createCapabilities(); // Set the clear color GL21.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); try (MemoryStack stack = MemoryStack.stackPush()) { IntBuffer pWidth = stack.mallocInt(1); // int* IntBuffer pHeight = stack.mallocInt(1); // int* GLFW.glfwGetWindowSize(window, pWidth, pHeight); width = pWidth.get(0); height = pHeight.get(0); } // Run the rendering loop until the user has attempted to close // the window or has pressed the ESCAPE key. glInit(); while (!GLFW.glfwWindowShouldClose(window)) { try (MemoryStack stack = MemoryStack.stackPush()) { IntBuffer pWidth = stack.mallocInt(1); // int* IntBuffer pHeight = stack.mallocInt(1); // int* GLFW.glfwGetWindowSize(window, pWidth, pHeight); width = pWidth.get(0); height = pHeight.get(0); } glRender(); GLFW.glfwSwapBuffers(window); // swap the color buffers // Poll for window events. The key callback above will only be // invoked during this call. GLFW.glfwPollEvents(); } } private void glInit() { GL21.glEnable(GL21.GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) GL21.glShadeModel(GL21.GL_SMOOTH); // Enable Smooth Shading GL21.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background GL21.glClearDepth(1.0f); // Depth Buffer Setup GL21.glEnable(GL21.GL_DEPTH_TEST); // Enables Depth Testing GL21.glDepthFunc(GL21.GL_LEQUAL); // The Type Of Depth Testing To Do GL21.glHint(GL21.GL_PERSPECTIVE_CORRECTION_HINT, GL21.GL_NICEST); // Really Nice Perspective Calculations GL21.glDepthMask(true); gizmo = LibGizmo.create(GizmoType.GIZMO_SCALE); gizmo.setEditMatrix(objectMatrix); gizmo.setScreenDimension(width, height); gizmo.setDisplayScale(2); GLFW.glfwSetCursorPosCallback(window, (window, xpos, ypos) -> { mouseX = (int) xpos; mouseY = (int) ypos; gizmo.onMouseMove(mouseX, mouseY); }); GLFW.glfwSetMouseButtonCallback(window, (window, button, action, mods) -> { if (action == GLFW.GLFW_PRESS) { gizmo.onMouseDown(mouseX, mouseY); } if (action == GLFW.GLFW_RELEASE) { gizmo.onMouseUp(mouseX, mouseY); } }); } public void resize() { // Prevent A Divide By Zero By GL21.glViewport(0, 0, width, height); // Reset The Current Viewport GL21.glMatrixMode(GL21.GL_PROJECTION); // Select The Projection Matrix GL21.glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window GLU.gluPerspective(45.0f, width / (float) height, 0.1f, 100.0f); GL21.glMatrixMode(GL21.GL_MODELVIEW); // Select The Modelview Matrix GL21.glLoadIdentity(); // Reset The Modelview Matrix GLU.gluLookAt(5, 5, 5, 0, 0, 0, 0, 1, 0); gizmo.setScreenDimension(width, height); } private void glRender() { resize(); GL21.glClearColor(0, 0, 0, 1); GL21.glClear(GL21.GL_COLOR_BUFFER_BIT | GL21.GL_DEPTH_BUFFER_BIT); // clear the framebuffer FloatBuffer viewMat = BufferUtils.createFloatBuffer(16); viewMat.put(new float[]{-0.1747f, -0.2647f, 0.8394f, 0.0000f, 0.0000f, 0.9537f, 0.3007f, 0.0000f, -0.8802f, 0.1427f, -0.4527f, 0.0000f, 180.6443f, -110.9036f, -91.6591f, 1.0000f}); viewMat.flip(); FloatBuffer projMat = BufferUtils.createFloatBuffer(16); projMat.put(new float[]{0.5625f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, -1.0002f, -1.0000f, 0.0000f, 0.0000f, -0.2000f, 0.0000f}); projMat.flip(); GL21.glMatrixMode(GL21.GL_PROJECTION); GL21.glLoadIdentity(); GL21.glLoadMatrixf(projMat); GL21.glMatrixMode(GL21.GL_MODELVIEW); GL21.glLoadIdentity(); GL21.glLoadMatrixf(viewMat); GL21.glPushMatrix(); GL21.glMultMatrixf(objectMatrix); GL21.glScalef(50, 50, 50); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glCullFace(GL21.GL_CW); GL21.glEnable(GL21.GL_CULL_FACE); GL21.glBegin(GL21.GL_QUADS); // Front Face GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(-1.0f, -1.0f, 1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(1.0f, -1.0f, 1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(1.0f, 1.0f, 1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(-1.0f, 1.0f, 1.0f); // Back Face GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(-1.0f, -1.0f, -1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(-1.0f, 1.0f, -1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(1.0f, 1.0f, -1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(1.0f, -1.0f, -1.0f); // Top Face GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(-1.0f, 1.0f, -1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(-1.0f, 1.0f, 1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(1.0f, 1.0f, 1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(1.0f, 1.0f, -1.0f); // Bottom Face GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(-1.0f, -1.0f, -1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(1.0f, -1.0f, -1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(1.0f, -1.0f, 1.0f); GL21.glColor4f(0.6f, 0.6f, 0.6f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(-1.0f, -1.0f, 1.0f); // Right face GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(1.0f, -1.0f, -1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(1.0f, 1.0f, -1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(1.0f, 1.0f, 1.0f); GL21.glColor4f(0.5f, 0.5f, 0.5f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(1.0f, -1.0f, 1.0f); // Left Face GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(0.0f, 0.0f); GL21.glVertex3f(-1.0f, -1.0f, -1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(1.0f, 0.0f); GL21.glVertex3f(-1.0f, -1.0f, 1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(1.0f, 1.0f); GL21.glVertex3f(-1.0f, 1.0f, 1.0f); GL21.glColor4f(0.4f, 0.4f, 0.4f, 1.f); GL21.glTexCoord2f(0.0f, 1.0f); GL21.glVertex3f(-1.0f, 1.0f, -1.0f); GL21.glEnd(); GL21.glPopMatrix(); gizmo.setCameraMatrix(viewMat, projMat); gizmo.draw(); } public static void main(String[] args) throws Throwable { new Test().run(); } }