Specific issue related to Raspberry Pi

The Raspberry Pi doesn’t support BGR8 image formats. Hence while using Jmonkey, I create images with an Alpha channel and save it as a PNG. This gets rendered correctly both on my Ubuntu machine as well as on Raspberry Pi - If a BGR8 image is used in an app in RaspberryPi - the renderer throws an exception and app quits.

I am a newbie to JMonkey. So please help with this issue.

I am trying to run the HelloCollison sample on the Raspberry Pi. The supplied images are all JPG’s with out Alpha.

So I opened all the images using GIMP and added an Alpha channel. Saved the file as PNG.

Modified the level.mesh.xml as well as main.material to change the file names from JPG to PNG.

When I run the code on the Ubuntu machine with the new PNG - the application works.

When I try to run this application on the RaspberryPi - the application starts up - no errors. But the scene appears in Silhoutte, i.e all the images/textures are Opaque. So all I get is black boxes every where on the scene.

With an earlier example, I had to have the following code to get the textures rendered correctly on the Raspberry Pi.
[java]
wall_mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);; – with this line I get black box
changed to >>> wall_mat = new Material((MaterialDef) assetManager.loadAsset(new AssetKey(“Common/MatDefs/Misc/Unshaded.j3md”)));
wall_mat.setTexture(“ColorMap”, assetManager.loadTexture(new TextureKey(“Textures/blue.png”, false)));
wall_mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); <<< with out this line I get black box

[/java]
In the HelloCollision example all Material settings are in the xml file.

How do I edit the xml to set the Alpha blendmode?

what exactly do you write into the additional alpha layer?

However i suspect a driver bug on raspberry, as the ubuntu works.

@krishnakumar.ck said: [java] wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); wall_mat = new Material((MaterialDef) assetManager.loadAsset(new AssetKey("Common/MatDefs/Misc/Unshaded.j3md"))); [/java]

The two lines above are effectively identical. If you get different results then it is not at all because of these lines or your testing methodology is flawed.

On Gimp, I open the JPG and use Layer->Add Transparency–>Add Alpha channel - then I save the image with PNG extension.

Please note if I create a image from scratch using GIMP with an Alpha channel and save it as PNG - it works on the Pi.

It is only when I try to change an existing JPG image to PNG - the image appears Opaque on the Pi.

@pspeed said: The two lines above are effectively identical. If you get different results then it is not at all because of these lines or your testing methodology is flawed.

I will retest my code - but the problem I encounter is not because of this line.

Just to clarify My working code is as below

Material floor_mat = newMaterial((MaterialDef) assetManager.loadAsset(new AssetKey(“Common/MatDefs/Misc/Unshaded.j3md”)));
floor_mat.setTexture(“ColorMap”, assetManager
.loadTexture(new TextureKey(“Textures/green.png”, false)));
floor_mat.getAdditionalRenderState().setBlendMode(
RenderState.BlendMode.Alpha);

green.png is an image I created from scratch using Gimp - nothing fancy a 16x16 image with green fill.

When this code is executed with green.png it works on the Raspberry Pi.

JMonkey sample codes predominantly use JPG textures. I convert one of those JPG images to PNG using Gimp and save it as a PNG (Process as described in earlier post).

When I use these converted PNG’s and run it on the Pi, I get opaque textures. [java][/java]

Just for you information RBG8 is not supposed to be supported, the opengl specs do not require it. Of course some hardware do, but I guess raspberry pi doesn’t.
However RGBA8 is required by the spec and usually supported.

EDIT, Actually looking closer it is required since ogl 2.0, so just disregard this post.

Also reading back the whole post it looks like something goes wrond when you convert the JPG to PNG in gimp in some way. Make sure your PNG is a PNG 24 format

@pspeed said: The two lines above are effectively identical. If you get different results then it is not at all because of these lines or your testing methodology is flawed.

You are correct - either of these two lines do not matter.

Just this line matters in Raspberry Pi

wall_mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); <<< with out this line I get black box

However to reiterate the problem, when I convert a JPG texture to PNG, the texture appears Opaque on Raspberry PI alone - even with the above code.

To answer my initial question how to set Alpha mode in the material file. The answer is in this link
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:j3m_material_files#example_3transparent

AdditionalRenderState {
Blend Alpha
AlphaTestFalloff 0.50
FaceCull Off
}

You could use ImagePainter to make sure the images are in a supported format although it would add some loading time & memory usage.

Try using a tool other than gimp to do the image conversion, it must be doing something odd. There are plenty of format conversion programs out there - try a few and see what works :slight_smile:

Please ignore my previous phrasing of the problem - it was not very clear. I am re-opening this as my problem is not yet resolved.

To render a texture on Raspberry Pi - I use the following code and this works

Material floor_mat = newMaterial((MaterialDef) assetManager.loadAsset(new AssetKey(“Common/MatDefs/Misc/Unshaded.j3md”)));
floor_mat.setTexture(“ColorMap”, assetManager
.loadTexture(new TextureKey(“Textures/green.png”, false)));
floor_mat.getAdditionalRenderState().setBlendMode(
RenderState.BlendMode.Alpha); — If this line is absent I get a opaque texture.

I am trying the HelloCollision example, in this example the whole scene is loaded using the xml file. The material properties are loaded via another file main.material - I am unable to set the BlendMode using Java code, as the Spatial class doesn’t seem to have a getAdditionalRenderState method

With the example code, I get opaque textures when it is run on the Raspberry Pi, as BlendMode is not set.

In order to set the BlendMode for the material - I edited the main.material file and added the RenderState as below - but this doesn’t seem to have any effect. I tried changing RenderState to AdditionalRenderState - that doesn’t make any difference.

