<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>nifty-gui</title>
	<atom:link href="http://nifty-gui.lessvoid.com/feed" rel="self" type="application/rss+xml" />
	<link>http://nifty-gui.lessvoid.com</link>
	<description>a nifty gui for your java opengl/lwjgl application</description>
	<lastBuildDate>Mon, 01 Apr 2013 09:25:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Inside Niftys RenderDevice and how to speed it up (Part 2/2)</title>
		<link>http://nifty-gui.lessvoid.com/archives/530</link>
		<comments>http://nifty-gui.lessvoid.com/archives/530#comments</comments>
		<pubDate>Mon, 01 Apr 2013 09:17:19 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=530</guid>
		<description><![CDATA[Welcome back to the second part of this two part mini series. Today we&#8217;ll speed up the Nifty rendering process. So fasten your seat belts &#8211; it will be a long and rough ride! In the first part we&#8217;ve identified several problems that we&#8217;d like to fix today: primitive/polygon submission is not optimal and requires [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome back to the second part of this two part mini series. Today we&#8217;ll speed up the Nifty rendering process. So fasten your seat belts &#8211; it will be a long and rough ride! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>In the <a href="http://nifty-gui.lessvoid.com/archives/505">first part</a> we&#8217;ve identified several problems that we&#8217;d like to fix today:</p>
<ul>
<li>primitive/polygon submission is not optimal and requires way too many GL calls</li>
<li>we switch GL state very often, especially enabling/disabling texturing while rendering and switching the current texture costs performance</li>
<li>we enable/disable and change the clipping rectangle very often (eventually)</li>
<li>we change other states like the blend mode. Not a lot but it is still happening if you ask for it within your screen (f.i. using some effect)</li>
</ul>
<p>So let&#8217;s tackle these issues one at a time.<br />
<span id="more-530"></span><br />
I won&#8217;t go into the specific OpenGL methods too much and will concentrate more on the &#8220;Nifty&#8221; side of things. You can read up the OpenGL calls <a href="http://www.opengl.org/sdk/docs/man3/">elsewhere</a>. But the interesting part &#8211; at least for me and I hope for you as well &#8211; is to connect all the dots and combine the individual pieces to optimize Nifty.</p>
<p>So without further ado let&#8217;s rock.</p>
<p><em><strong>Optimize polygon submission</strong></em></p>
<p>Well, that one is a no brainer since vertex arrays have been a part of the OpenGL spec since the very early OpenGL 1.1 days (1995 or so). The idea is to put all of your vertex data into an array and then give OpenGL a pointer to that array and tell it in a single call: now go and render all of them. Since I&#8217;d like to keep the current LWJGL renderer compatible with legacy OpenGL (for now, be patient ^^) I&#8217;ve used plain old client-side vertex arrays. This means that all of the vertex data is stored on the CPU and is only send to the GPU for rendering. This allows us to take advantage of the GL_QUADS rendering mode (which has been optimized away from core profile unfortunatly).</p>
<p>So for each Nifty <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/spi/render/RenderDevice.java">RenderDevice</a> render*() method (renderQuad() or renderImage()) we add four vertices to the vertex buffer representing a single quad. When Nifty later calls the endFrame() method we render all of the quads with a single glDrawElements(GL_QUADS) call. This way we can remove a couple of hundred individual glBegin()/glEnd()/glVertex() calls and GL can now take our buffer, process it in one step and render it! Much faster!</p>
<p>Great! We&#8217;re done! Woohoo!</p>
<p>But wait, what do you say? We&#8217;re not finished yet? What&#8217;s with all of the texturing and what is with font rendering? And what if we want to render a single colored untextured quad like a Nifty panel with a plain backgroundColor? Wouldn&#8217;t we have to disable texturing somehow in between all those quads in the vertex array?</p>
<p>Of course you&#8217;re right &#8211; readers are always right <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  So let&#8217;s continue.</p>
<p><strong>Disable texturing while rendering with a vertex array</strong></p>
<p>If we would enable/disable texturing all the time or switch the current texture while we&#8217;re rendering our quads we would end up with individual render calls again. In the end all of our performance gains would have been lost again. So what should we do?</p>
<p>Our first trick is to let texturing enabled all the time. We&#8217;ll simply submit textured quads only &#8211; all the time. To render a plain colored quad we&#8217;ll reserve some pixels of a plain solid color in our texture, let&#8217;s say white. If we then render a quad with texture coordinates of this white piece of the texture we would end up with a solid white quad &#8211; and this quad could really be any size we want since it doesn&#8217;t really matter if we would stretch a single white pixel to the size of the screen. It would still be white <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So that&#8217;s great. We can render white colored quads. Yeah! But what about other colors? Ok, that&#8217;s easy as well. We attach vertex colors to our vertices. To render a plain colored red quad for instance, we&#8217;ll set the vertex color of each vertex to red and in the end we&#8217;d have a red quad instead of a white one. And btw. this allows us to add support for linear gradients as well when we use different colors.</p>
<p>So to summarize our vertex data, here are the components we store per vertex in our array:</p>
<ul>
<li>The position of the vertex. At the moment we&#8217;re only 2d so two floats should be appropriate (x and y coordinates)</li>
<li>The texture coordinate for the vertex (u and v, 2 floats as well)</li>
<li>A color for the vertex. That will add 4 more floats.</li>
</ul>
<p>So there is no need to disable texturing at all! If we want to render a plain colored quad we&#8217;ll simply adjust the texture coordinates of that quad in our vertex array to match up with the plain colored area in our texture.</p>
<p><strong>Switch the current texture while rendering with a vertex array</strong></p>
<p>Finally we&#8217;ll need a way to render different textures. The solution to this is simple in theory but was a bit more involved in the end.</p>
<p>The idea is to combine all of our individual images into one big texture. The name for this optimization technique is &#8220;texture atlas&#8221; or &#8220;texture packing&#8221;. In most cases you would combine your textures into a bigger one as a pre-process using some custom tool. But for Nifty we&#8217;ll need to do that dynamically. Let&#8217;s enter the world of texture packing algorithms also known as bin packing.</p>
<p>Well, as it appears this topic is a huge one! There are even PhD Thesis discussing this in depth (The PhD Thesis of Andrea Lodi f.i.: <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.98.3502&#038;rep=rep1&#038;type=pdf">Algorithms for Two Dimensional Bin Packing and Assignment Problems</a>).</p>
<p>One of the more simple algorithms and the one we&#8217;ll use for now is the <a href="http://www.blackpawn.com/texts/lightmaps/default.html">Lightmap Packing Algorithm</a> by <a href="http://www.blackpawn.com/">Black Pawn</a> and the <a href="https://github.com/lukaszdk/texture-atlas-generator">Java port</a> of this algorithm done by <a href="https://github.com/lukaszdk/texture-atlas-generator">lukaszdk</a>.</p>
<p>The Java version of the <a href="https://github.com/lukaszdk/texture-atlas-generator">Texture Atlas Generator</a> is meant to be used as an executable jar that combines multiple textures into a bigger one using java.awt.image.* stuff. Not bad but for Nifty we&#8217;d like to do that on the fly and we&#8217;d like to separate the actual algorithm from the actual handling of the graphics. In the end the algorithm can work independently of the actual graphics data. So we&#8217;ve modified his code a bit. If you&#8217;re interested in the details you can find our version in the <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/batch/TextureAtlasGenerator.java">TextureAtlasGenerator</a> class. This class can be used on its own since it is self contained and doesn&#8217;t need any Nifty dependencies at all &#8211; if you ever need a similar algorithm <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>So we&#8217;ll start with a big texture (something like 2048&#215;2048 pixels works very well so far) and as Nifty loads images we&#8217;ll put them into this texture at positions the TextureAtlasGenerator calculates for us. And with that in place switching textures actually only means changing the texture coordinates according to the data that the TextureAtlasGenerator has generated. And voila we can keep rendering all of our quads in a single call using the same big texture! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><strong>Managing image resources</strong></p>
<p>The texture atlas will be filled with images for the current Nifty screen. This way all images used will be part of the texture atlas. To do that Nifty keeps track of which image belongs to which screen when it reads a XML file or when a screen is created with the Builder pattern. This tracking is done for all loaded screens and even for images that are dynamically created with Nifty.createImage().</p>
<p>In general Nifty will make sure that it uploads all images that are required for a screen when the screen is started (and gets active). Consequently when a screen ends the texture atlas is being reset to an empty one.</p>
<p>Nifty already implemented a reference counting mechanism to keep track of loaded images. This was used to prevent loading the same image multiple times and it is still being used for this purpose. However, the process of loading an image is now separated into two steps:</p>
<p>1. the actual image data is loaded into whatever image representation an implementation supports (for instance the implementation using native LWJGL will simply load an image file into a ByteBuffer) and</p>
<p>2. the loaded image data is put into the texture atlas at a position that Nifty decided when it&#8217;s time for this image to be a part of the current screens texture atlas.</p>
<p>When an image is accessed dynamically while a screen is running it will be uploaded at the time of the first access. For best performance static images &#8211; or at least ones that Nifty knows about before the screen is started &#8211; should be preferred so that Nifty can upload them to the texture atlas at the time the screen starts and not while the screen is already running. Although I think you can get away with a couple of image uploads if you don&#8217;t access too many new images at once.</p>
<p>All of this is required to keep only the currently active images in the texture atlas. This should work quite well for most use cases. However, it&#8217;s still possible to use up all of the available space in the texture atlas. In that case Nifty will complain in the log but there will be missing images. All of the Nifty examples run well with a 2K (2048&#215;2048) texture so far. The batch renderer provides a better rendering performance but you might want to plan for some additional tests to check if all of your images fit into the texture.</p>
<p><strong>Clipping</strong></p>
<p>Nifty allows you to clip child elements to the area of it&#8217;s parent element. This way only the part that intersects with the parent element will be displayed. The original Nifty renderer used glScissor() for this prior to rendering the child elements. The problem with this approach is that we can&#8217;t change the size of the scissor box while rendering with vertex arrays. So what should we do?</p>
<p>Well, clipping is a somewhat simple 2d operation so we simply clip on the CPU now! The quads we will send into the vertex array will already be clipped so we don&#8217;t have to change the scissor state while we&#8217;re rendering <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Blending</strong></p>
<p>Nifty renders everything with usual alpha transparency blending (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)) but it can be changed to Multiply (glBlendFunc(GL_DST_COLOR, GL_ZERO)) if necessary for rendering special effects. However, for the optimized renderer this is a slight problem since we can&#8217;t change the blending mode while rendering a vertex array. What Nifty will do now is to create a new batch when the blending mode changes. Since the Multiply blending mode is currently the only &#8220;other&#8221; blend mode supported and this is rarely used we&#8217;ll get away with the new batch approach. Rendering a couple of batches per frame is still a lot better than rendering hundreds of individual quads with hundreds of draw calls.</p>
<p>So with blending out of the way we&#8217;ve actually solved all of the problems we set out to fix! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>The only thing we have to discuss is how all of this has been implemented.</p>
<p>Usually this is done by each rendering system individually like a LWJGL, JOGL or JME3 batched renderer implementation. However each of these individual implementations would solve the exact same problems outlined above. All of the batching, texture atlas management and so on. Not a very nifty solution.</p>
<p>A better approach would be to solve the managment of the batches once and then use a simplified implementation for the native implementations. And that&#8217;s exactly what we did <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><strong>Unified batched RenderDevice implementation!</strong></p>
<p>Nifty 1.3.3 will provide a default implementation of the RenderDevice interface. The <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/batch/BatchRenderDevice.java">de.lessvoid.nifty.batch.BatchRenderDevice</a> handles all of things we&#8217;ve mentioned so far including all of the texture packing logic and so on.</p>
<p>Of course there is still the need for specific implementations to connect all of this to LWJGL, JOGL or jME. But these implementations are now much simpler since they don&#8217;t have to handle all of the details the original RenderDevice has to. The <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/batch/spi/BatchRenderBackend.java">de.lessvoid.nifty.batch.spi.BatchRenderBackend</a> SPI is much simpler. The BatchRenderBackend will receive quads that it should buffer in whatever way it sees fit. The LWJGL implementation fills a vertex array exactly as we&#8217;ve described above. Handling the texture atlas is reduced to creating a texture and replacing subtextures.</p>
<p>Rendering fonts is also handled inside the BatchRenderDevice which means the BatchRenderBackend doesn&#8217;t have to implement that. Font rendering is reduced to rendering quads as well and the font texture is simply treated as another part of the texture atlas. This has the additional benefit that font rendering looks the same no matter what rendering system you use because things like kerning, text string width calculations and so on are all happening inside of Nifty now <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But wait, there is even more!</p>
<p><strong>Bonus: LWJGL OpenGL Core Profile implementation</strong></p>
<p>Until this point you could not really use Nifty with modern OpenGL because the original LWJGL implementation didn&#8217;t support it. With the new BatchRenderDevice a full OpenGL Core Profile implementation is now available! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><strong>Shut up and <del datetime="2013-04-01T08:09:45+00:00">take my money</del> show me how to use it</strong></p>
<p>Usage of the batched renderer is very easy. In place of your usual RenderDevice implementation you use the BatchRendererDevice when you instantiante Nifty:</p>
<pre class="brush:java">BatchRenderDevice renderDevice = new BatchRenderDevice(
    put-in-batched-renderer-backend-here, // BatchRenderBackend impl
    2048, // width of texture atlas
    2048); // height of texture atlas</pre>
<p>The first parameter is an implementation of the <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/batch/spi/BatchRenderBackend.java">de.lessvoid.nifty.batch.spi.BatchRenderBackend</a> interface that connects the batched renderer to a specific OpenGL implementation. Currently the following implementations exist:</p>
<ul>
<li>LWJGL legacy batched renderer: <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-renderer-lwjgl/src/main/java/de/lessvoid/nifty/renderer/lwjgl/render/batch/LwjglBatchRenderBackend.java">de.lessvoid.nifty.renderer.lwjgl.render.batch.LwjglBatchRenderBackend</a></li>
<li>LWJGL core profile batched renderer: <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-renderer-lwjgl/src/main/java/de/lessvoid/nifty/renderer/lwjgl/render/batch/LwjglBatchRenderBackendCoreProfile.java">de.lessvoid.nifty.renderer.lwjgl.render.batch.LwjglBatchRenderBackendCoreProfile</a></li>
<li>jme3 batched renderer implementation: <a href="http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/niftygui/com/jme3/niftygui/JmeBatchRenderBackend.java">com.jme3.niftygui.JmeBatchRenderBackend</a></li>
</ul>
<p>You&#8217;ll need to use Nifty 1.3.3 or Nifty 1.4 nightly builds to have these new implementations available. For jme3 you&#8217;ll need a nightly build as well.</p>
<p>Besides the BatchRendererBackend implementation you&#8217;ll need to provide the size of the texture atlas as parameters. As mentioned above a 2k texture was enough to run all of Niftys standard examples.</p>
<p>So, that&#8217;s all there is!</p>
<p>If you made it through this huge post. Congratulations! You now know all the things that took me a couple of months to figure out <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I hope you&#8217;ve enjoyed this in-depth explanation a bit!</p>
<p>See you next time!</p>
<p>void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/530/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Correctly configure jdk14-logging (guest blog post by Ben)</title>
		<link>http://nifty-gui.lessvoid.com/archives/532</link>
		<comments>http://nifty-gui.lessvoid.com/archives/532#comments</comments>
		<pubDate>Sat, 16 Mar 2013 00:33:28 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=532</guid>
		<description><![CDATA[After being puzzled for a while why he wasn&#8217;t able to configure logging in jME-Nifty properly Ben (&#8220;ben dot foxmoore at gmail dot com&#8221;) set aside some time to figure it out. He was kind enough to share his findings with us in this guest blog post So here is Ben explaining a proper way [...]]]></description>
			<content:encoded><![CDATA[<p>After being puzzled for a while why he wasn&#8217;t able to configure logging in jME-Nifty properly Ben (&#8220;ben dot foxmoore at gmail dot com&#8221;) set aside some time to figure it out. He was kind enough to share his findings with us in this guest blog post <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So here is Ben explaining a proper way to configure Nifty logging:</p>
<p>It seems that most people who have issues with Nifty&#8217;s logs want to cut down on the number shown, but I, on the other hand, wanted to see more. Unfortunately, setting the global logging level to Info caused JME3 to also log lots of information that wasn&#8217;t relevant to the problem at hand. I attempted a quick fix using the following code:</p>
<pre class="brush:java">public static void main(String[] args) {
        Logger.getLogger("").setLevel(Level.WARNING);
        Logger.getLogger("de.lessvoid.nifty").setLevel(Level.INFO);
        SimpleApplication app = new SimpleApplication() {
            public void simpleInitApp() {
                NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(
                     assetManager, inputManager, audioRenderer, guiViewPort);
                Nifty nifty = niftyDisplay.getNifty();
                nifty.loadStyleFile("nifty-default-styles.xml");
                nifty.loadControlFile("nifty-default-controls.xml");
                guiViewPort.addProcessor(niftyDisplay);
            }
        };
        app.start();
    }</pre>
<p>However, you&#8217;ll quickly realise that this doesn&#8217;t actually cause Nifty to display any extra logs. After many hours trying to work out why, I discovered that it&#8217;s all down to an intricacy in the way LogManager keeps track of the Loggers in your program. LogManager only keeps a weakReference to each Logger, allowing any that are no longer being used to be garbage collected. Because of this, in the time between line 3 and line 6, the JRE garbage collects the original &#8220;de.lessvoid.nifty&#8221; Logger created at line 3. When the &#8220;de.lessvoid.nifty.Nifty&#8221; Logger is retrieved in the Nifty constructor (called by the NiftyJmeDisplay constructor at line 6), a new one is created and it inherits its Level from the rootLogger, which is set to Warning at line 2. (The LogManager keeps a strong reference to the rootLogger so it is never garbage collected.)</p>
<p>A quick (but not very nifty) solution to this problem is to just keep a static (strong) reference to the &#8220;de.lessvoid.nifty&#8221; Logger in your class, as such:</p>
<pre class="brush:java">    private static Logger logger;

    public static void main(String[] args) {
        Logger.getLogger("").setLevel(Level.WARNING);
        logger = Logger.getLogger("de.lessvoid.nifty");
        logger.setLevel(Level.INFO);
        SimpleApplication app = new SimpleApplication() {
            public void simpleInitApp() {
                ...
            }
        };
        app.start();
    }</pre>
<p>Ultimately though, the niftiest solution to this problem is to use a custom properties file which specifies to the LogManager how to initialize all of the Loggers. The following &#8220;logging.properties&#8221; file will initialize the Logging system in the same way as the code above:</p>
<pre class="brush:java">handlers=java.util.logging.ConsoleHandler
.level=WARNING
de.lessvoid.nifty.level=INFO</pre>
<p>There are two ways to tell the LogManager to use this file. Either use the</p>
<pre class="brush:java">"-Djava.util.logging.config.file=pathToLogging.properties"</pre>
<p>flag when running your program, or, alternatively, use the following code:</p>
<pre class="brush:java">    public static void main(String[] args) throws Exception {
        InputStream inputStream =
             ClassLoader.getSystemResourceAsStream("logging.properties");
        LogManager.getLogManager().readConfiguration(inputStream);
        SimpleApplication app = new SimpleApplication() {
            public void simpleInitApp() {
                ...
            }
        };
        app.start();
    }</pre>
<p>Hopefully this should help anyone who comes across the same issue that I did!</p>
<p>(As a small side note, there is one final alternative: LogManager can also use the &#8220;java.util.logging.config.class&#8221; property. If present, the given class will be loaded, an object will be instantiated, and that object&#8217;s constructor is responsible for providing the initial configuration as an InputStream, just as above.)</p>
<p>So that&#8217;s it! Finally you can configure logging correctly! THANKS A LOT BEN! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>void</p>
<p>PS: Nifty 1.3.3 and Nifty 1.4 have already been configured to log less by default. So most people should now be more happy with the new defaults. But if you really need the logging to debug an issue you now can do it properly &#8211; thanks to Ben <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/532/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Inside Niftys RenderDevice and how to speed it up (Part 1/2)</title>
		<link>http://nifty-gui.lessvoid.com/archives/505</link>
		<comments>http://nifty-gui.lessvoid.com/archives/505#comments</comments>
		<pubDate>Sun, 10 Mar 2013 18:32:13 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=505</guid>
		<description><![CDATA[When I started Nifty my mindset was like, &#8220;well, games can render millions of polys each frame so throwing a couple of hundred textured polys at the GPU shouldn&#8217;t hurt performance that much&#8221;. Well, I was wrong. To achieve a somewhat high performance you still have to play by the GPU rules. Simply throwing polys [...]]]></description>
			<content:encoded><![CDATA[<p>When I started Nifty my mindset was like, &#8220;well, games can render millions of polys each frame so throwing a couple of hundred textured polys at the GPU shouldn&#8217;t hurt performance that much&#8221;.</p>
<p>Well, I was wrong.</p>
<p>To achieve a somewhat high performance you still have to play by the GPU rules. Simply throwing polys at the GPU and expect the best rendering performance doesn&#8217;t really work. In this two part series of blog posts I&#8217;ll try to explain what basically sucks in the current way we render things and what we&#8217;ve done in the last couple of months to achieve better rendering performance.</p>
<p>There is of course always room for more improvement. One thing I&#8217;d like to tackle in the future and especially in Nifty 2.0 would be to render only the parts of a scene that have changed. Since the best performance you can ever get is not to render <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But since this is a bit more involved for now we&#8217;re stuck with the &#8220;render the whole GUI each frame&#8221; approach of current generation Nifty. BUT at least we can make Nifty render fast. Very fast.<br />
<span id="more-505"></span><br />
So here we go. A trip down the current way how Nifty renders its GUI and how we can try to be a bit smart to optimize it a lot. In this first part we&#8217;ll look at the way the current renderer works and how bad some of the decisions have been according to rendering performance. In the second part of this two part series we&#8217;ll look at the way we can make everything better and speed it up.</p>
<p>When it comes to rendering Nifty only knows three somewhat high level primitives:</p>
<ul>
<li>render a quad in a single color or with different colors at each vertex (for gradient support)</li>
<li>render a textured image</li>
<li>render text with a given font</li>
</ul>
<p>So all of the elements on your Nifty screen and all effects you apply to them will end up as a number of colored quads, textured images or text renderings.</p>
<p>To actually perform all of this Nifty provides some <a href="http://en.wikipedia.org/wiki/Service_provider_interface">SPI</a> in the <a href="https://github.com/void256/nifty-gui/tree/1.3/nifty-core/src/main/java/de/lessvoid/nifty/spi/render">de.lessvoid.nifty.spi.render</a> package. If you implement the four simple interfaces for the rendering system of your choice you&#8217;re done and Nifty can be used with your rendering system. Nifty provides native LWJGL, JOGL, jME3, Slick2D and even Java2D adapter implementations already.</p>
<p>So let&#8217;s take a look at the main interface of the SPI the <a href="https://github.com/void256/nifty-gui/blob/1.3/nifty-core/src/main/java/de/lessvoid/nifty/spi/render/RenderDevice.java">de.lessvoid.nifty.spi.render.RenderDevice</a>. There are methods to load images and fonts and methods to let Nifty request the size of the screen. Other methods let the implementation know when a render frame begins and when it ends. However, the core of the RenderDevice interface are a couple of methods to render colored quads, images and text.</p>
<p>The render*() methods contain almost all the state that is required to perform the render directly as method parameters. Things like where to render the quad on the screen and which width, height and color to use are given as parameters.</p>
<p>Besides those parameters there are two additional states that can be modified by Nifty in calling RenderDevice methods which are:</p>
<ul>
<li>the current blendmode &#8211; that defines how blending should be configured prior to rendering elements</li>
<li>enable or disable clipping &#8211; to restrict rendering to a certain rectangle on the screen. Everything outside this clipping rectangle will not be rendered.</li>
</ul>
<p>So Nifty calls beginFrame() and then repeats for everything it needs to render: set the state (clipping and blending) and then calls renderQuad(), renderImage() or renderFont() and finally it calls endFrame(). In each render*() call the implementation will now ensure that the correct textures are set or that texturing is disabled, to render plain colored quads. In case of font rendering the correct bitmap font texture needs to be selected so that the text can be rendered properly and so on.</p>
<p>And here is the main issue in the naive implementations that have been used so far especially in the LWJGL renderer. Changing state costs performance since each state switch results in quite a lot of processing on it&#8217;s way through all the different layers involved on the way to the GPU. There are driver calls, OS calls, state checks, command queues and so on to finally set the GPU in the state we need to render our triangles. If you&#8217;re interessted in all of the details there is a great series of blogs available by Fabian Giesen called <a href="http://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-pipeline-2011-index/">A trip through the Graphics Pipeline 2011</a>.</p>
<p>So the first issue the current way Nifty renders stuff is that we change state quite a lot each frame. If we need to render a single colored untextured quad we&#8217;ll need to disable texturing. If we need to render a certain image next, we&#8217;ll need to enable texturing again and make sure the texture of the image we need to render is enabled. The same happens to clipping and blending which need to be enabled or disabled as well. So we&#8217;re constantly changing state which, well, hurts performance.</p>
<p>A second issue that is especially apparent in the native LWJGL renderer is the way the actual vertex data is submitted to the GPU. When submitting data to OpenGL the classic (and very old way) to submit vertex data has been used: the immediate mode. Which means each vertex is send with multiple OpenGL calls. Here is an example:</p>
<pre class="brush:java">// code to render a single quad with vertex color - DON'T DO THAT!
  GL11.glBegin(GL11.GL_QUADS);
      GL11.glColor4f(topLeft.getRed(), topLeft.getGreen(), topLeft.getBlue(), topLeft.getAlpha());
      GL11.glVertex2i(x, y);
      GL11.glColor4f(topRight.getRed(), topRight.getGreen(), topRight.getBlue(), topRight.getAlpha());
      GL11.glVertex2i(x + width, y);
      GL11.glColor4f(bottomRight.getRed(), bottomRight.getGreen(), bottomRight.getBlue(), bottomRight.getAlpha());
      GL11.glVertex2i(x + width, y + height);
      GL11.glColor4f(bottomLeft.getRed(), bottomLeft.getGreen(), bottomLeft.getBlue(), bottomLeft.getAlpha());
      GL11.glVertex2i(x, y + height);
    GL11.glEnd();</pre>
<p>That&#8217;s really bad. First there are lots of calls to the GL and each of the calls will need to get through the different layers and checks again. This will only be ok if you send very view vertices but as the vertex count increases the overhead of the individual method calls will add up and will hurt performance as well.</p>
<p>So these are the main issues we&#8217;ll need to solve to improve rendering performance:</p>
<ul>
<li>reduce state switches</li>
<li>reduce draw calls to send vertex data</li>
</ul>
<p>The second part of this mini blog series will explain how we solve those two issues by providing a special RenderDevice implementation. Interesting enough this special RenderDevice solves additional issues and makes implementing a new renderer for Nifty more easy as well <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Instead of hundreds of glVertex() calls we can render the whole GUI in very few draw calls and most of the time even only in a single one! And all of this with no changes to the rest of Nifty or your code. In most case you&#8217;ll be able to use the new special RenderDevice for a performance boost and that&#8217;s it. nifty! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Curious? See you on the next blog post!</p>
<p>void <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/505/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Updated Manual for Nifty GUI 1.3.2 available</title>
		<link>http://nifty-gui.lessvoid.com/archives/495</link>
		<comments>http://nifty-gui.lessvoid.com/archives/495#comments</comments>
		<pubDate>Mon, 12 Nov 2012 22:23:01 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[docs]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=495</guid>
		<description><![CDATA[The updated Manual for Nifty GUI 1.3.2 is now available as a sf.net file download: nifty-gui-the-manual-1.3.2.pdf The changes are marked in the document but here is a summary of everthing that has been added: Grammar and spelling corrections thanks to wezrule Get Nifty Version String Feature Description (Short) description of imageMode=&#8221;subImageDirect:x,y,w,h&#8221; Feature Padding feature description [...]]]></description>
			<content:encoded><![CDATA[<p>The updated Manual for Nifty GUI 1.3.2 is now available as a sf.net file download: <a href="http://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.3.2/nifty-gui-the-manual-1.3.2.pdf/download">nifty-gui-the-manual-1.3.2.pdf</a></p>
<div id="attachment_496" class="wp-caption aligncenter" style="width: 310px"><a href="http://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.3.2/nifty-gui-the-manual-1.3.2.pdf/download"><img src="http://nifty-gui.lessvoid.com/wp-content/2012/11/Bildschirmfoto-2012-11-12-um-23.04.59-300x211.png" alt="" title="Nifty GUI Manual 1.3.2" width="300" height="211" class="size-medium wp-image-496" /></a><p class="wp-caption-text">Nifty GUI Manual 1.3.2</p></div>
<p>The changes are marked in the document but here is a summary of everthing that has been added:
<ul>
<li>Grammar and spelling corrections thanks to wezrule</li>
<li>Get Nifty Version String Feature Description</li>
<li>(Short) description of imageMode=&#8221;subImageDirect:x,y,w,h&#8221; Feature</li>
<li>Padding feature description including lots of examples with screenshots</li>
<li>Margin feature description</li>
<li>Renderorder feature description</li>
<li>Nifty event consuming and disable flags description</li>
<li>Description of general mouse event processing changes in Nifty 1.3.2</li>
<li>Dynamically changing effect parameters example</li>
</ul>
<p> <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/495/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nifty GUI Editor Project</title>
		<link>http://nifty-gui.lessvoid.com/archives/492</link>
		<comments>http://nifty-gui.lessvoid.com/archives/492#comments</comments>
		<pubDate>Thu, 08 Nov 2012 19:28:11 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[sightings]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=492</guid>
		<description><![CDATA[There is a Nifty editor project started by Cristiano Aguzzi which looks very promising. It allows you to create Nifty GUI XML by simply adding Nifty Elements and Controls with drag&#8217;n'drop! http://niftyguieditor.altervista.org/ It&#8217;s a Java Swing application that uses the Nifty Java2D renderer for preview. This means you can change Element properties and see the [...]]]></description>
			<content:encoded><![CDATA[<p>There is a Nifty editor project started by Cristiano Aguzzi which looks very promising. It allows you to create Nifty GUI XML by simply adding Nifty Elements and Controls with drag&#8217;n'drop!</p>
<p><a href="http://niftyguieditor.altervista.org/">http://niftyguieditor.altervista.org/</a></p>
<p>It&#8217;s a Java Swing application that uses the Nifty Java2D renderer for preview. This means you can change Element properties and see the changes in realtime! Pretty, erm, Nifty! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/492/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nifty 1.3.2 contributors kudos</title>
		<link>http://nifty-gui.lessvoid.com/archives/484</link>
		<comments>http://nifty-gui.lessvoid.com/archives/484#comments</comments>
		<pubDate>Tue, 09 Oct 2012 23:16:48 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=484</guid>
		<description><![CDATA[Well, this was really planned to be a part of yesterdays release announcement but somehow I missed to include it :/ There are a lot of people worth mentioning here that have helped in Niftys development in one way or another, be it forum posts, comments, bug reports or emails. Actually there are countless people [...]]]></description>
			<content:encoded><![CDATA[<p>Well, this was really planned to be a part of yesterdays release announcement but somehow I missed to include it :/</p>
<p>There are a lot of people worth mentioning here that have helped in Niftys development in one way or another, be it forum posts, comments, bug reports or emails. Actually there are countless people and I&#8217;d not be able to list them all! But all of that feedback &#8211; may it positive or negative &#8211; is greatly appreciated! Keep it coming and thanks A LOT for it!</p>
<p>This time I&#8217;d really like to mention a couple of special people that have provided direct patches and pull requests for Nifty 1.3.2. First of all there is:</p>
<p><strong>Martin Karing (nitram) of <a href="http://illarion.org/">http://illarion.org/</a></strong></p>
<p>who provided countless suggestions and patches. He rewrote the Slick2D renderer and pretty much rewrote the Tabs control to make it actually usable. So extra special kudos go out to Martin! <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Other Nifty 1.3.2 contributors I&#8217;d like to thank for improving Nifty are &#8211; in alpabetical order:</p>
<p>Jeremy Woertink / jwoertink<br />
Joachim Durchholz / toolforger<br />
Jonathan Fischer Friberg / odyssomay<br />
Mark / ractoc<br />
Tony Ivanov / telamohn</p>
<p>Thank you all. You rock! And see you all in Nifty 2.0! =D</p>
<p>void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/484/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nifty 1.3.2 finally arrived</title>
		<link>http://nifty-gui.lessvoid.com/archives/459</link>
		<comments>http://nifty-gui.lessvoid.com/archives/459#comments</comments>
		<pubDate>Mon, 08 Oct 2012 22:18:02 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=459</guid>
		<description><![CDATA[Nifty 1.3.2 is mainly a bugfix release and is compatible with Nifty 1.3.1. There are a couple of nifty new features available too We&#8217;ve counted 175 individual changes which is A LOT! There will be an updated Nifty Manual available soon. Until it is available you can find out what&#8217;s new in the Nifty 1.3.2 [...]]]></description>
			<content:encoded><![CDATA[<p>Nifty 1.3.2 is mainly a bugfix release and is compatible with Nifty 1.3.1. There are a couple of nifty new features available too <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  We&#8217;ve counted 175 individual changes which is <strong>A LOT</strong>!</p>
<p>There will be an updated Nifty Manual available soon. Until it is available you can find out what&#8217;s new in the <a href="http://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.3.2/nifty-1.3.2-changelog.txt/download">Nifty 1.3.2 change log (sf.net)</a></p>
<p>And here are the other Nifty links:</p>
<p><a href="https://sourceforge.net/projects/nifty-gui/files/nifty-gui/1.3.2/">Nifty 1.3.2 Download Folder at sf.net</a><br />
<a href="http://nifty-gui.sourceforge.net/projects/1.3.2/">Nifty 1.3.2 Maven Projects Page (browse the JavaDoc online!)</a><br />
<a href="http://www.jmonkeyengine.com/nightly/">Get a nightly jME3 build with Nifty 1.3.2 (jME3_2012-10-08.zip+) </a><br />
<a href="http://nifty-gui.sourceforge.net/webstart/nifty-default-controls-examples-1.3.2.jnlp">Webstart &#8211; Nifty Default Controls Example (1.3.2)</a><br />
<a href="http://nifty-gui.sourceforge.net/webstart/nifty-examples-1.3.2.jnlp">Webstart &#8211; Nifty Standard Examples (1.3.2)</a></p>
<p>For Maven simply add our sf.net Nifty Maven Repo to your pom.xml:</p>
<pre class="brush:xml">  <repositories>
    <repository>
      <id>nifty-maven-repo.sourceforge.net</id>
      <url>http://nifty-gui.sourceforge.net/nifty-maven-repo</url>
    </repository>
  </repositories></pre>
<p>and upgrade your dependency to 1.3.2:</p>
<pre class="brush:xml">    <dependency>
      <groupId>lessvoid</groupId>
      <artifactId>nifty</artifactId>
      <version>1.3.2</version>
    </dependency></pre>
<p>Have a lot of fun with Nifty 1.3.2! The best Nifty since Nifty <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/459/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>java.util.logging (jdk14 logging) oddities explained (and fixed)</title>
		<link>http://nifty-gui.lessvoid.com/archives/436</link>
		<comments>http://nifty-gui.lessvoid.com/archives/436#comments</comments>
		<pubDate>Sun, 01 Apr 2012 17:37:15 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[bubble]]></category>
		<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=436</guid>
		<description><![CDATA[Usually when you add logging to your application you create a java.util.logging.Logger that has the same name as the class you use the Logger in. Your code might look like this: package some.test; import java.util.logging.Logger; public class Main { private static Logger log = Logger.getLogger(Main.class.getName()); public static void main(final String[] args) { log.info("test"); } } [...]]]></description>
			<content:encoded><![CDATA[<p>Usually when you add logging to your application you create a java.util.logging.Logger that has the same name as the class you use the Logger in. Your code might look like this:</p>
<pre class="brush:java">package some.test;

import java.util.logging.Logger;

public class Main {
  private static Logger log = Logger.getLogger(Main.class.getName());

  public static void main(final String[] args) {
    log.info("test");
  }
}
</pre>
<p>This works well and you get something like this as the log output:</p>
<pre class="brush:java">01.04.2012 19:10:39 some.test.Main main
INFO: test
</pre>
<p>Now we can easily change the configuration of this logger and change the Loglevel. So for instance when we don&#8217;t like any logging we can disable logging for this class either using a configuration file or do it directly from code like so:</p>
<pre class="brush:java">
Logger.getLogger("some.test").setLevel(Level.OFF);</pre>
<p>and the class will not log anymore.</p>
<p>Sometimes doing this in Nifty and using the name &#8220;de.lessvoid.nifty&#8221; for instance to shut off the logging refused to work. Some classes simply didn&#8217;t stop logging at all. What&#8217;s going on?</p>
<p>After a long headache we&#8217;ve finally found out!</p>
<p>Nifty used some special logger names for eventbus and inputevent logging. Both loggers used special names that did not relate to any class because there where several classes that would need to log those events. So a special name, like &#8220;NiftyEventBusLog&#8221; made sense for me.</p>
<p>In some places we had code like that:</p>
<pre class="brush:java">package some.test;

import java.util.logging.Logger;

public class Main {
  private static Logger differentLog = Logger.getLogger("SpecialLog");

  public static void main(final String[] args) {
    differentLog.info("test");
  }
}
</pre>
<p>I somehow expected the loggername in the log to be &#8220;SpecialLog&#8221; since it&#8217;s the name of the logger. But in fact we get something else:</p>
<pre class="brush:java">
01.04.2012 19:24:41 some.test.Main main
INFO: test
</pre>
<p>O_o</p>
<p>The information still shows &#8220;some.test.Main&#8221; since this is the class that actually logged!</p>
<p>If you now try to disable logging for this class, like we&#8217;ve seen above:</p>
<pre class="brush:java">
Logger.getLogger("some.test").setLevel(Level.OFF);</pre>
<p>YOU WOULD STILL SEE THE LINE IN THE LOG &#8211; even though you&#8217;ve disabled it (kinda) <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Of course to fix this you would need to disable the &#8220;SpecialLog&#8221; additionaly to &#8220;some.test.Main&#8221; but that&#8217;s pretty odd since you usually don&#8217;t know the exact names of all loggers beforehand.</p>
<p>So to make a long story short Nifty now (current git) removed all the special loggers and always only uses the logger with the name of the current class. When you now disable a logger you should be pretty sure that you really disable any output with that name <img src='http://nifty-gui.lessvoid.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>void</p>
<p><strong>EDIT</strong></p>
<p>I just realized that it would be very helpful to give you the actual logger names you need to disable when you still use Nifty 1.3.1:</p>
<ul>
<li>&#8220;NiftyInputEventHandlingLog&#8221;</li>
<li>&#8220;NiftyEventBusLog&#8221;</li>
<li>&#8220;NiftyImageManager&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/436/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Nifty 1.3.1 webstart demos online</title>
		<link>http://nifty-gui.lessvoid.com/archives/427</link>
		<comments>http://nifty-gui.lessvoid.com/archives/427#comments</comments>
		<pubDate>Sun, 15 Jan 2012 17:54:07 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[demo]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=427</guid>
		<description><![CDATA[In case you&#8217;ve missed the online demos with the latest Nifty 1.3.1 release (like Nifty user waltobc6) this might be of interest for you: Nifty Default Controls Example (1.3.1) Nifty Standard Examples (1.3.1) Have fun, void]]></description>
			<content:encoded><![CDATA[<p>In case you&#8217;ve missed the online demos with the latest Nifty 1.3.1 release (like Nifty user waltobc6) this might be of interest for you:</p>
<p><a href="http://nifty-gui.sourceforge.net/webstart/nifty-default-controls-examples-1.3.1.jnlp">Nifty Default Controls Example (1.3.1)</a></p>
<p><a href="http://nifty-gui.sourceforge.net/webstart/nifty-default-controls-examples-1.3.1.jnlp"><img src="http://nifty-gui.lessvoid.com/wp-content/2012/01/Bildschirmfoto-2012-01-15-um-18.36.41-300x238.png" alt="" title="Nifty Controls Demo 1.3.1" width="300" height="238" class="aligncenter size-medium wp-image-428" /></a></p>
<p><a href="http://nifty-gui.sourceforge.net/webstart/nifty-examples-1.3.1.jnlp">Nifty Standard Examples (1.3.1)</a></p>
<p><a href="http://nifty-gui.sourceforge.net/webstart/nifty-examples-1.3.1.jnlp"><img src="http://nifty-gui.lessvoid.com/wp-content/2012/01/Bildschirmfoto-2012-01-15-um-18.35.38-300x238.png" alt="" title="Nifty Demo 1.3.1" width="300" height="238" class="aligncenter size-medium wp-image-430" /></a></p>
<p>Have fun,<br />
void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/427/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>scm branch cleanup</title>
		<link>http://nifty-gui.lessvoid.com/archives/416</link>
		<comments>http://nifty-gui.lessvoid.com/archives/416#comments</comments>
		<pubDate>Sat, 14 Jan 2012 00:31:27 +0000</pubDate>
		<dc:creator>void</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nifty-gui.lessvoid.com/?p=416</guid>
		<description><![CDATA[So now that 1.3.1 is out of the way, we&#8217;ve cleaned up the branches in git. There are now two main development branches available: 1.3 The branch formerly known as 1.3.1. This branch will be the base for an eventual 1.3.2 release. Mostly bugfixes should go in there but maybe some improvements will find their [...]]]></description>
			<content:encoded><![CDATA[<p>So now that 1.3.1 is out of the way, we&#8217;ve cleaned up the branches in git.</p>
<p>There are now two main development branches available:</p>
<p><strong>1.3</strong><br />
The branch formerly known as 1.3.1. This branch will be the base for an eventual 1.3.2 release. Mostly bugfixes should go in there but maybe some improvements will find their way into this as well.</p>
<p><strong>master</strong><br />
The main branch and the base for any 1.4 development. This will be an unstable version (1.4.0-SNAPSHOT) for a while but all the new nifty things will be in there.</p>
<p>While speaking of 1.4 there is not yet a final plan for it. We&#8217;ll need to sort out all of the bug and feature requests first. Please feel free to suggest other things you&#8217;d like to see in the comments or on the forum.</p>
<p>Both branches are available at <a href="http://sourceforge.net/projects/nifty-gui/develop">sf.net</a> and at <a href="https://github.com/void256/nifty-gui">github</a>. Synchronizing both repos is a manual process at the moment but works pretty good thanks to git!</p>
<p>Ah and one final word about the git repository at sf.net: Unfortunately the sf.net &#8220;code / git&#8221; menu lists the wrong repository. I&#8217;ve talked to their tech support on IRC and this can&#8217;t be changed at the moment :/</p>
<p>The &#8220;develop&#8221; menu has the correct URL which is:</p>
<p><code>git clone git://nifty-gui.git.sourceforge.net/gitroot/nifty-gui/nifty</code></p>
<p>So the <strong>correct</strong> URL ends with &#8220;nifty&#8221; and <strong>not</strong> with &#8220;nifty-gui&#8221;! Sorry about this =)</p>
<p>void</p>
]]></content:encoded>
			<wfw:commentRss>http://nifty-gui.lessvoid.com/archives/416/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
