Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (491)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (556)
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  
  VBO  (Read 6009 times)
0 Members and 1 Guest are viewing this topic.
Offline StumpyStrust
« Posted 2012-09-15 08:39:49 »

 Angry So I am really mad right now. Have been working for 2 days on getting a dynamic vbo to work...basically a sprite batcher of sorts and can't get anything right. I have read probably every tutorial that you can find by googling VBO, dynamic VBO, interleaved VBO.....I even have looked through libgdx's source for enlightenment.

Right now I have stuff actually showing up on screen without all sorts of black crashes. I am trying to use an interleaved VBO with Vertex Color Texture. Vertex is 2f Color is 4f, and Texture is 2f.

I have no idea if I am doing anything right so here is what I have. Tell me what is horribly wrong without being too rude.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
vctBuffer = BufferUtils.createFloatBuffer(vert.size());
      vctBuffer.put(vert.shrink());
      vctBuffer.flip();
       
       
        int stride = (2+4+2)*4;
      bufferData(vctPointer, vctBuffer);
      Util.checkGLError();
      int offset = 0 * 4;
        GL11.glVertexPointer(2, GL11.GL_FLOAT,stride, offset);
        Util.checkGLError();
        offset = 4 * 4;
        GL11.glColorPointer(4, GL11.GL_FLOAT, stride, offset);
        Util.checkGLError();
        offset = (4+2) * 4;
        GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, offset);
        Util.checkGLError();
       
        Util.checkGLError();
       
        Util.checkGLError();
        GL11.glDrawArrays(GL11.GL_QUADS, 0, draws*4);

       
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
        GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
       draws = 0;
       index = 0;
       vctBuffer.clear();
       GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);


I am got a version working using vertex arrays that could get 40k sprites before fps drops but I want closer to 50k stable 150k drop fps. I know about fill rate limit and I am testing with very small sprites, 4 pixels.

The vert.shrink() stuff is basically my custom array class that grows if it is too small. The size() returns the number of indexs used and the shrink() returns and float[] of the indexes.

If any one could also explain how to use the drawElements command I would also be very happy. I know what it does and why it can be faster but just don't get how to create the indices stuff. I am really put out at how ridiculously hard this is as there are very few tutorials on this stuff that go further then drawing/rendering a static cube/triangle.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2012-09-15 09:35:05 »

Maybe this helps?

http://www.java-gaming.org/topics/introduction-to-vertex-arrays-and-vertex-buffer-objects-opengl/24272/view.html

Sure, this tutorial handles only drawing a triangle, in various ways, but I expect you can move on from there pretty quickly, as you're working from a base that works.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline theagentd
« Reply #2 - Posted 2012-09-15 12:20:25 »

I have no idea if I am doing anything right so here is what I have. Tell me what is horribly wrong without being too rude.

