I posted a couple days ago about rendering textures using Java2D and the wiki tutorial:
http://www.jmonkeyengine.com/jmeforum/index.php?topic=1709.0
I think I came up with somewhat of a solution, basically it boils down to me updating the underlying Java2D Image, and then calling deleteAll() on the TextureState object, and calling setNeedsFilterRefresh(true), on the Texture object. I basically stumbled on to the setNeedsFilterRefresh(true), fix/hack, by removing lines from my verbose inefficient previous solution (creating a new Texture and TextureState every update).
My question is why does this setNeedsFilterRefresh(true) put the Texture in a state that it will be correctly refreshed, does the jME not render the texture from the Texture’s image buffer each frame? Also it didn’t seem to pick it up when I called updateRenderState() on the Node being textured? Is there some other jME update*State() that I’m not calling that would allow me to refresh it correctly.
The fixed solution code setGauge() method is:
jME does not render the texture from the image buffer each frame because that would be very slow, the image would have to be re-sent to the videocard each frame.
I'm sorry I missed your reply in that thread (it's an old one after all). These days jME has a very useful class for this, (LWJGL)ImageGraphics. It takes care of all the updating for you (only when it has to, only the parts of the texture that changed, etc).
Batman's code is broken, because jME is now more optimized to ignore setting textures that are already set. However, it doesn't ignore them if they need a filter or wrap refresh. It actually doesn't jump right tot he part where it does the refresh, so it noticed the texture's id is 0, so it updates the texture.
Still, it should work the way batman does it, he deletes the textures in his code. But currently if you delete a texture while it's set as a current texture, the current texture is not cleared. That looks like a bug to me, so thanks…
Should be fixed in CVS, you won't need setNeedsFilterRefresh(true); anymore. But please verify this if you like.
llama,
It's still not updating when I do just the deleteAll() on the TextureState without the setNeedsFilterRefresh(true). Let me know what debug info I can provide you with.
What I've noticed:
When the LWGLTextureState deleteAll() method is called on in my setGauge() method:
- The texture ArrayList contains one Texture object whose image field is set to my PaintedGauge image object and imageLocation==null.
- The currentTexture[] array contains one Texture element, whose image field is set to an Image reference and the imageLocation==file:/<PATH_DETAILS>/jme/src/com/jme/app/defaultfont.tga, where <PATH_DETAILS> is irrelevant path information on my machine.
So it appears that the currentTexture[] doesn't contain the object that is in the texture ArrayList. Let me know if you need any other information from my program.
Thanks again!
The CVS server was being very slow, could you check if this is in your LWJGLTextureState.java?
public void deleteAll() {
for (int i = 0; i < texture.size(); i++) {
Texture tex = texture.get(i);
if (tex == null)
continue;
id.clear();
id.put(tex.getTextureId());
id.rewind();
tex.setTextureId(0);
GL11.glDeleteTextures(id);
// if the texture was currently bound glDeleteTextures reverts the binding to 0
// however we still have to clear it from currentTexture.
if (currentTexture[i] == tex)
currentTexture[i] = null;
idCache[i] = 0;
}
}
I'm a bit at a loss why it won't work with this, but it would with filter refresh.
llama,
My version of deleteAll() looks to be the same one:
Er, ok I was actually ignoring the wonderful debug data you gave me. The font texture (for drawing the FPS stuff) is set over the java2d texture, so yes in theory, the texture should be updated anyway when it's switched back again. Without my bug fix and without the filter update. Still, we found a bug
I'm kinda lost. Can you set a breakpoint on the load method of TextureState? I can't imagine setting some filter parameters will magically update the texture. Even so, see if you get the same result (that it works) with setNeedsWrapRefresh().
The line that decides wether to ignore a texture is:
if ((texture == currentTexture[i]
&& (texture == null || (!texture.needsWrapRefresh() && !texture.needsFilterRefresh())))) {
continue;
}
As you said, texture != currentTexture so the filter part is not even reached.
I hit the load method every time when I use the setFilterRefresh(), but I do not with the setWrapRefresh(), which is very bizarre…Unless other stuff is happening outside of TextureState??
I'll try digging into it more, let me know what other information you're looking for.
At least you agree with me it's bizarre I'll take a look at your code myself now…
For what it's worth… you should probably set them both to true after deleting the texture from the unit anyway, else they might not get set (because you've destroyed the texture id). Maybe I'll add this to the delete methods. I just don't see how how setting or not setting them
OK…
With me, load is always invoked (even when I don't set filter or wrap) when I move the camera. Are you sure this does not happen with you?
The problem is, that when the texture is deleted, it does need a filter refresh, because of what I said in my previous post (the texture is deleted, so more an initial setting than a refresh). Without setting the filter the texture is not properly displayed here (all white), maybe there it'll just remain static. (Ati card here) I'll add setNeedsFilterRefresh(true)
llama,
Thank you very much, for fixing that!!
:mrgreen:
Let me know if there is any piece of jME that you guys need digging into!
Hi,
I am trying to use JAVA2D images as a texture but I cannot compile all these examples for JME2.0.
For example I have to change AlphaState to BlendState.
A few changes are here
http://www.jmonkeyengine.com/wiki/doku.php?id=jme_to_jme2_changes
but most of them not.
Can anyone help me?
All examples come with the jme source.
So download the source and you have all the working examples.