External Publication
Visit Post

An attempt at Vulkan

jMonkeyEngine Hub March 14, 2026
Source

https://youtu.be/eYkkGzoRzkU A piece of good news: I can now successfully use most of the frontend functionalities in jMonkeyEngine 3.

package com.jme3.lwjgl.test;

import com.jme3.app.FlyCamAppState;
import com.jme3.app.LegacyApplication;
import com.jme3.asset.plugins.ClasspathLocator;
import com.jme3.input.FlyByCamera;
import com.jme3.input.RawInputListener;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.material.Material;
import com.jme3.material.plugins.J3MLoader;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;

import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeSystem;
import com.jme3.system.VulkanSystemDelegate;

public class VulkanMaterialUnshadedApp extends LegacyApplication {

    private Node rootNode = new Node("Root");
    private ViewPort viewPort;
    private Camera cam;

    private FlyCamAppState flyCamState;
    private boolean flyConfigured = false;

    @Override
    public void initialize() {
        super.initialize();
        assetManager.registerLocator("/", ClasspathLocator.class);
        assetManager.registerLoader(J3MLoader.class, "j3md", "j3m");

        cam = getCamera();
        viewPort = renderManager.createMainView("Main", cam);
        viewPort.attachScene(rootNode);

        Quad q = new Quad(1f, 1f);
        Geometry g = new Geometry("quad", q);

        Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        m.setColor("Color", ColorRGBA.White);
        g.setMaterial(m);
        rootNode.attachChild(g);

        cam.setLocation(new Vector3f(0, 0, 10f));
        cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
        cam.setFrustumPerspective(45f, (float) cam.getWidth() / cam.getHeight(), 0.1f, 100f);

        flyCamState = new FlyCamAppState();
        flyCamState.initialize(stateManager, this);
        stateManager.attach(flyCamState);

        // 不要在这里立刻 getCamera() 配置
        // 验证输入对象是否为 GLFW 真实实现
        inputManager.addRawInputListener(new RawInputListener() {
            @Override
            public void beginInput() {
            }

            @Override
            public void endInput() {
            }

            @Override
            public void onKeyEvent(KeyInputEvent evt) {
                if (evt.isPressed()) {
                    System.out.println("KEY pressed: " + evt.getKeyCode());
                }
            }

            @Override
            public void onMouseMotionEvent(MouseMotionEvent evt) {
            }

            @Override
            public void onMouseButtonEvent(MouseButtonEvent evt) {
            }

            @Override
            public void onJoyAxisEvent(JoyAxisEvent evt) {
            }

            @Override
            public void onJoyButtonEvent(JoyButtonEvent evt) {
            }

            @Override
            public void onTouchEvent(TouchEvent evt) {
            }
        });
//        FlyByCamera flyCam = flyCamState.getCamera();
//        flyCam.setMoveSpeed(5f);
//        flyCam.setDragToRotate(false);
//        flyCam.registerWithInput(inputManager);

    }

    @Override
    public void update() {
        super.update();

        float tpf = timer.getTimePerFrame();



        // 3) scene 更新 + 渲染
        rootNode.updateLogicalState(tpf);
        rootNode.updateGeometricState();

        if (context != null && context.isRenderable()) {
            renderManager.render(tpf, true);
        }
    }

    public static void main(String[] args) {
        JmeSystem.setSystemDelegate(new VulkanSystemDelegate());

        AppSettings s = new AppSettings(true);
        s.setCustomRenderer(com.jme3.renderer.vulkan.LwjglVulkanContext.class);
        s.setWidth(1280);
        s.setHeight(720);

        VulkanMaterialUnshadedApp app = new VulkanMaterialUnshadedApp();
        app.setSettings(s);
        app.start();
    }
}

The current issue is how to handle the shaders. I might need to go to the library as I haven’t found any information about OpenGL compatibility with Vulkan on the internet. If anyone else has any findings, please let me know.

Discussion in the ATmosphere

Loading comments...