If your code works (your first paragraph implied that it wasn't), you've got basic VBOs working fine. I can give you some performance tips though:

 - Using floats for your color data is waaay more precision than you need. Just go with 4 bytes for RGBA. Even if you don't have alpha, include it anyway to keep the data a little better aligned.
 - You could also use (unsigned) shorts for texture coordinates. Shorts have enough precision by far (up to 65536x65536 textures, which aren't even supported by hardware), so they'll be fine with tiled images too.
 - Don't use glBufferData(). Instead, use glMapBuffer(), which gets you a ByteBuffer. Either fill this ByteBuffer directly with your sprite data, or just copy the data you have in vctBuffer to it and then unmap it. The first is of course the fastest but a little less flexible, especially if you need to dynamically expand the buffer, so go for the second one since it's easily implemented (I can post code).

Simply minimizing the data will reduce it to 16 bytes per vertex, down from 32 bytes. You're currently transferring (32 bytes * 4 vertices * 50 000 sprites * 60 FPS) = 366 MBs of data per second to your graphics card. This is probably your main bottleneck, so focus on that. I can help you with glMapBuffer() after you get that working, since removing glBufferData() avoids an extra copy operation of the data to the driver.


If any one could also explain how to use the drawElements command I would also be very happy. I know what it does and why it can be faster but just don't get how to create the indices stuff. I am really put out at how ridiculously hard this is as there are very few tutorials on this stuff that go further then drawing/rendering a static cube/triangle.

To use glDrawElements() you need (at least) two VBOs, one (or more) with vertex data and one with indices. Using the indices, glDrawElements() creates primitives from the vertices supplied. This is very useful for 3D models, since the same vertices can be reused for 4+ triangles, and the vertex matrix transformations etc are only performed once. Sprites are just a quad made of four vertices, and nothing is shared between sprites. The only time that sprites can benefit from indices is if you can't use GL_QUADS (= on Android or on OpenGL 3+ since it was deprecated). In that case you can create the four vertices just like you do now for GL_QUADS, then create indices to create two triangles to form a quad from 4 vertices and 3*2=6 indices. Without indices, you'd need 6 vertices to create those two triangles, since you'd have to duplicate the 2 shared vertices. Assuming the above 16 bytes per vertex:

With indices: (16 bytes * 4 vertices) + (6 short indices) = 64 + 12 = 76 bytes.
Without indices: 16 bytes * 6 indices = 96 bytes + 33.3% less vertex processing.

EDIT: I forgot another limitation: 32-bit indices are very slow, so in practice you're limited to 16-bit indices. That gives you a maximum of 65 536 possible indices, meaning that you're limited to drawing 16 384 sprites per batch. In practice that's rarely a problem for sprites since you usually need change some OpenGL state for different sprites, in which case you can't batch together many of them anyway.

TL;DR: I don't see how using indices will improve anything for you.

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StumpyStrust
« Reply #3 - Posted 2012-09-15 17:18:29 »

I have no idea if I am doing anything right so here is what I have. Tell me what is horribly wrong without being too rude.

If your code works (your first paragraph implied that it wasn't), you've got basic VBOs working fine. I can give you some performance tips though:


It wasn't working but I got it working except I think the offsets are all wrong because it looks all funky. I read everywhere the interleaving data can give a performance boost as does drawElements. If I use different data types I will need to split things up right?

So to use drawElements I need another VBO full of the indices that will be used. What are the indices? 0 1 2 2 3 0 Like you would with glbegin and end? I may not use it I just want to know how.

Revin I have read that over and over and the problem with it is that every thing is very basic. That is probably the one that made most sense to me and helped a lot.

I know that inevitably I will be fillrate limited so any tips would also help.

Offline theagentd
« Reply #4 - Posted 2012-09-15 22:12:43 »

You do not have to split things even if you use different data types. The easiest way is to just use a ByteBuffer instead of a FloatBuffer and use the put***() methods (putFloat(), putShort(), put() <--- last one is for bytes). You can then do everything as usual, but the stride and offsets will be different.

Your current stride and offsets are looking good. Could you post more code or a screenshot if you still have problems?


You almost certainly won't be fill-rate limited unless your sprites are very big. Your main bottleneck will most likely be your CPU and your RAM speed. I have a particle test which draws colored GL_POINTS particles using VBOs, glMapBuffer() and even MappedObject to minimize the amount of data that has to be handled and uploaded by the CPU, yet I am still easily bottlenecked by my CPU. Furthermore my points only take up 12 bytes since I don't have any texture coordinates for them.

This little particle engine can handle 700 000 particles at 60 FPS using only one CPU core with a point size of 1 (= exactly one pixel covered per particle). That's only 700 000 pixels filled per frame. However, since I am CPU limited, I can increase the point size without any FPS drop up to 13 and still stay fixed at 60 FPS. This is a fillrate of 700 000 * 13 * 13 = 118 300 000 pixels per frame. Yes, that's 118 MILLION pixels per frame, or around 7.1 billion pixels per second (60 FPS). My GPU, equivalent to an NVidia GTX 275, has a theoretical pixel fillrate of 16.1 billion pixels per second. A brand new high-end card has twice that performance.

The thing is, I'm not rendering quads. I'm rendering points, so each particle comes from only a single vertex. You have 4 vertices per quad. My program is CPU limited, so having 4 times as much data to create quads that fill the same number of pixels is going to give 4 times as much CPU work while the fillrate requirements stay the same. Since I'd only be able pump out 1/4th as many particles as before with quads, I could double the particle size (= 4x the pixel area) and still not be GPU limited. Add that I am using MappedObjects (around a 40% performance boost) and glMapBuffer() (around 40% more) and you quickly realize that with quads you'd be able to handle around 100 000 sprites due to the increased data size and not using glMapBuffer(). MappedObjects can't really be used well for sprites... And sure enough, rendering only 100 000 particles allow me to buff up the point size to 42.

Don't get me wrong here! I'm not saying that your code or quads are bad! Quads are a lot more flexible (texturing, etc.). I'm just saying that simply handling the data takes a lot of CPU processing power and that GPUs are really fast. Rendering 100 000 sprites without any FPS drop is definitely attainable, but you won't be fillrate limited unless your sprites are larger than around 40x40 pixels.

100 000 particles covering 42x42 pixels each (FPS drop due to print screen):

Myomyomyo.
Offline StumpyStrust
« Reply #5 - Posted 2012-09-16 00:48:49 »

I got it working properly now as it turns out. So get a byte buffer from mapBuffers and put everything in that and still use offsets hmmm...I will work on this and see what I get.

Right now I can get 50k with 28-30fps. Really sad I know but I will get there I hope.

I want some particles to be 256*256 max. Maybe higher. I want it to be stable at 50k with no big performance hits but then start to slow down as it gets to 100-150k

I always thought I was fill rate limited hmmm...

Anyways ty for the help. Very much appreciated.

Offline StumpyStrust
« Reply #6 - Posted 2012-09-16 01:32:23 »

I keep getting null pointers with this

1  
2  
3  
4  
5  
6  
7  
8  
9  
   public static ByteBuffer bufferData(int id, ByteBuffer buff) {
        if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
           Util.checkGLError();
          ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
          Util.checkGLError();
          return ARBVertexBufferObject.glMapBufferARB(GL15.GL_ARRAY_BUFFER, GL15.GL_DYNAMIC_DRAW, buff);
        }
        return null;
      }



The problem with all of this is that any googling gives non-lwjgl opengl which has a different api then lwjgl and lwjgl as no examples that I can find.

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #7 - Posted 2012-09-16 02:06:58 »

Where exactly do you get a NullPointerException?

Offline StumpyStrust
« Reply #8 - Posted 2012-09-16 05:04:41 »

I get it on the return statement

Weird, because using the exact same code in my first opengl particle thing, which that is just fixed function, works.

I think I need to scrap this whole thing and restart as I must be doing something horribly wrong.

Offline ra4king

JGO Kernel


Medals: 345
Projects: 3
Exp: 5 years


I'm the King!


« Reply #9 - Posted 2012-09-16 06:21:50 »

null is returned because that extension isn't supported then...?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StumpyStrust
« Reply #10 - Posted 2012-09-16 07:31:21 »

No that is what the if check does.

It works because as I said on a different project is gave me the bytebuffer.

According to the docs, it will return null if it cant find a space for the buffer I think.

Hehe this is all after hundereds of unexplained crashes and VM crashs. You know "send error to windoes?" and "VM crash an error log was created"

I guess this really is not as trivial as all the tutorial make it out to be.

Offline theagentd
« Reply #11 - Posted 2012-09-16 13:03:20 »

glMapBuffer() allows you to map parts of the buffer's data to a ByteBuffer which it returns. However, to be able to map it you also need to create the VBO's data buffer. Basically, you need a glBufferData(int target, long data_size, int usage) call to initialize the buffer's data to the given capacity, and then map it. It returns null because there's nothing to map yet.

There's no problem with recreating the buffer's data each frame. It's actually preferred in most case, since mapping the buffer may cause a stall if the old data is still needed somewhere. Recreating the buffer's data each frame makes sure that can't happen, since the driver can just store the old data until it's no longer needed.

EDIT: Here's a test program to demonstrate VBOs with glMapBuffer(): http://www.java-gaming.org/?action=pastebin&id=257

Myomyomyo.
Offline StumpyStrust
« Reply #12 - Posted 2012-09-18 06:20:45 »

Sadly, the test program just shows some really messed up screen of random colors. Is that what is suppose to happen?

And I switched to mapBuffers with no performance gain by following that code. ;/

Online princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #13 - Posted 2012-09-18 08:11:22 »

You won't see a perf. gain from glMapBuffer() until you're doing rather a lot of rendering and state changing. FWIW it took me about 60 hours to get this all working right Smiley You might want to take a look at the DefaultSpriteRenderer class in the Revenge of the Titans source code (and a bit of a mosey around in general in there). I think I've nailed the absolute optimum set-up there in so far as asynchronous rendering and Java computation goes. The only improvement I could make is to utilise geometry shaders and move most of that Java code into the driver but that excludes most systems in the wild.

Cas Smiley

Offline StumpyStrust
« Reply #14 - Posted 2012-09-18 08:34:55 »

What is your current performance.

from 1k sprites to 10k, 25k, 50k 100k, 500k.


Want to know if I am asking for too much.

Online princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #15 - Posted 2012-09-18 08:44:18 »

Totally varies depending on the sprites you're drawing, the fillrate of the card, and the power of your CPU.

I can draw just a 20,000 sprites at 60fps on 1920x1200 if they're all transparent and moderately large (say 64x64 ish). I say draw but I'm also including animation logic that's running in my little sprite benchmark. Whereas if the sprites are all generally quite small like in Revenge of the Titans and some of them are opaque I can draw few thousand more. I'm on a 2.6Ghz i7 with Nvidia GTX 280 running Java 7 server with 2-tiered compilation.

Make no mistake, a couple of thousand sprites in a single video frame is a lot of sprites!

<edit> Sorry - got my numbers screwy - should be factor of 10 more sprites!

Cas Smiley

Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #16 - Posted 2012-09-19 20:19:31 »

</edit>

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Online princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #17 - Posted 2012-09-19 21:04:30 »

Hm?

Cas Smiley

Offline StumpyStrust
« Reply #18 - Posted 2012-09-19 22:17:11 »

200k??? O.o I keep thinking I am doing something wrong.

Libgdx's spritebatcher on my comp is about 10-13 fps fast then my spritebatcher.

Libgdx gets 42-44 fps on my comp at 40k alpha blended 14 pixel sprites. Everything the same and I get 30-31

i5 2.5gh with the turbo boost like 2.7-2.8 and well...meh laptop only uses the integrated chip ever.

On my desk top which is quad core 2.6 and geforce250 I get maybe 10k more sprites so I think I need to use more gpu.

I guess I should not be complaining about performance but still.... Angry

Edit:
hehe java 2d using opaque sprites and volatile images, I get 20-22 fps at 40k sprites.

Online princec

JGO Kernel


Medals: 369
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #19 - Posted 2012-09-19 22:47:57 »

Bah my edit is confusing Smiley No I mean, 20k sprites. 20k is good for 60fps on good hardware.

Cas Smiley

Offline StumpyStrust
« Reply #20 - Posted 2012-09-21 22:24:07 »

Well I figured out what was the slow down.

it was filling the arrays with the damn data.

I could call drawArrays/Elements 4-5 times and no fps drop...hmmm

Basically, it is better to fill an array[] and then use put(array[]) to put it into the buffer.

Using a dynamic vertex array version of my spritebatcher I can now get 75k at 66fps and this is with everything being floats. I am not fillrate limited woot.

The drawing is only 20fps drop, the updating and pushing into arrays is the slow part.

Oh I followed libgdx's code where you don't have one huge array/vbo of all data but instead send everything in chunks. I think 1-2k texture quads is optimal. Getting larger only slows things down.

Offline theagentd
« Reply #21 - Posted 2012-09-22 00:41:37 »

it was filling the arrays with the damn data.

I know...  Clueless
Your main bottleneck will most likely be your CPU and your RAM speed.

Myomyomyo.
Offline StumpyStrust
« Reply #22 - Posted 2012-09-22 03:24:46 »

So quick little bench mark for my spritebatch is basically a rehash of my spacemaker prog but now you can get lots of particles looking all cool.

http://www.mediafire.com/?gv1ng4l7uz96m3d

Screen



Click around and have fun

right now I can get 50k with physics going at 60fps

bout 70k with no physics at 60fps

So tell me what you guys are getting.

Online Phased
« Reply #23 - Posted 2012-09-22 03:43:41 »

50k with physics at 60 fps

38 - 40 fps - 70k with physics
40 fps with 70k no physics

100k sprites - im staying pretty much at 30 fps

200k sprites - 15 fps
Offline StumpyStrust
« Reply #24 - Posted 2012-09-22 04:02:52 »

What are you system specs?

The drop in fps should be much higher when you do physics. 10-20 My guess is that your cpu can do more but gpu is fill rate limited.

Just added delta timing which makes thing much smoother

Can actually do 120k at 35fps with physics.


Online Phased
« Reply #25 - Posted 2012-09-22 04:06:44 »

Graphics Card: NVIDIA Geforce GTS 250 (1gb)
ram: 12gb DDR3 if I remember right
CPU: Processor   Intel(R) Core(TM)2 Quad CPU    Q9400  @ 2.66GHz, 2667 Mhz, 4 Core(s), 4 Logical Processor(s)
Online Phased
« Reply #26 - Posted 2012-09-22 04:17:00 »

Just relised, that clicking actually changed stuff lol, im stupid, heres the new list:

200k sprites - 15 fps (no clicking around)
200k sprites - 11 - 13 fps (clicking)

120k sprites - 25 - 27 fps (no clicking)
120k sprites - 20 - 21 (clicking)

100k sprites - 30 fps (no clicking)
100k sprites - 25 fps (clicking)

50k sprites - 60 fps (no clicking)
50k sprites - 51 fps (clicking)

by clicking, Im constantly clicking around, soon as i stop clicking for a second or 2, it jumps straight back up to what its going at before the clicking.

and after finally working out about the clicking, I got to say, that is awesome, I'm trying to learn VBO's slowly, but still  kinda hard lol, Making a game for my school project, and Iv hardly even started to make the game, and I have probably enough code to get full marks in the programming side of it lol. Still got 1 year or so left to make it, (have not even received the assignment sheet lol). but good luck in what ever your trying to make!

P.S not sure if this is intended but, I just left the program open while typing out those 2 paragraphs, and it says Sprites: 0 , do the sprites have a certain life time? or is that a bug?
Offline StumpyStrust
« Reply #27 - Posted 2012-09-22 05:08:58 »

Yeah the sprites actually slowly fade out to test alpha stuff.

Clicking causes the particle to move towards the mouse via physics.

This is actually not using vbos just vertex arrays. The one I made using vbos was bottle necked. I think I can optimize it so it is fast then this but the main drop is not the number but filling up an array with all the vertices.

Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #28 - Posted 2012-09-22 15:51:28 »

</edit>
Hm?

Cas Smiley

One useless comment on closing the <edit>-tag Tongue
Yeah... seems like I'm not that good in making jokes...  persecutioncomplex  Undecided

EDIT: Okey... I should also contribute to this... This is what I get, when simply starting Tester.jar:

$ java -jar Tester.jar
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f3a6c8ae9f6, pid=1806, tid=139888907867904
#
# JRE version: 7.0_07-b30
# Java VM: OpenJDK 64-Bit Server VM (23.2-b09 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [ld-linux-x86-64.so.2+0x69f6]  _dl_map_object_from_fd+0x746
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/philipp/Downloads/hs_err_pid1806.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   http://icedtea.classpath.org/bugzilla
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#


EDIT2: More information:
$ java -version
java version "1.7.0_07"
OpenJDK Runtime Environment (IcedTea7 2.3.2) (ArchLinux build 7.u7_2.3.2-2-x86_64)
OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline StumpyStrust
« Reply #29 - Posted 2012-09-22 17:07:51 »

O.o

Well...I made this with java 1.6 not 1.7 but I don't think that should make much difference.

It runs on my 64bit laptop so that can't be it.

You are using a version of linux? I may be missing some .dlls but I think it would give a different error.

I got a many of those when I was trying to figure everything out and generally it has to do with in proper offsets/pointer/other open related things.

Do you have an nvidia card or amd? do you have up to date drivers?


Side note: I may write a tutorial on how to make a basic  spriteBatcher using vertex arrays and VBOs to no one else has to suffer as I have.

Edit:
Fullscreen/HD
180k 30+ fps with physics


Are you not entertained?

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.

Nickropheliac (15 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

CopyableCougar4 (32 views)
2014-08-22 19:31:30

atombrot (41 views)
2014-08-19 09:29:53

Tekkerue (40 views)
2014-08-16 06:45:27

Tekkerue (35 views)
2014-08-16 06:22:17

Tekkerue (25 views)
2014-08-16 06:20:21

Tekkerue (37 views)
2014-08-16 06:12:11

Rayexar (72 views)
2014-08-11 02:49:23

BurntPizza (49 views)
2014-08-09 21:09:32
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!