Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Pre-multiplied Alpha for drawing particles in one pass  (Read 6812 times)
0 Members and 1 Guest are viewing this topic.
Offline roland
« Posted 2012-08-19 04:31:21 »

Firstly, thanks to Orangy Tang for pointing this out to me.

Tips on optimising particle drawing (Thanks to davedes) can be found here: http://www.java-gaming.org/topics/storing-adding-drawing-particles/27126/msg/242110/view.html#msg242110

Here are some tutorials on pre-multiplied alpha:  Pointing
http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Premultiplied%20alpha]]
http://blog.rarepebble.com/111/premultiplied-alpha-in-opengl/
http://www.quasimondo.com/archives/000665.php

It doesn't seem too complicated but you also need to have the right textures, otherwise it's not going to work.
Firstly, in the code:

Rather than having two blend modes that we use for drawing particles:

Additive, for fire, etc:
1  
GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE);


And Normal(or Lerp) for smoke: (I use this blendmode for drawing everything else, it should be re-set after drawing the particles)
1  
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);





Have just one:
1  
GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);



Now, you have two different types of particles, smoke and fire. You need to keep track of these because they are drawn in slightly different ways.
Firstly setting the colour:

Additive(Fire):
1  
GL11.glColor4f(r*a,g*a,b*a,0);


Normal "Lerp" (Smoke)
1  
GL11.glColor4f(r*a,g*a,b*a,a);



The other part is the textures.

Additive textures must have a black background.
Normal/lerp textures have a transparent background.

Here is a sample additive texture for fire:

Here is a sample lerp texture for smoke:



If you use an additive texture with a transparent background you will get something like this(BAD):




Final results:



If I have any of this wrong, please correct me!

-roland
Offline philfrei
« Reply #1 - Posted 2012-08-19 05:57:16 »

Some nice tips.

I happen to be writing a little tool for combining textures at the moment, and was just figuring out the importance of the distinction of addition vs interpolation. I implemented interpolation, but am now planning to give the addition option as well. So far, I'm able to do a simple scaling and translating in Simplex noise, and interpolate three such screens together. It's gui driven, and generates a text line for the Java Simplex 2D call that can be copied-and-pasted into a procedural routine.

"It's after the end of the world! Don't you know that yet?"
Offline roland
« Reply #2 - Posted 2012-08-19 06:07:39 »

Some nice tips.

I happen to be writing a little tool for combining textures at the moment, and was just figuring out the importance of the distinction of addition vs interpolation. I implemented interpolation, but am now planning to give the addition option as well. So far, I'm able to do a simple scaling and translating in Simplex noise, and interpolate three such screens together. It's gui driven, and generates a text line for the Java Simplex 2D call that can be copied-and-pasted into a procedural routine.
Thanks  Smiley that sounds interesting, any chance of a screenshot or something?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline philfrei
« Reply #3 - Posted 2012-08-19 23:43:11 »

Quote
Thanks  Smiley that sounds interesting, any chance of a screenshot or something?



I just wanted to make something to help me get a better handle on making textures, and am only starting to realize how much is involved to make a tool like this useful!

One thing I didn't realize until I just this hour, (when I made the display boxes double in size along the horizontal) is that the way I did scaling is kind of dubious. Maybe I should define my scaling in terms of a set number of pixels rather than as a proportion of the display area? But given that screen resolutions vary a lot, even that is kind of dubious as a measure. So, producing the equations as I do in the text fields below the sliders (they don't quite fit in the JTextFields visually) is maybe not so useful. Also, I suspect people don't use a translation very often.

Right now it is monochromatic and alpha isn't involved. Your post and links are very helpful in working out how to handle this once I'm ready to try including color and transparency.

Going back to the idea of adding vs lerp -- I think I still want to try that out. Right now, I am just taking a weighted average for the displayed values. But I was thinking I wanted to do something like this: specify a mapping from the noise function to a number range and then add the results in. For example, have one Simplex output mapped to values from -16 to 16, and ADD these in to get the final color value. It doesn't seem to me that there is a simple way to get the equivalent mathematical results using lerp. True?

I haven't looked around to see if there are already tools that do these graphics manipulations with the goal of creating procedural code. Nor do I know if there is much interest in such. Most people would just use an artist to get design and create the needed tiles/textures, I assume.

