Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (495)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  JOGL main loop, simulation and rendering  (Read 2235 times)
0 Members and 1 Guest are viewing this topic.
Offline flip

Junior Newbie





« Posted 2009-05-06 16:10:01 »

hello everybody, im new to jogl and i intend to port a C opengl app to jogl.

here comes my first question:

ive seen jogl examples in the opengl-pack quite simple and they all seem to apply the simulation function y the rendering func as this is called everytime by the Animator.

What i want is to know the right way to implement de main loop and call the simulation func at a given rate as i do in C.

In another java app i did, i used a thread to implement this and the sim and rendering func were called inside the while loop in the thread.

¿how do you guys do this? ¿could you post something like a template? ¿were would you call the whole simulation func in your game and how can you control the FPS?

thanks in advance
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 798
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2009-05-06 18:01:46 »

If you want your transition from OpenGL in C to OpenGL in Java to be as smooth as possible, pick the 'other' OpenGL binding: LWJGL. (www.lwjgl.org) Browse through the examples.

I bet the next reply here is how I'd ever dare to point you on that direction, but trust me, LWJGL is much more C style. JOGL is more OO, raising the abstraction level a bit, making it harder to port C to Java.


Additionally:
LWJGL features OpenGL 3.0 and 3.1, is actively supported, and JOGL is currently, seemingly, dead in the water.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline bienator

Senior Member




OutOfCoffeeException


« Reply #2 - Posted 2009-05-06 19:31:22 »

hi filip,

instead of using the Animator you can simple call display() on  a drawable like a GLCanvas in a custom thread.

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  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
package org.yourorghere;

import com.sun.opengl.util.Animator;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;



/**
 * SimpleJOGL.java <BR>
 * author: Brian Paul (converted to Java by Ron Cemer and Sven Goethel) <P>
 *
 * This version is equal to Brian Paul's version 1.2 1999/10/21
 */

public class SimpleJOGL implements GLEventListener {

    public static void main(String[] args) {
        Frame frame = new Frame("Simple JOGL Application");
        final GLCanvas canvas = new GLCanvas();

        canvas.addGLEventListener(new SimpleJOGL());
        frame.add(canvas);
        frame.setSize(640, 480);
//        final Animator animator = new Animator(canvas);
       frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Run this on another thread than the AWT event queue to
               // make sure the call to Animator.stop() completes before
               // exiting
               new Thread(new Runnable() {

                    public void run() {
//                        animator.stop();
                       System.exit(0);
                    }
                }).start();
            }
        });
        // Center frame
       frame.setLocationRelativeTo(null);
        frame.setVisible(true);
//        animator.start();

        while(true) {
            canvas.display();
        }


    }

    public void init(GLAutoDrawable drawable) {
        // Use debug pipeline
       // drawable.setGL(new DebugGL(drawable.getGL()));

        GL gl = drawable.getGL();
        System.err.println("INIT GL IS: " + gl.getClass().getName());

        // Enable VSync
       gl.setSwapInterval(1);

        // Setup the drawing area and shading mode
       gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.
   }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        GL gl = drawable.getGL();
        GLU glu = new GLU();

        if (height <= 0) { // avoid a divide by zero error!
       
            height = 1;
        }
        final float h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();

        // Clear the drawing area
       gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Reset the current matrix to the "identity"
       gl.glLoadIdentity();

        // Move the "drawing cursor" around
       gl.glTranslatef(-1.5f, 0.0f, -6.0f);

        // Drawing Using Triangles
       gl.glBegin(GL.GL_TRIANGLES);
            gl.glColor3f(1.0f, 0.0f, 0.0f);    // Set the current drawing color to red
           gl.glVertex3f(0.0f, 1.0f, 0.0f);   // Top
           gl.glColor3f(0.0f, 1.0f, 0.0f);    // Set the current drawing color to green
           gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
           gl.glColor3f(0.0f, 0.0f, 1.0f);    // Set the current drawing color to blue
           gl.glVertex3f(1.0f, -1.0f, 0.0f);  // Bottom Right
       // Finished Drawing The Triangle
       gl.glEnd();

        // Move the "drawing cursor" to another position
       gl.glTranslatef(3.0f, 0.0f, 0.0f);
        // Draw A Quad
       gl.glBegin(GL.GL_QUADS);
            gl.glColor3f(0.5f, 0.5f, 1.0f);    // Set the current drawing color to light blue
           gl.glVertex3f(-1.0f, 1.0f, 0.0f);  // Top Left
           gl.glVertex3f(1.0f, 1.0f, 0.0f);   // Top Right
           gl.glVertex3f(1.0f, -1.0f, 0.0f);  // Bottom Right
           gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
       // Done Drawing The Quad
       gl.glEnd();

        // Flush all drawing operations to the graphics card
       gl.glFlush();
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }
}

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #3 - Posted 2009-05-06 19:51:36 »

