Jme3-examples: TestTessellationShader failed

Hi everyone,

I’m wondering if the TestTessellationShader class works correctly for you.

When I first ran it, I encountered the following OpenGL error:

INFO: OpenGL Renderer Information
 * Vendor: Intel
 * Renderer: Intel(R) Iris(R) Xe Graphics
 * OpenGL Version: 4.0.0 - Build 32.0.101.5763
 * GLSL Version: 4.00 - Build 32.0.101.5763
 * Profile: Core
[JME3] OpenGL debug message
        ID: 1280
        Source: API
        Type: ERROR
        Severity: HIGH
        Message: Error has been generated. GL error GL_INVALID_ENUM in GetBooleanv: (ID: 659224037) Generic error
java.lang.Exception: Stack trace
	at java.base/java.lang.Thread.dumpStack(Thread.java:2209)
	at com.jme3.system.lwjgl.LwjglGLDebugOutputHandler.handleMessage(LwjglGLDebugOutputHandler.java:76)
	at org.lwjgl.opengl.GL11.nglGetBooleanv(Native Method)
	at org.lwjgl.opengl.GL11.glGetBoolean(GL11.java:1321)
	at com.jme3.renderer.lwjgl.LwjglGL.glGetBoolean(LwjglGL.java:287)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at com.jme3.renderer.opengl.GLDebug.invoke(GLDebug.java:107)

After some online searching and Java debugging, I temporarily resolved this by setting gammaCorrection = false in the initial settings. This could be a potential bug in the GLRenderer class, I will come back to it after I fix the shader problems.

    public static void main(String[] args) {
        TestTessellationShader app = new TestTessellationShader();
        AppSettings settings = new AppSettings(true);
        settings.setRenderer(AppSettings.LWJGL_OPENGL40);
        settings.setGammaCorrection(false); // <--
        app.setSettings(settings);
        app.start();
    }

Now the error message is as follows:

[JME3] OpenGL debug message
       ID: 1
       Source: SHADER_COMPILER
       Type: ERROR
       Severity: HIGH
       Message: SHADER_ID_LINK error has been generated. GLSL link failed for program 1, "": Varying "gl_PerVertex;_IN" has different block does not match across different shaders.

java.lang.Exception: Stack trace
	at java.base/java.lang.Thread.dumpStack(Thread.java:2209)
	at com.jme3.system.lwjgl.LwjglGLDebugOutputHandler.handleMessage(LwjglGLDebugOutputHandler.java:76)
	at org.lwjgl.opengl.GL20.nglLinkProgram(Native Method)
	at org.lwjgl.opengl.GL20.glLinkProgram(GL20.java:290)
	at com.jme3.renderer.lwjgl.LwjglGL.glLinkProgram(LwjglGL.java:347)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at com.jme3.renderer.opengl.GLDebug.invoke(GLDebug.java:107)
	at jdk.proxy1/jdk.proxy1.$Proxy0.glLinkProgram(Unknown Source)
	at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1705)
	at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1751)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:97)
	at com.jme3.material.Technique.render(Technique.java:168)
	at com.jme3.material.Material.render(Material.java:1114)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:842)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:772)
	at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
	at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
	at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:1117)
	at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:1012)
	at com.jme3.renderer.pipeline.ForwardPipeline.pipelineRender(ForwardPipeline.java:117)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1313)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1355)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:283)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:163)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:246)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:245)
	at java.base/java.lang.Thread.run(Thread.java:1583)
mag 24, 2025 1:25:18 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[#37,jME3 Main,5,main]
com.jme3.renderer.RendererException: Shader failed to link, shader:Shader[numSources=4, numUniforms=2, numBufferBlocks=0, shaderSources=[ShaderSource[name=Materials/Tess/SimpleTess.frag, defines, type=Fragment, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.vert, defines, type=Vertex, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.tsctrl, defines, type=TessellationControl, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.tseval, defines, type=TessellationEvaluation, language=GLSL400]]]
Varying "gl_PerVertex;_IN" has different block does not match across different shaders.

	at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1738)
	at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1751)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:97)
	at com.jme3.material.Technique.render(Technique.java:168)
	at com.jme3.material.Material.render(Material.java:1114)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:842)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:772)
	at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
	at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
	at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:1117)
	at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:1012)
	at com.jme3.renderer.pipeline.ForwardPipeline.pipelineRender(ForwardPipeline.java:117)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1313)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1355)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:283)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:163)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:246)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:245)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Here’s the shader files:
Materials Tess

Has anyone run into this second issue, or do you have any ideas what might be going on? Any help would be greatly appreciated!

Cheers

@RiccardoBlb @codex @zzuegg @yaRnMcDonuts

2 Likes

I was able to run the app without any error messages on my Linux laptop.

It’s a tricky test to run, because it requires OpenGL 4, so you usually can’t run it from TestChooser. And you need a graphics driver that supports OpenGL 4 . And after you run it your app settings are persistently altered.

Here’s my console output, for comparison:

May 24, 2025 8:36:25 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.8.0-SNAPSHOT
 * Branch: master
 * Git Hash: dcb2262
 * Build Date: 2025-05-24
May 24, 2025 8:36:26 AM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.5 context running on thread jME3 Main
 * Graphics Adapter: null
 * Driver Version: null
 * Scaling Factor: 1
May 24, 2025 8:36:26 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: NVIDIA GeForce RTX 2070/PCIe/SSE2
 * OpenGL Version: 4.0.0 NVIDIA 550.144.03
 * GLSL Version: 4.00 NVIDIA via Cg compiler
 * Profile: Core
May 24, 2025 8:36:26 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
 * Device: OpenAL Soft
 * Vendor: OpenAL Community
 * Renderer: OpenAL Soft
 * Version: 1.1 ALSOFT 1.15.1
 * Supported channels: 64
 * ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
 * AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
May 24, 2025 8:36:26 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
May 24, 2025 8:36:26 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
May 24, 2025 8:36:26 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
1 Like

I just tried it, and I got this error:

SEVERE: Uncaught exception thrown in Thread[#32,jME3 Main,5,main]
com.jme3.renderer.RendererException: Shader failed to link, shader:Shader[numSources=4, numUniforms=2, numBufferBlocks=0, shaderSources=[ShaderSource[name=Materials/Tess/SimpleTess.frag, defines, type=Fragment, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.vert, defines, type=Vertex, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.tsctrl, defines, type=TessellationControl, language=GLSL400], ShaderSource[name=Materials/Tess/SimpleTess.tseval, defines, type=TessellationEvaluation, language=GLSL400]]]
error: definitions of interface block `gl_PerVertex' do not match

	at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1737)
	at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1750)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:97)
	at com.jme3.material.Technique.render(Technique.java:168)
	at com.jme3.material.Material.render(Material.java:1090)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:695)
	at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
	at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
	at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:973)
	at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:868)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1228)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1298)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:283)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:163)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:225)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:245)
	at java.base/java.lang.Thread.run(Thread.java:1583)

I found two solutions:

  1. Completely remove it in the file “SimpleTess.tsctrl”
  2. Modify the file “SimpleTess.tseval”
#import "Common/ShaderLib/GLSLCompat.glsllib"

layout (quads,equal_spacing,cw) in;

//Code added
in gl_PerVertex {
    vec4 gl_Position;
} gl_in[];

out gl_PerVertex {
    vec4 gl_Position;
};
//End code added

uniform mat4 g_WorldViewProjectionMatrix;

void main(){
        vec3 p0 = mix(gl_in[0].gl_Position.xyz, gl_in[3].gl_Position.xyz, gl_TessCoord.x);
        // interpolate in horizontal direction between vert. 1 and 2
        vec3 p1 = mix(gl_in[1].gl_Position.xyz, gl_in[2].gl_Position.xyz, gl_TessCoord.x);
        // interpolate in vert direction
        vec3 tePosition = mix(p0, p1, gl_TessCoord.y);
        gl_Position = g_WorldViewProjectionMatrix * vec4(tePosition, 1.0);
}
1 Like

Thank you for your response, @sgold . From your explanation, I gather that my graphics driver does not meet the requirements. I will try using another computer with a dedicated NVIDIA graphics card.

You are correct! None of the example classes work anymore. How do I restore the AppSettings to their default settings?

The first error raised a hidden problem, however. It appears that the getBoolean(GLExt.GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) method is not supported on Windows either. This means the workaround is incorrect and there is a bug.

INFO: OpenGL Renderer Information
 * Vendor: Intel
 * Renderer: Intel(R) Iris(R) Xe Graphics
 * OpenGL Version: 4.0.0 - Build 32.0.101.5763
 * GLSL Version: 4.00 - Build 32.0.101.5763
 * Profile: Core
[JME3] OpenGL debug message
        ID: 1280
        Source: API
        Type: ERROR
        Severity: HIGH
        Message: Error has been generated. GL error GL_INVALID_ENUM in GetBooleanv: (ID: 659224037) Generic error
java.lang.Exception: Stack trace
	at java.base/java.lang.Thread.dumpStack(Thread.java:2209)
	at com.jme3.system.lwjgl.LwjglGLDebugOutputHandler.handleMessage(LwjglGLDebugOutputHandler.java:76)
	at org.lwjgl.opengl.GL11.nglGetBooleanv(Native Method)
	at org.lwjgl.opengl.GL11.glGetBoolean(GL11.java:1321)
	at com.jme3.renderer.lwjgl.LwjglGL.glGetBoolean(LwjglGL.java:287)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at com.jme3.renderer.opengl.GLDebug.invoke(GLDebug.java:107)

Thank you for your response, @German_Caal . I tried Solution 1, and now the test works. Here is a screenshot:

To make it work, I set gammaCorrection = false and removed the part of the code containing the error in the SimpleTess.tsctrl file.

AppSettings settings = new AppSettings(true);
settings.setRenderer(AppSettings.LWJGL_OPENGL40);
settings.setGammaCorrection(false);
#import "Common/ShaderLib/GLSLCompat.glsllib"

layout(vertices=4) out;
/*
out gl_PerVertex{
  vec4 gl_Position;
}gl_out[];
*/

uniform int m_TessellationFactor;
void main(){
    if (gl_InvocationID == 0){
        float f_TessellationFactor=float(m_TessellationFactor);

        gl_TessLevelOuter[0]=f_TessellationFactor;
        gl_TessLevelOuter[1]=f_TessellationFactor;
        gl_TessLevelOuter[2]=f_TessellationFactor;
        gl_TessLevelOuter[3]=f_TessellationFactor;

        gl_TessLevelInner[0]=f_TessellationFactor;
        gl_TessLevelInner[1]=f_TessellationFactor;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

However, I’m seeing a warning message in the console. It’s flagged as medium severity, and I’m not sure if it indicates a serious underlying issue.

[JME3] OpenGL debug message
       ID: 5
       Source: API
       Type: PERFORMANCE
       Severity: MEDIUM
       Message: API_ID_RECOMPILE_HULL_SHADER performance warning has been generated. Hull shader recompiled due to state change.
java.lang.Exception: Stack trace
	at java.base/java.lang.Thread.dumpStack(Thread.java:2209)
	at com.jme3.system.lwjgl.LwjglGLDebugOutputHandler.handleMessage(LwjglGLDebugOutputHandler.java:76)
	at org.lwjgl.opengl.GL12.nglDrawRangeElementsBO(Native Method)
	at org.lwjgl.opengl.GL12.glDrawRangeElements(GL12.java:92)
	at com.jme3.renderer.lwjgl.LwjglGL.glDrawRangeElements(LwjglGL.java:249)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at com.jme3.renderer.opengl.GLDebug.invoke(GLDebug.java:107)
	at jdk.proxy1/jdk.proxy1.$Proxy0.glDrawRangeElements(Unknown Source)
	at com.jme3.renderer.opengl.GLRenderer.drawTriangleList(GLRenderer.java:3321)
	at com.jme3.renderer.opengl.GLRenderer.renderMeshDefault(GLRenderer.java:3447)
	at com.jme3.renderer.opengl.GLRenderer.renderMesh(GLRenderer.java:3475)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.renderMeshFromGeometry(DefaultTechniqueDefLogic.java:73)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:98)
	at com.jme3.material.Technique.render(Technique.java:168)
	at com.jme3.material.Material.render(Material.java:1122)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:842)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:772)
	at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
	at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
	at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:1117)
	at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:1012)
	at com.jme3.renderer.pipeline.ForwardPipeline.pipelineRender(ForwardPipeline.java:117)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1313)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1355)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:283)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:163)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:246)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:245)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Edit:
Even with solution 2 I get the same result.

Which of the two solutions would be the right one?

Here’s a little app that may be useful:

public class SetDefaultRenderer {

    public static void main(String[] args) {
        AppSettings settings = new AppSettings(true);
        String defaultRenderer = settings.getRenderer();
        String preferencesKey = JmeVersion.FULL_NAME;
        try {
            settings.load(preferencesKey);
            String oldRenderer = settings.getRenderer();
            System.out.printf("The renderer for \"%s\" was set to \"%s\"%n",
                    preferencesKey, oldRenderer);

            if (oldRenderer.equals(defaultRenderer)) {
                System.out.println(" ... did not change the renderer.");
            } else {
                settings.setRenderer(defaultRenderer);
                settings.save(preferencesKey);
                System.out.printf(
                        " ... set the renderer to \"%s\".", defaultRenderer);
            }

        } catch (BackingStoreException e) {
            throw new RuntimeException(e);
        }
    }
}    

Note that each release of JME defaults to a different preferences key, so that app has to be built for the specific release you’re interested in.

I temporarily resolved this by setting gammaCorrection = false in the initial settings.

On my Linux laptop, the test runs fine with or without gamma correction.

3 Likes

While i have no access to a computer during my holidays i can help as long no coding is required. Just ping in case the issue is not resolved.

Ultimately back in the days and the main reason there is no full featured tessellation shader in jme is because it would required to specify a technique depending on the mesh mode. And my motivation to modify the engine back then after the tessallation support was at an all time low.

2 Likes

I think that depends on the situation. In this case, gl_PerVertex is not used, which is why it works when it’s removed. If it were used, the reference would need to be added in the “tseval” file, since the error occurs because it can’t link the interface between the shaders.

The warning that shows up for you doesn’t appear for me.

1 Like

Hi everyone,
First off, thank you all for your support!

I’m encountering a couple of bugs with the TestTessellationShader test class when running it on PCs without a dedicated NVIDIA graphics card (i.e., using integrated graphics like Intel). These issues, when combined, are confusing and quite a headache to debug. I’ll try to summarize them to figure out a solution together.

Issues Encountered:

  1. Automatic and “Hidden” Settings Persistence: As @sgold rightly pointed out, settings are automatically persisted without any explicit warning to the user. This behavior is misleading because changing parameters in the Settings object within the main function doesn’t give the impression that these parameters are actually being saved.
  2. GL_INVALID_ENUM (1280) Error in GLRenderer: The setMainFrameBufferSrgb() method in the GLRenderer class calls getBoolean(GLExt.GL_FRAMEBUFFER_SRGB_CAPABLE_EXT), which results in error 1280 (invalid enum). This issue occurs on both Windows and macOS (contrary to what one might initially suspect) when using an Intel integrated graphics card. I have reason to believe that the workaround in the GLRenderer code only masked the problem without fully resolving it.
  • Temporary Workaround: Since gammaCorretion = true by default, to isolate this bug without modifying the source code, I had to set gammaCorrection = false (this means enableSrgb = false).

Progress and Proposals:

Thanks to @German_Caal suggestions for the shader, the test class now seems to be working correctly, allowing the number of vertices of the Quad in the example to be increased/decreased.

In light of all this, I would like to propose the following PRs:

  1. Shader Correction: Implement the shader modifications suggested by @German_Caal
  2. Remove Problematic Call in GLRenderer: Completely remove the call to getBoolean(GLExt.GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) to prevent the error 1280 (invalid enum).

Regarding the settings persistence:

  • @sgold’s workaround is helpful for resetting them.
  • However, it would be beneficial to add some logs or a warning to inform the user about the automatic persistence. Where are the settings saved?

Thanks again for your help!

1 Like

The code is terribly obscure. After you press the “Continue” button in the settings dialog:

1 Like