"It's after the end of the world! Don't you know that yet?"
Offline roland
« Reply #4 - Posted 2012-08-20 08:18:29 »

Quote
Thanks  Smiley that sounds interesting, any chance of a screenshot or something?



I just wanted to make something to help me get a better handle on making textures, and am only starting to realize how much is involved to make a tool like this useful!

One thing I didn't realize until I just this hour, (when I made the display boxes double in size along the horizontal) is that the way I did scaling is kind of dubious. Maybe I should define my scaling in terms of a set number of pixels rather than as a proportion of the display area? But given that screen resolutions vary a lot, even that is kind of dubious as a measure. So, producing the equations as I do in the text fields below the sliders (they don't quite fit in the JTextFields visually) is maybe not so useful. Also, I suspect people don't use a translation very often.

Right now it is monochromatic and alpha isn't involved. Your post and links are very helpful in working out how to handle this once I'm ready to try including color and transparency.

Going back to the idea of adding vs lerp -- I think I still want to try that out. Right now, I am just taking a weighted average for the displayed values. But I was thinking I wanted to do something like this: specify a mapping from the noise function to a number range and then add the results in. For example, have one Simplex output mapped to values from -16 to 16, and ADD these in to get the final color value. It doesn't seem to me that there is a simple way to get the equivalent mathematical results using lerp. True?

I haven't looked around to see if there are already tools that do these graphics manipulations with the goal of creating procedural code. Nor do I know if there is much interest in such. Most people would just use an artist to get design and create the needed tiles/textures, I assume.

That's a good question. I think you should go with scaling in terms of 1.2x or something(So how it is now), but keep the image sizes the same and their dimensions correct (so they aren't stretched 2:1 sideways), and use horizontal+vertical scrollbars on each texture.

Is the mapping for each individual pixel? Could you make the number (-16 -> 16) map to a RGB colour using another algorithm such as
r = ((i +X * SOME_BIG_NUMBER) % SOME_SMALLER_NUMBER)/SOME_SMALLER_NUMBER
g = ((i+Y * SOME_BIG_NUMBER2) % SOME_SMALLER_NUMBER2)/SOME_SMALLER_NUMBER2
b = ((i+Z * SOME_BIG_NUMBER3) % SOME_SMALLER_NUMBER3)/SOME_SMALLER_NUMBER3

where X Y Z are different numbers. I still don't really know what your doing so I may have just written something completely not what you want. If that's the case, just ignore it  Grin

Sorry I don't know much about noise functions, nor much about textures apart from the very basics and a few different types of blend modes. If you manage to make a good procedural texture maker that would be awesome! Right now I use Texture Maker Professional v3.0.3  (http://www.texturemaker.com/screenshots.php) which has a lot of procedural options but its hard to make good ones (atleast for me it is)


I'm glad my code will help you out later Smiley This should be a more well known topic I think! It's important and I hadn't even heard about it until a few days ago Cranky
Offline nsigma
« Reply #5 - Posted 2012-08-20 09:07:46 »

Additive textures must have a black background.
Normal/lerp textures have a transparent background.
...
If you use an additive texture with a transparent background you will get something like this(BAD):

Isn't that because your textures themselves should be pre-multiplied?

Other than that, great post!  Smiley  I'm a huge fan of pre-multiplied alpha in general - it makes so many things easier.  Hadn't thought of the additive blending 'hack' though.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #6 - Posted 2012-08-20 09:15:07 »

Critical feature of using premult alpha: you must premultiply the alpha in all your graphics before you upload them to OpenGL! I do this at compile time but if you're lazy you can do it at runtime:
1  
2  
   BufferedImage bi = ImageIO.read(inputFile);
   bi.coerceData(true); // This forces the alpha to be premultiplied, if it isn't, and does nothing, if it already is


Cas Smiley

Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #7 - Posted 2012-08-20 23:20:45 »

Could someone explain what pre-multiplied alpha is exactly? Google isn't exactly helping with its big words.

Offline BurntPizza
« Reply #8 - Posted 2012-08-20 23:39:40 »

Could someone explain what pre-multiplied alpha is exactly? Google isn't exactly helping with its big words.

It's precisely what it sounds like: the rgb colors are multiplied with the alpha channel before anything is drawn, instead of being blended in while stuff is being drawn.