If you want your transition from OpenGL in C to OpenGL in Java to be as smooth as possible, pick the 'other' OpenGL binding: LWJGL. (www.lwjgl.org) Browse through the examples.

I bet the next reply here is how I'd ever dare to point you on that direction, but trust me, LWJGL is much more C style. JOGL is more OO, raising the abstraction level a bit, making it harder to port C to Java.


Additionally:
LWJGL features OpenGL 3.0 and 3.1, is actively supported, and JOGL is currently, seemingly, dead in the water.

careful, goussej might just kill you Wink
Offline gouessej
« Reply #4 - Posted 2009-05-06 21:07:39 »

I bet the next reply here is how I'd ever dare to point you on that direction, but trust me, LWJGL is much more C style. JOGL is more OO, raising the abstraction level a bit, making it harder to port C to Java.
JOGL has only some object-oriented classes but the most part is in the GL interface which is very close of what you can do with C. Therefore, I recommend you to use JOGL. On the other hand, Riven has forgotten to tell you that in most cases, you are not forced to use the higher abstraction level if you prefer doing exactly the same things than in C. For example, to use the textures, you can use the class Texture to take the OO way or use the methods of the interface GL to take the C-like way.

JOGL is currently, seemingly, dead in the water.
Kenneth is very busy, JOGL is not dead, please stop this propaganda now. You disappoint me because I thought you would have a bit more respect for his work. He wrote me recently that he has only to modify some things in GlueGen but the biggest part of the refactoring has been done.

flip, let me know if you need some more examples or if you have any problem with your game, I will do my best.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 798
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #5 - Posted 2009-05-06 22:09:13 »

Kenneth is very busy, JOGL is not dead, please stop this propaganda now. You disappoint me because I thought you would have a bit more respect for his work. He wrote me recently that he has only to modify some things in GlueGen but the biggest part of the refactoring has been done.

You seem to confuse the concepts 'respect' and 'observation'.

JOGL is nice, I have respect for Kenneth, but there simply aint much visible progress anymore, in like, recent months.

Therefore I truly think picking LWJGL is better, as you are not dependant on ONE person at Sun. The community backing at LWJGL is exceptional.

Anyway, please don't take it too personally.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline GKW

Senior Member




Revenge is mine!


« Reply #6 - Posted 2009-05-06 23:46:18 »

I believe it's actually two people at Sun that we are relying on.
Offline flip

Junior Newbie





« Reply #7 - Posted 2009-05-07 10:06:31 »

i'm sorry but i still see this very much confusing. I ll try to explain myself better

in waht concerns the use of  jogl, i''ll stick to it instead of the other one, for now.

let me ask the question again more precisely

in J2me for example we have:
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  
new Thread().start()
.....
void run (){
...
...
//main loop
while (!gameover){

//simulation stuff
calculate()

//rendering stuff
repaint()

elapsed=startTime;
startTime=System.currentTimeMillis();
elapsed=startTime-elapsed;
If(elapsed < MILLISECS_PER_FRAME)
{
   thread.sleep(MILLISECS_PER_FRAME-elapsed);
}
Else
{
   thread.yield();
}
}
}


how do you translate the same loop and its componenes to jogl?
Offline gouessej
« Reply #8 - Posted 2009-05-07 12:45:02 »

I believe it's actually two people at Sun that we are relying on.
Yes, another guy who worked on GL4Java works now on JOGL too.

flip, you can watch the following example and the one provided by bienator:
http://en.wikipedia.org/wiki/JOGL
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  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
//depends on jogl.jar and gluegen-rt.jar
import javax.media.opengl.GL;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GLCanvas;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import com.sun.opengl.util.Animator;
 
