Shader parameter and materials

Hi all,

i have a question to the material system(shaders).



I’m trying to write a gui lib for jme3 (which i want to share, as soon as the basic stuff is done).

For that i need a clipping shader for scrollpane behavior. These shaders are copies of the existing solidcolor and simpletexture shaders and i have to manipulate the parameter(clip_Rect) at runtime.



The ClipSolidColor.frag file looks like this:

[java]

uniform vec4 m_Color;

uniform vec4 clip_Rect;



void main(){

if(clip_Rect!=0){

if(gl_FragCoord.x<clip_Rect.x | gl_FragCoord.y<clip_Rect.y | gl_FragCoord.x>clip_Rect.x+clip_Rect.z | gl_FragCoord.y>clip_Rect.y+clip_Rect.w){

return;

}

}

gl_FragColor = m_Color;

}

[/java]



If i apply the clip_Rect of one of the materials, all the materials(of the same type) are affected. (for the rectangle is a color used by now, hope there will be a setVector4f()-method soon)



[java]

public void setClipRect(int x, int y, int widht, int height) {

clipRect = new ColorRGBA(x, y, widht, height);



for (Component child : getChildren()) {

child.setClipRect(x, y, widht, height);

}



for (Spatial child : visibleNode.getChildren()) {

if (child instanceof Geometry) {

((Geometry) child).getMaterial().setColor(“clip_Rect”, clipRect);

}

}



}

[/java]



Perhaps i have a logical fail, but i think i don’t understand the materials perfectly. Perhaps the caching of the materials is my problem.



If anyone can give me a hint what i’m doing wrong would be nice.

The bug you’re talking about is real (we know about it, and we will fix it at some point). However your use case can be solved by using the renderer call setClipRect

2 Likes

Thanks for the response, so i don’t have to waste time for searching in my code. Unfortunately i don’t see a way to use renderManager.setClipRect, cause i need clipping for child nodes of my scroll pane, not for the scene.

Think i have to wait for the fix, but no need to hurry, i can go on with other things .

Hi, i recognized a fix but i think the BitMapFonts still have that problem, but i’m not sure about that cause i had to reimplement that stuff to render the right way. If there’s a test program needed i could share it here to show the issue.

That bug should be fixed in the latest revision. Could you provide the test program?

Sure, here is the eclipse project with a test class in the test package.

http://nh-game.net/gui.zip



As you can see there, the window in the right and the textfields don’t show the text, as soon as you drag that window behind/before the scrollpane in the left( there’s the clipping set to the material), it is shown.

Is the test ok or shall i do a simplier one to get the behavoir isolated?

Yeah sorry I completely forgot to answer this one. :open_mouth:

There’s way too many classes to track where the problem is.

A test case should be one class and not use many assets, that would be best

Hi,

i updated the material things and made the simpliest test i can.



http://nh-game.net/testFont.zip



There are 2 BitmapText components and the first is set with a clipping material. As you can see the second text component and the fps-text in the stats view are also clipped.



The BitmapFontLoader is a copy of the existing one in jme and the only thing i changed is the setting of the material.

The two texts share the same font, so they share the same material.

E.g. text1.material == text2.material, so when you set a parameter on one, it also goes to the other.

But isn’t it the same problem like at the beginning in this post? I have a shared material and it is cached, and the manipulation of one affects the other. The materials for my other components should be “shared” too, cause the are SimpleTexture’s with the same images and such things. How can i fix my problem and how is it fixed for the other materials, i don’t understand this…

When you load regular models, the materials are cloned (e.g clone() is called on them). However when you create a text which is a “instance of a font”, it shares the material with the font without cloning it.

So i wanted to clone the materials for BitmapTextPages too. But the methods of the QuadList class have the default modifier and are only accessable in the package. Is that made by design or only laziness for prototyping? If they were public i could use this and don’t have to copy the whole classes for bitmap text only to set the material in one line.



I only have to set the line 63 in BitmapTextPage to “Material mat = font.getPage(page).clone();”, or do you have another idea for that?

So what exactly do we have to do to make this work?

Maybe you can provide a patch file?

1 Like

I have to think about it and read the source to get the best approach. Seperating the material from the implementation of text is the way i would prefer right now, but i don’t really know. Think i can figure it out this weekend and give a patch for it.

A BitmapText (in the latest jME version) is a node that has a bunch of BitmapTextPages, so you can just go through them and call something like:

[java]

page.setMaterial(page.getMaterial().clone());

[/java]

and that should work

Ok, i did it in another way. I already had to moco the BitmapFontLoader to load the right MaterialDef.

[java]MaterialDef spriteMat = (MaterialDef) info.getManager().loadAsset(new AssetKey(“assets/scroll/ClipUnshaded.j3md”));[/java]



So i only had to make a class:

[java]public class ClonedBitmapFont extends BitmapFont {



@Override

public Material getPage(int index) {

return super.getPage(index).clone();

}



}[/java]



And use it in the loader.

[java]BitmapFont font = new ClonedBitmapFont();[/java]



So thank you for your help, think that’s all for this thread.