I got the syntax from this link
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:material_specification

Could any one please suggest how do I set a BlendMode for a material which gets loaded from the scene file/material properties file.

[java]
material grass.png
{
technique
{
pass
{
diffuse 1.000000 1.000000 1.000000
specular 0.000000 0.000000 0.000000 12.500000
texture_unit
{
texture grass.png
}
}
}
RenderState {
Blend Alpha
}

} [/java]

I went through some PDF documentation on the Materials file available on this website. It states the syntax as below [java]material grass.png
{
technique
{
pass
{
diffuse 1.000000 1.000000 1.000000
specular 0.000000 0.000000 0.000000 12.500000
texture_unit
{
texture grass.png
}
}

RenderState {
Blend Alpha
}
}[/java]

When I use this syntax, I get a Unsupported pass directive: Blend

Hence I went through the code of MaterialLoader.Java - it was expecting a different syntax

So I modified the file as below
[java]
material rooftiles.png
{
technique
{
pass
{
diffuse 1.000000 1.000000 1.000000
specular 0.000000 0.000000 0.000000 12.500000
texture_unit
{
texture rooftiles.png

		}
		scene_blend alpha_blend
		
	}
	
}

}
[/java>

With this new code, the warning disappeared, but the textures are still Opaque.

Please note the issue is only on the RaspberryPi - the textures render properly with or with out Alpha Blending on a regular desktop.

1 Like

Your object has to be in the transparent bucket.

@nehon said: Your object has to be in the transparent bucket.

Note: technically this is not true. It just affects when it is drawn… which could cause weird sorting issues.

The fact that OP says it works on desktop and not on Pi seems to point to a driver issue to me. Though I don’t know how blending is even remotely working on desktop if something is setting blend to alpha. I think there is more going on here than we can see without a simple test case… not that we could run it on the Pi but we could rule out a little of potential mistakes.

@nehon said: Your object has to be in the transparent bucket.

I am using the HelloCollision code as it is - no modifications to the Java Code. Except that I have extracted the town.zip file into Scenes folder

I am not proficient enough with JMonkey or in the Graphics terminology to understand whether the HelloCollision code has a transparent bucket. Any help is appreciated, the link to the code is as below

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_collision

Please note:

I have tested the BrickWall application on the Pi and it works. (Not with the original images but with PNG’s re-created)

There are two main criteria for a JMonkey Application to render on the RaspberryPi,

  1. the texture images should be a PNG (i.e RGBA8).

2 . floor_mat.getAdditionalRenderState().setBlendMode(
RenderState.BlendMode.Alpha);

This line of code needs to be present for the texture to appear on the Pi. If it is absent then it results in Opaque texture.

However on Desktop - the presence or absence of this line doesn’t have an effect.

My problem with the HelloCollision application is that materials are loaded from a scene file and I have no access to the textures/materials from the Java code to set the BlendMode(or atleast I am not aware of - if this is possible please let me know and I will try).

So I have been messing around the main.material file to include the BlendMode option - which so far has been unsuccessful

I have even tried using images from the Brick wall app(which rendered on the Pi) in the HelloCollision app just to rule out that it is an image issue.

@krishnakumar.ck said: 2 . floor_mat.getAdditionalRenderState().setBlendMode(

Without that line somewhere, the material will always be rendered opaque. Maybe our definitions of opaque are different. My definition of opaque is that any transparent pixels are rendered as a solid color (usually black)… but otherwise the picture in the texture is rendered properly.

But if you don’t set the blend mode on the material… either in code or the material definition, then no blending will occur.

Well for the workaround,loop over the rootnode’s childs (the loaded scene a loaded model whatever)
if instanceof Node -> recursive for all childs
if instanceof Geometry -> getMaterial -> setBlendmode

@pspeed said: Without that line somewhere, the material will always be rendered opaque. Maybe our definitions of opaque are different. My definition of opaque is that any transparent pixels are rendered as a solid color (usually black)... but otherwise the picture in the texture is rendered properly.

But if you don’t set the blend mode on the material… either in code or the material definition, then no blending will occur.

I am unable to get a screen grab on a Pi, as I am running the Jmonkey code with out X.

Let me explain what I mean by Opaque.

I have a cube on screen, I have a green.png file 16x16 pixel which is a solid green image. When I set the material for the cube and apply the texture with this code
Box floor = new Box(Vector3f.ZERO, 10f, 0.1f, 5f);
floor.scaleTextureCoordinates(new Vector2f(3, 6));
Geometry floor_geo = new Geometry(“Floor”, floor);
Material floor_mat = newMaterial((MaterialDef) assetManager.loadAsset(new AssetKey(“Common/MatDefs/Misc/Unshaded.j3md”)));
floor_mat.setTexture(“ColorMap”, assetManager
.loadTexture(new TextureKey(“Textures/green.png”, false)));
floor_mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); ------- M
floor_geo.setMaterial(floor_mat);
floor_geo.setLocalTranslation(0, -0.1f, 0);

I expect to see a green cube. This cube appears green on Desktop with or with out this line of code marked as M.

This cube appears as a Black cube on the Raspberry Pi if the line M is absent. (This Blackness is what I am referring as Opaque)

I am again coming back to the HelloCollision example where, the Materials are not explicitly set in the Java code, they are defined in a xml/text file.

My query is, how do I set the Blend mode in Java for a scene/materials loaded from scene file?.

@Empire Phoenix said: Well for the workaround,loop over the rootnode's childs (the loaded scene a loaded model whatever) if instanceof Node -> recursive for all childs if instanceof Geometry -> getMaterial -> setBlendmode

I understand your suggestion - I will try it as a last resort, but I guess there must be something simple which I am missing out as a newbie.