public class JOGLTetrahedron implements GLEventListener, KeyListener {
    float rotateT = 0.0f;
    static GLU glu = new GLU();
    static GLCanvas canvas = new GLCanvas();
    static Frame frame = new Frame("Jogl 3D Shape/Rotation");
    static Animator animator = new Animator(canvas);
    public void display(GLAutoDrawable gLDrawable) {
   final GL gl = gLDrawable.getGL();
   gl.glClear(GL.GL_COLOR_BUFFER_BIT);
   gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
   gl.glLoadIdentity();
   gl.glTranslatef(0.0f, 0.0f, -5.0f);
 
   gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
   gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
   gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
   gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
 
   gl.glBegin(GL.GL_TRIANGLES);
 
   // Front
  gl.glColor3f(0.0f, 1.0f, 1.0f);
   gl.glVertex3f(0.0f, 1.0f, 0.0f);
   gl.glColor3f(0.0f, 0.0f, 1.0f);
   gl.glVertex3f(-1.0f, -1.0f, 1.0f);
   gl.glColor3f(0.0f, 0.0f, 0.0f);
   gl.glVertex3f(1.0f, -1.0f, 1.0f);
 
   // Right Side Facing Front
  gl.glColor3f(0.0f, 1.0f, 1.0f);
   gl.glVertex3f(0.0f, 1.0f, 0.0f);
   gl.glColor3f(0.0f, 0.0f, 1.0f);
   gl.glVertex3f(1.0f, -1.0f, 1.0f);
   gl.glColor3f(0.0f, 0.0f, 0.0f);
   gl.glVertex3f(0.0f, -1.0f, -1.0f);
 
   // Left Side Facing Front
  gl.glColor3f(0.0f, 1.0f, 1.0f);
   gl.glVertex3f(0.0f, 1.0f, 0.0f);
   gl.glColor3f(0.0f, 0.0f, 1.0f);
   gl.glVertex3f(0.0f, -1.0f, -1.0f);
   gl.glColor3f(0.0f, 0.0f, 0.0f);
   gl.glVertex3f(-1.0f, -1.0f, 1.0f);
 
   // Bottom
  gl.glColor3f(0.0f, 0.0f, 0.0f);
   gl.glVertex3f(-1.0f, -1.0f, 1.0f);
   gl.glColor3f(0.1f, 0.1f, 0.1f);
   gl.glVertex3f(1.0f, -1.0f, 1.0f);
   gl.glColor3f(0.2f, 0.2f, 0.2f);
   gl.glVertex3f(0.0f, -1.0f, -1.0f);
 
   gl.glEnd();
 
   rotateT += 0.2f;
    }
 
    public void displayChanged(GLAutoDrawable gLDrawable,
                boolean modeChanged, boolean deviceChanged) {
    }
 
    public void init(GLAutoDrawable gLDrawable) {
   GL gl = gLDrawable.getGL();
   gl.glShadeModel(GL.GL_SMOOTH);
   gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
   gl.glClearDepth(1.0f);
   gl.glEnable(GL.GL_DEPTH_TEST);
   gl.glDepthFunc(GL.GL_LEQUAL);
   gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,
        GL.GL_NICEST);
   gLDrawable.addKeyListener(this);
    }
 
    public void reshape(GLAutoDrawable gLDrawable, int x,
         int y, int width, int height) {
   GL gl = gLDrawable.getGL();
   if(height <= 0) {
       height = 1;
   }
   float h = (float)width / (float)height;
   gl.glMatrixMode(GL.GL_PROJECTION);
   gl.glLoadIdentity();
   glu.gluPerspective(50.0f, h, 1.0, 1000.0);
   gl.glMatrixMode(GL.GL_MODELVIEW);
   gl.glLoadIdentity();
    }
 
    public void keyPressed(KeyEvent e) {
   if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
       exit();
   }
    }
 
    public void keyReleased(KeyEvent e) {
    }
 
    public void keyTyped(KeyEvent e) {
    }
 
    public static void exit(){
   animator.stop();
   frame.dispose();
   System.exit(0);
    }
 
    public static void main(String[] args) {
   canvas.addGLEventListener(new JOGLTetrahedron());
   frame.add(canvas);
   frame.setSize(640, 480);
   frame.setUndecorated(true);
   frame.setExtendedState(Frame.MAXIMIZED_BOTH);
   frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
          exit();
      }
       });
   frame.setVisible(true);
   animator.start();
   canvas.requestFocus();
    }
}



As we use an Animator, you don't need to call repaint or anything like this except in active rendering:
1  
2  
3  
4  
5  
6  
7  
8  
while (!gameover){
//simulation stuff
calculate();

//rendering stuff
canvas.display();
//NO SLEEP!!! It breaks the synchronization and decreases the frame rate noticeably!!!
}


Then, you need a GLEventListener to perform all GL tasks, watch the example whose I have given you the link. Your GLEventListener has a method called public void display(GLAutoDrawable gLDrawable) that performs the GL calls except for the initialization, calling display() on the canvas (GLCanvas) does the same thing than glutPostRedisplay when you use GLUT in C. The method public void init(GLAutoDrawable gLDrawable) performs the GL calls at the initialization of the context (glFrustum and gluLookAt for example). Another method handles the case of reshaping and change of display.

Offline flip

Junior Newbie





« Reply #9 - Posted 2009-05-07 14:16:38 »

Ok, ive already seen those examples, but where do you really make the call to the simulation function (collision detection, etc) where is the right spot to place it in the code? i believe it's not in the rendering function which is called everytime by the animator.
i've pointed out a possible solution with a thread, but there may be others like for example with a timertask perhaps?
i mean where do you guys put all the code related to the game in the example above of the wikipedia? in the example above, the
1  
rotateT+= 0.2f
in the display function shouldnt be there because as i see it, it belongs to the simulation function, that's what im specifically asking. We cant place all the gameupdate/logic/etc into the display function just because it's called everytime by the animator. It must be separated.
And finally,
how can you control the timing/FPS of your app then?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gouessej
« Reply #10 - Posted 2009-05-07 14:32:26 »