So, say if you drew a  transparent red [1.0f, 0.0f, 0.0f, 0.5f] (that's rgba) square, then what would end up on screen is the same as if you drew a square with the opaque color [.5f, 0.0f, 0.0f 1.0f]. Notice the 1.0f * 0.5f = 0.5f, hence 'pre-multiplication.'

This is nice for large batch rendering because you can simulate blend modes just by setting the current color to draw with, instead of using glBlendFunc().
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #9 - Posted 2012-08-20 23:58:44 »

That's what all other websites explain too....but I still don't get the point. What do you mean 'simulate blend modes'? Also other sources say that you still keep the 0.5f alpha after you pre-multiply, which confused me further Tongue

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline BurntPizza
« Reply #10 - Posted 2012-08-21 00:11:39 »

Maybe someone else has a better explanation, but as I understand, it's just another way of compositing colors, you don't need to use it, or understand why it exists, nothing, just that it is an alternative method for (in the case of OpenGL) glBlendFunc(), as well as a non-implementation specific method of compositing, so if the language/api/whatever you are using doesn't support anything like glBlendFunc you can use this. That is what I know.
Offline philfrei
« Reply #11 - Posted 2012-08-21 00:57:36 »

@ra4king - I'm still trying to figure this out, too!

Two scenarios:
(a) opaque black background, draw [1.0, 0, 0, 0.5] red on it.
I can see where the result would be [0.5, 0, 0] to the eye. Same as drawing [0.5, 0, 0, 1.0] over this background.

(b) opaque white background, draw [1.0, 0, 0, 0.5] red on it.
Wouldn't the result be [1.0, 0.5, 0.5] to the eye? This is NOT the same as drawing [0.5, 0, 0, 1.0] over this background.

Huh

Maybe this has to do with there being different forms of blending depending upon the background, which the OP talks about.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
   public void paintComponent(Graphics g)
   {
      Graphics2D g2 = (Graphics2D) g;
     
      // refresh screen
      g2.setBackground(new Color(255, 255, 255, 255));
      g2.clearRect(0, 0, width/2, height);
     
      g2.setPaint(new Color(0, 0, 0, 255));
      g2.fillRect(width/2, 0, width/2, height);
     
      g2.setPaint(new Color(1.0f, 0f, 0f, 0.5f));
      g2.fillRect(100, 50, 100, 100);
      g2.fillRect(400, 50, 100, 100);
     
      g2.setPaint(new Color(0.5f, 0f, 0f, 1.0f));
      g2.fillRect(100, 200, 100, 100);
      g2.fillRect(400, 200, 100, 100);
   }


"It's after the end of the world! Don't you know that yet?"
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #12 - Posted 2012-08-21 03:16:36 »

Shocked

Offline nsigma
« Reply #13 - Posted 2012-08-21 08:41:29 »

@philfrei - In what way is that unexpected?  In the top case the colour is still half transparent, therefore on the white background 50% of the white is added and makes it look paler.  On the black, 50% of nothing is added so looks identical.  You can't ignore the alpha channel in pre-multiplied - as you've found, comparing it with an opaque colour that happens to have the same colour value is pointless (and confusing!  Cheesy )

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline delt0r

JGO Knight


Medals: 27
Exp: 18 years


Computers can do that?


« Reply #14 - Posted 2012-08-21 08:59:30 »

@ra4king Since you don't seem to afraid of math...

If i paint the colour (r,g,b,a) onto a background colour of (r',g',b') the resultant colour is (ra+r'(1-a),ga+g'(1-a),ba+b'(1-a)) in standard blend mode.

This is the same as adding (ra,ga,ba) to (r'(1-a),g'(1-a),b'(1-a)).

So we have the blend mode with ONE & ONE_MINUS_SRC_ALPHA, and we need to multiply our painting colour by alpha first (pre multiply) to get mathematically the same result as with the blend mode SRC_ALPHA, ONE_MINUS_SRC_ALPHA.

Also it should be clear why we need to keep the alpha value.

I have no special talents. I am only passionately curious.--Albert Einstein
Offline roland
« Reply #15 - Posted 2012-08-21 09:12:57 »

Critical feature of using premult alpha: you must premultiply the alpha in all your graphics before you upload them to OpenGL! I do this at compile time but if you're lazy you can do it at runtime:
1  
2  
   BufferedImage bi = ImageIO.read(inputFile);
   bi.coerceData(true); // This forces the alpha to be premultiplied, if it isn't, and does nothing, if it already is


Cas Smiley
Shocked thanks! so what are the image backgrounds supposed to look like? (eg. black or transparent or it doesn't matter?)
Offline Spasi
« Reply #16 - Posted 2012-08-21 10:40:04 »

In a shader-based renderer another option would be doing the pre-multiplication in the fragment shader:

1  
2  
3  
vec4 color = texture2D(...);
... // do lighting/whatever
gl_FragColor = vec4(color.rgb * color.a, color.a);

The computation cost is minimal and you don't waste time with pre-processing textures (either offline or at runtime). Also, it avoids the posterization problem described in the OP's third link, for a small quality gain.
Offline theagentd
« Reply #17 - Posted 2012-08-21 12:46:39 »

In a shader-based renderer another option would be doing the pre-multiplication in the fragment shader:

1  
2  
3  
vec4 color = texture2D(...);
... // do lighting/whatever
gl_FragColor = vec4(color.rgb * color.a, color.a);

The computation cost is minimal and you don't waste time with pre-processing textures (either offline or at runtime). Also, it avoids the posterization problem described in the OP's third link, for a small quality gain.
That would defeat the purpose of it, if I've understood this right. It's at least partly meant to solve bleeding when using bilinear filtering. By "premultiplying" the already interpolated color, you're not achieving this.

Myomyomyo.
Offline Spasi
« Reply #18 - Posted 2012-08-21 13:30:10 »

That would defeat the purpose of it, if I've understood this right. It's at least partly meant to solve bleeding when using bilinear filtering. By "premultiplying" the already interpolated color, you're not achieving this.

That's correct, if the texture's getting scaled, you need premultiplied values before sampling. In most 2D games that's not an issue however.
Offline theagentd
« Reply #19 - Posted 2012-08-21 18:52:14 »

That would defeat the purpose of it, if I've understood this right. It's at least partly meant to solve bleeding when using bilinear filtering. By "premultiplying" the already interpolated color, you're not achieving this.

That's correct, if the texture's getting scaled, you need premultiplied values before sampling. In most 2D games that's not an issue however.
Then what's the whole point of it? You're emulating blending that's done pretty much for free by dedicated hardware in a shader / with fixed functionality.

Myomyomyo.
Offline Spasi
« Reply #20 - Posted 2012-08-21 19:04:15 »

It's not blending, it's doing the premultiplication on the fly, rather than offline or at texture creation time. Anyway, it can only be applied in 2D rendering (no magnification/minification), so it's not a general solution.
Offline ra4king

JGO Kernel


Medals: 350
Projects: 3
Exp: 5 years


I'm the King!


« Reply #21 - Posted 2012-08-21 21:49:49 »

@ra4king Since you don't seem to afraid of math...

If i paint the colour (r,g,b,a) onto a background colour of (r',g',b') the resultant colour is (ra+r'(1-a),ga+g'(1-a),ba+b'(1-a)) in standard blend mode.

This is the same as adding (ra,ga,ba) to (r'(1-a),g'(1-a),b'(1-a)).

So we have the blend mode with ONE & ONE_MINUS_SRC_ALPHA, and we need to multiply our painting colour by alpha first (pre multiply) to get mathematically the same result as with the blend mode SRC_ALPHA, ONE_MINUS_SRC_ALPHA.

Also it should be clear why we need to keep the alpha value.
Shocked *hugs delt0r* that explains a lot! especially the whole 'ONE'/'ONE_MINUS_SRC_ALPHA', since I never understood that stuff either Cheesy

Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #22 - Posted 2012-08-21 23:05:00 »

Always do the premultiplication on the source data before it gets to the shader, i.e. it needs to be that way when you upload it to GL. A lot of 2D games do scaling and layering and this is only really solved by doing it this way. And of course you don't need to use any fancy shader for it to work.

Also you should realise that you can and need to use premultiplied alpha on all other rendering as well in your 2D graphics effects. This means if you were going to use the totally wrong and busted method of:
1  
2  
3  
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // NEVER USE THIS
glColor4f(1.0f, 0.5f, 0.25f, 0.5f);
// render some lines or a rectangle or something here...

you actually need to premultiply your colour there, too:
1  
2  
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.5f, 0.25f, 0.125f, 0.5f);


I can't stress highly enough how WRONG using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) is. NEVER USE IT. Just about every example ever on the internet and in books uses this blend function, and it is wrong wrong wrong.

Cas Smiley

Offline Cero
« Reply #23 - Posted 2012-08-21 23:35:32 »

I can't stress highly enough how WRONG using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) is. NEVER USE IT. Just about every example ever on the internet and in books uses this blend function, and it is wrong wrong wrong.

but I use textures with transparent background using PNGs...

Offline nsigma
« Reply #24 - Posted 2012-08-22 08:47:48 »

@princec - I regret I hath but one medal to lay down ...  Smiley

Absolutely agree, always use pre-multiplied alpha.  I've said this a few times on here myself, and it's usually met with mild bemusement.  I read a great article a few years back that outlined all the various pitfalls, but can't seem to find it any longer (though my old mate Google brings up a few others that aren't as comprehensive).  If you know of any good articles on this, please share links - I guess the ins and outs of this would make a useful wiki article.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #25 - Posted 2012-08-22 09:33:28 »

Embarrassingly I only found out about all this myself about 2 years ago. I think the link I was reading at the time was this blog on MSDN by Shawn Hargreaves.

Cas Smiley

Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #26 - Posted 2012-08-22 09:34:32 »

I have to admit that other than the niche case of doing regular blending and additive blending in one image I don't really see the need to use pre-multiplied alpha everywhere. You lose flexibility to do some of the more interesting alpha tricks at runtime and you probably have to add some kind of extra build step. Plus it confuses the heck out of artists, so you either get lower quality art or you have to keep running around after them fixing stuff because they made their art wrong.

Maybe someone could have a proper stab at explaining the actual concrete benefits to using pre-multiplied everywhere?

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #27 - Posted 2012-08-22 09:41:56 »

The reasons given in the linked article:
Quote
Why premultiplied r0x0rz

Premultiplied alpha is better than conventional blending for several reasons:

It works properly when filtering alpha cutouts (see below)
It works properly when doing image composition (stay tuned for my next post)
It is a superset of both conventional and additive blending. If you set alpha to zero while RGB is non zero, you get an additive blend. This can be handy for particle systems that want to smoothly transition from additive glowing sparks to dark pieces of soot as the particles age.
It plays nice with DXT compression, which only supports transparent pixels with an RGB of zero.

Image composition and filtering were what did it for me. It made an instantly noticeable improvement in graphics that had been bugging me for years - when we composited several sprites over each other they always seemed to end up with a greyish border around them all eventually. Then I discover it's because we'd been doing it wrong.

There's absolutely no reason not to switch to the correct method, right now, today. The "old" method is simply wrong, and always has been. As you're applying premultiplication at texture upload time the artist never has to know about it either - they carry on working as per normal.

Cas Smiley

Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #28 - Posted 2012-08-22 09:56:55 »

1. It works properly when filtering alpha cutouts (see below)
2. It works properly when doing image composition (stay tuned for my next post)
3. It is a superset of both conventional and additive blending. If you set alpha to zero while RGB is non zero, you get an additive blend. This can be handy for particle systems that want to smoothly transition from additive glowing sparks to dark pieces of soot as the particles age.
4. It plays nice with DXT compression, which only supports transparent pixels with an RGB of zero.

I always solve 1 + 2 by 'bleeding' the colour of sprites for any non-alpha-zero texels. That produces more sane data (in my head) as the alpha and colour data are still orthogonal. I've also never seen a proper breakdown of 'it's more correct' with actual observable differences that can't be solved by bleeding the rgb channels. Everywhere always just does some hand-wavy 'it's just better stupid'.

4 - I never use DXT because I hate the artifacts.

Which only leaves 3 - which is a useful trick but comes at the expense of being able to do other tricks and confuses artists. So as far as I'm concerned it's just a matter of preference.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #29 - Posted 2012-08-22 09:57:51 »

I'm really not sure why you're bringing artists into the equation... Chaz never even knew I'd made the change. Everything just suddenly looked better one day.

Cas Smiley

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (38 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (65 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!