Malfunctioning screenshotAppState

Hi guys,

after attaching and using the ScreenshotAppState I’m very sad of the outcome ;(

That is how it is supposed to look:

And that is the truth:

I have the SimpleWaterProcessor attached to the viewport. Any ideas?

Hmm, even after removing the water plane and its processor I still have the issue. The terrain just gets rendered in a grayish color (not white as in the picture, it comes from the jpg conversion). Note that the models and the skybox (upper right corner) appear in a correct manner.

The terrain is just standard geometry with the shader from the jME core, pimped up to 12 splat textures.

Here’s some code:

[java]public ScreenshotAppState screenshotState = new ScreenshotAppState();


and then just triggering it with the corresponding action key…

I cannot reproduce this issue.

I edited TestPostWater so it uses SimpleWaterFilter, then added a ScreenshotAppState to the end of the code.

I am able to take screenshots and I can see the terrain there

1 Like

Peculiarly, if I use the standard Common-MatDefs-Terrain.j3md, the terrain is correctly drawn in the screen shot. If I use my own material, the above happens. Hmpf strange because I see the terrain and the screenshotAppState dumps the framebuffer… so basically what I see… or not?

I am using the TerrainLighting.j3md material

What filters/processors do you have on your viewport?

Also are you using your own appstates?

Hi Momoko_Fan,

I tried the TerrainLighting.j3md and it worked as expected with the screenshot. Happens only with my material…

Filters: none. Processors: only SimpleWaterProcessor, which I also deactivated afterwards without improvement, so currently also none.

I use my own AppState, yes. That’s the basic structure:

[java]public class Main extends SimpleApplication {

public BulletAppState bulletState = new BulletAppState();

public ScreenshotAppState screenshotState = new ScreenshotAppState();

public AppState worldMapState = new AbstractAppState()


… // all of the code here


public static void main(String[] args) {

Main app = new Main();



public void simpleInitApp() {







What is your material doing then?

Nothing fancy, really.

[java]MaterialDef Terrain {

MaterialParameters {

Texture2D Key0

Texture2D Key1

Texture2D Tex0

Texture2D Tex1

Texture2D Tex2

Texture2D Tex3

Texture2D Tex4

Texture2D Tex5

Texture2D Tex6

Texture2D Tex7

Texture2D Tex8

Texture2D Tex9

Texture2D Tex10

Texture2D Tex11

Texture2D Tex12

Texture2D Tex13

Boolean useGrid


Technique {

LightMode MultiPass

VertexShader GLSL100: materials/terrain/terrain.vert

FragmentShader GLSL100: materials/terrain/terrain.frag

WorldParameters {






Defines {

USE_GRID : useGrid



Technique FixedFunc {

LightMode FixedPipeline



In the .vert-file basic light calculation

[java]uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldViewMatrix;

uniform mat3 g_NormalMatrix;

uniform mat4 g_ViewMatrix;

uniform vec4 g_LightColor;

uniform vec4 g_LightPosition;

attribute vec3 inPosition;

attribute vec3 inNormal;

attribute vec2 inTexCoord;

attribute vec4 inTangent;

varying vec3 vNormal;

varying vec2 texCoord;

varying vec3 vPosition;

varying vec4 vLightDir;

varying vec4 DiffuseSum;

void main()


vec4 pos = vec4(inPosition, 1.0);

gl_Position = g_WorldViewProjectionMatrix * pos;

texCoord = inTexCoord;

vPosition = (g_WorldViewMatrix * pos).xyz;

vNormal = normalize(g_NormalMatrix * inNormal);

vec4 wvLightPos = (g_ViewMatrix * vec4(, g_LightColor.w));

wvLightPos.w = g_LightPosition.w;

float posLight = step(0.5, g_LightColor.w);

vec3 tempVec = * sign(posLight - 0.5) - (vPosition * posLight);

vLightDir = vec4(normalize(tempVec), 1.0);

DiffuseSum = g_LightColor;


And in the .frag-file splat together all 12 textures with 2 key-textures and do phong (without specular)

[java]uniform sampler2D m_Key0;

uniform sampler2D m_Key1;

uniform sampler2D m_Tex0;

uniform sampler2D m_Tex1;

uniform sampler2D m_Tex13;

varying vec4 DiffuseSum;

varying vec3 vNormal;

varying vec2 texCoord;

varying vec3 vPosition;

varying vec4 vLightDir;

vec4 computeDiffuse()


// dumb tile offset

vec2 diff = texCoord + (1.0/256.0,1.0/256.0);

vec4 key0=texture2D(m_Key0,diff);

vec4 key1=texture2D(m_Key1,diff);

vec4 t0=texture2D(m_Tex0,texCoord32.0);

vec4 t1=texture2D(m_Tex1,texCoord

vec4 t2=texture2D(m_Tex2,texCoord32.0);

vec4 t3=texture2D(m_Tex3,texCoord

vec4 t4=texture2D(m_Tex4,texCoord32.0);

vec4 t5=texture2D(m_Tex5,texCoord

vec4 t6=texture2D(m_Tex6,texCoord32.0);

vec4 t7=texture2D(m_Tex7,texCoord

vec4 t8=texture2D(m_Tex8,texCoord32.0);

vec4 t9=texture2D(m_Tex9,texCoord

vec4 t10=texture2D(m_Tex10,texCoord16.0);

vec4 t11=texture2D(m_Tex11,texCoord

vec4 outColor=t0*(key0.r * key1.r);

outColor+=t1*(key0.g * key1.r);

outColor+=t2*(key0.b * key1.r);

outColor+=t3*(key0.a * key1.r);

outColor+=t4*(key0.r * key1.g);

outColor+=t5*(key0.g * key1.g);

outColor+=t6*(key0.b * key1.g);

outColor+=t7*(key0.a * key1.g);

outColor+=t8*(key0.r * key1.b);

outColor+=t9*(key0.g * key1.b);

outColor+=t10*(key0.b * key1.b);

outColor+=t11*(key0.a * key1.b);

// overlay


#ifdef USE_GRID

// somewhen in the future this grid will be used for green/red/brown path coloring

vec4 t13=texture2D(m_Tex13,texCoord*256.0);

outColor =t13;


return outColor;


void main(void)


vec4 outColor = computeDiffuse()

float diffuseFactor = max(0.0, dot(vNormal,normalize(;

outColor = outColor
DiffuseSum * diffuseFactor;

gl_FragColor = outColor;



Hahaha, priceless.

I ran my program in Ubuntu and recognized, thanks to the standard image viewer installed, that the gray areas in the picture are indeed transparent. So a simple “outColor.a = 1.0;” at the end of the frag shader solved the issue.

Thanks for the effort, Kirill :slight_smile:

Haha, yeah the exported screenshot has actual alpha intact

But is this intended behaviour? Don’t you actually want to have 1:1 copy from framebuffer to screenshot? This is apparently not the case here…

Dodikles said:
But is this intended behaviour? Don't you actually want to have 1:1 copy from framebuffer to screenshot? This is apparently not the case here...

That is a 1:1 copy from framebuffer to screenshot

Haha, got me there :stuck_out_tongue:

I mean WYSIWYG as I got obviously not what I see. Another question: Why did I see my terrain anyway when it was transparent the whole time?

The values in the framebuffer are not alpha premultiplied.

In any case, I see this as a feature and not as a limitation