Ok, ive already seen those examples, but where do you really make the call to the simulation function (collision detection, etc) where is the right spot to place it in the code? i believe it's not in the rendering function which is called everytime by the animator.
i've pointed out a possible solution with a thread, but there may be others like for example with a timertask perhaps?
i mean where do you guys put all the code related to the game in the example above of the wikipedia? in the example above, the
1  
rotateT+= 0.2f
in the display function shouldnt be there because as i see it, it belongs to the simulation function, that's what im specifically asking. We cant place all the gameupdate/logic/etc into the display function just because it's called everytime by the animator. It must be separated.
And finally,
how can you control the timing/FPS of your app then?
I advise you to look at my own source code, especially this class:
https://tuer.svn.sourceforge.net/svnroot/tuer/tuer/main/GameController.java
You're right, it is not in the rendering method. In my case, this.gameModel.runEngine() does something very close to your loop while(!gameover){...}:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
canvas.addGLEventListener(gameView=new GameGLView(this));   
canvas.addMouseMotionListener(gameMouseMotionController=new GameMouseMotionController(gameView));      
canvas.addMouseListener(gameMouseMotionController);  
canvas.addKeyListener(new GameKeyboardMonitor(gameView));            
gameView.display();
frame.add(canvas);
frame.setVisible(true);
canvas.requestFocus();
canvas.requestFocusInWindow();      
attachSound();
openSound();
this.gameModel.runEngine();



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  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
public final void runEngine(){
        lastBotShotTime=currentTime();
        initialize();  // load stuff, raw setup
       gameRunning=true;
        innerLoop=false;
        boolean hasBeenKilled=false;
        Rectangle2D.Float rWallVoxel = new Rectangle2D.Float();
        Rectangle2D.Float rPlayerVoxel = new Rectangle2D.Float();
        final float playerSize=1.0f/4.0f;
        final float wallSize=1.0f;
        rPlayerVoxel.width=playerSize;
        rPlayerVoxel.height=playerSize;
        rWallVoxel.width=wallSize;
        rWallVoxel.height=wallSize;      
        boolean playMenuMusicOnce=true;
        //loop until the player tries to exit the game    
       while(gameRunning)
            {reinit(hasBeenKilled);     // re-set all positions            
            while(gameController.getCycle()!=GameCycle.GAME && gameRunning)
                 {if(playMenuMusicOnce)
                      {gameController.playSound(15);
                       playMenuMusicOnce=false;
                      }
                  //TODO: update a model only used in the menu
                 gameController.display();
                 }
             if(gameRunning)
                 {if(hasBeenKilled)
                      {player.respawn();
                       hasBeenKilled=false;                      
                      }          
                  innerLoop=true;
                  gameController.playSound(14);
                 }
             boolean bmoved;
             double playerXnew,playerZnew;
             float framerateCompensatedSpeed;          
             this.internalClock.start();
             this.lastBotShotTime=currentTime();
             this.lastShot=currentTime();
             this.isFalling=false;
             long cycleDuration;
             boolean walkSoundPlayedOnce=false;
             //loop until the end of a party (even when game paused)
            while(innerLoop)
                 {gameController.display();                              
                  //update the clock if required
                 cycleDuration=internalClock.getElapsedTime();
                  if(bpause)
                      {if(!internalClock.isPaused())
                           internalClock.pause();
                       continue;
                      }
                  else
                      if(internalClock.isPaused())
                          internalClock.unpause();
                      else
                          internalClock.sync();
                  cycleDuration=internalClock.getElapsedTime()-cycleDuration;
                  framerateCompensationFactor = 16*cycleDuration*10;
                  //uses the time spent between 2 frames to adapt the step to the speed of the machine
                 framerateCompensatedSpeed=framerateCompensationFactor*(runningFast?3:1)/65536.0f;

In the source code above, you see gameController.display() in the inner loop, some synchronization (internalClock). If you look at the whole method, the collisions are tested a bit further.

Pages: [1]
  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.

Dwinin (29 views)
2014-09-12 09:08:26

Norakomi (57 views)
2014-09-10 13:57:51

TehJavaDev (76 views)
2014-09-10 06:39:09

Tekkerue (38 views)
2014-09-09 02:24:56

mitcheeb (58 views)
2014-09-08 06:06:29

BurntPizza (45 views)
2014-09-07 01:13:42

Longarmx (30 views)
2014-09-07 01:12:14

Longarmx (35 views)
2014-09-07 01:11:22

Longarmx (36 views)
2014-09-07 01:10:19

mitcheeb (40 views)
2014-09-04 23:08:59
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!