An attempt at Vulkan
jMonkeyEngine Hub
March 14, 2026
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