Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
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  
  Introduction to Vertex Arrays and Vertex Buffer Objects (OpenGL)  (Read 24528 times)
0 Members and 1 Guest are viewing this topic.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Posted 2011-05-23 21:01:59 »

Introduction to Vertex Arrays and Vertex Buffer Objects
Copy 'n Paste OpenGL



It is my suspicion that most aspiring developers these days prefer to copy snippets of code, paste them into their own project, see if it works, modify a few things, and work from there. Therefore I decided not to explain too much in this tutorial, because most is either self descriptive or properly explained elsewhere (see here).

Having said that, here goes:

Getting started...
First we initialize an OpenGL context through LWJGL:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
import org.lwjgl.*;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.ARBBufferObject.*;
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
import static org.lwjgl.opengl.GL11.*;

public class JgoVbo
{
   static void initContext() throws LWJGLException
   {
      int w = 640;
      int h = 480;

      Display.setDisplayMode(new DisplayMode(w, h));
      Display.setFullscreen(false);
      Display.create();
      glViewport(0, 0, w, h);
   }


Render loop
Once we have the context, we need some loop that will prepare a frame, render some graphics and showing it on screen, until we close the window.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   static void renderLoop()
   {
      while (!Display.isCloseRequested())
      {
         preRender();

         render();

         Display.update();

         Display.sync(10 /* desired fps */);
      }

      Display.destroy();
   }


Clearing the screen
Before the render anything, we need to start with a clean slate by clearing the framebuffer and resetting the the OpenGL matrices.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
   static void preRender()
   {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
   }


Immediate mode
Now lets start simple, by drawing a triangle using the immediate mode of OpenGL:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   static void drawImmediateMode()
   {
      glBegin(GL_TRIANGLES);

      glColor3f(1, 0, 0);
      glVertex3f(-0.5f, -0.5f, 0.0f);

      glColor3f(0, 1, 0);
      glVertex3f(+0.5f, -0.5f, 0.0f);

      glColor3f(0, 0, 1);
      glVertex3f(+0.5f, +0.5f, 0.0f);

      glEnd();
   }


Output:

Vertex Arrays
We can draw exactly the same triangle using Vertex Arrays, like this:
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  
   static void drawVertexArray()
   {
      // create geometry buffers
     FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9);
      cBuffer.put(1).put(0).put(0);
      cBuffer.put(0).put(1).put(0);
      cBuffer.put(0).put(0).put(1);
      cBuffer.flip();

      FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9);
      vBuffer.put(-0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(+0.5f).put(0.0f);
      vBuffer.flip();

      //

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glColorPointer(3, /* stride */3 << 2, cBuffer);
      glVertexPointer(3, /* stride */3 << 2, vBuffer);
      glDrawArrays(GL_TRIANGLES, 0, /* elements */3);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);
   }


Vertex Buffer Objects
With Vertex Buffer Objects (VBOs) we need to first generate resources on the GPU, and access them by their handles. The idea is to keep that geometry as long as possible on the GPU, so, as opposed to Vertex Arrays, we don't have to upload them every frame.
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  
   static void drawVertexBufferObject()
   {
      // create geometry buffers
     FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9);
      cBuffer.put(1).put(0).put(0);
      cBuffer.put(0).put(1).put(0);
      cBuffer.put(0).put(0).put(1);
      cBuffer.flip();

      FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9);
      vBuffer.put(-0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(+0.5f).put(0.0f);
      vBuffer.flip();

      //

      IntBuffer ib = BufferUtils.createIntBuffer(2);

      glGenBuffersARB(ib);
      int vHandle = ib.get(0);
      int cHandle = ib.get(1);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
      glVertexPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
      glColorPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

      glDrawArrays(GL_TRIANGLES, 0, 3 /* elements */);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      // cleanup VBO handles
     ib.put(0, vHandle);
      ib.put(1, cHandle);
      glDeleteBuffersARB(ib);
   }


Vertex Buffer Objects (indexed)
Now we might want to render the trangle using indexed geometry. That means you have a buffer that holds the indices of the triangles we want to render. This way you can reuse geometry (vertices) for more than one triangle (shared vertices). The only difference is that we need to create an index buffer, which also is a VBO, and fill it. In most cases 16 bit indices are a good choice:
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  
   static void drawVertexBufferObjectIndexed()
   {
      // create geometry buffers
     FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9);
      cBuffer.put(1).put(0).put(0);
      cBuffer.put(0).put(1).put(0);
      cBuffer.put(0).put(0).put(1);
      cBuffer.flip();

      FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9);
      vBuffer.put(-0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(+0.5f).put(0.0f);
      vBuffer.flip();

      // create index buffer
     ShortBuffer iBuffer = BufferUtils.createShortBuffer(3);
      iBuffer.put((short) 0);
      iBuffer.put((short) 1);
      iBuffer.put((short) 2);
      iBuffer.flip();

      //

      IntBuffer ib = BufferUtils.createIntBuffer(3);

      glGenBuffersARB(ib);
      int vHandle = ib.get(0);
      int cHandle = ib.get(1);
      int iHandle = ib.get(2);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
      glVertexPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
      glColorPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);

      glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
      glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iBuffer, GL_STATIC_DRAW_ARB);

      glDrawElements(GL_TRIANGLES, /* elements */3, GL_UNSIGNED_SHORT, 0L);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
      glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      // cleanup VBO handles
     ib.put(0, vHandle);
      ib.put(1, cHandle);
      ib.put(2, iHandle);
      glDeleteBuffersARB(ib);
   }


Vertex Buffer Objects (interleaved)
Until now we have created separate VBOs for vertices and colors. We can interleave them in two ways:

1. VCVCVC (V stands for vertex element, C stands for color element)
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  
   static void drawVertexBufferObjectInterleaved1()
   {
      // create geometry buffer (both vertex and color)
     FloatBuffer vcBuffer = BufferUtils.createFloatBuffer(9 + 9);

      vcBuffer.put(-0.5f).put(-0.5f).put(0.0f); // v
     vcBuffer.put(1).put(0).put(0); // c

      vcBuffer.put(+0.5f).put(-0.5f).put(0.0f); // v
     vcBuffer.put(0).put(1).put(0); // c

      vcBuffer.put(+0.5f).put(+0.5f).put(0.0f); // v
     vcBuffer.put(0).put(0).put(1); // c

      vcBuffer.flip();

      //

      IntBuffer ib = BufferUtils.createIntBuffer(1);

      glGenBuffersARB(ib);
      int vcHandle = ib.get(0);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vcHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, vcBuffer, GL_STATIC_DRAW_ARB);
      glVertexPointer(3, GL_FLOAT, /* stride **/(3 * 2) << 2, /* offset **/0 << 2); // float at index 0
     glColorPointer(3, GL_FLOAT, /* stride **/(3 * 2) << 2, /* offset **/(3*1) << 2); // float at index 3

      glDrawArrays(GL_TRIANGLES, 0, 3 /* elements */);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      // cleanup VBO handles
     ib.put(0, vcHandle);
      glDeleteBuffersARB(ib);
   }


2. VVVCCC (V stands for vertex element, C stands for color element)
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  
   static void drawVertexBufferObjectInterleaved2()
   {
      // create geometry buffer (both vertex and color)
     FloatBuffer vcBuffer = BufferUtils.createFloatBuffer(9 + 9);

      vcBuffer.put(-0.5f).put(-0.5f).put(0.0f); // v
     vcBuffer.put(+0.5f).put(-0.5f).put(0.0f); // v
     vcBuffer.put(+0.5f).put(+0.5f).put(0.0f); // v
     vcBuffer.put(1).put(0).put(0); // c      
     vcBuffer.put(0).put(1).put(0); // c      
     vcBuffer.put(0).put(0).put(1); // c

      vcBuffer.flip();

      //

      IntBuffer ib = BufferUtils.createIntBuffer(1);

      glGenBuffersARB(ib);
      int vcHandle = ib.get(0);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vcHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, vcBuffer, GL_STATIC_DRAW_ARB);
      glVertexPointer(3, GL_FLOAT, /* stride **/(3 * 1) << 2, /* offset */0 << 2); // float at index 0
     glColorPointer(3, GL_FLOAT, /* stride **/(3 * 1) << 2, /* offset */(3 * 3) << 2); // float at index 9

      glDrawArrays(GL_TRIANGLES, 0, 3 /* elements */);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      // cleanup VBO handles
     ib.put(0, vcHandle);
      glDeleteBuffersARB(ib);
   }

Pay close attention to the values specified as stride and offset in both examples of interleaved rendering.


Mapped Vertex Buffer Object
We can also request a memory region from the driver, to push our vertex data into. We obtain this memory region as a ByteBuffer, in which we can solely write, using the glMapBuffer(..). When we've defined the data, we call glUnmapBuffer(...) to notify the driver we are done, allowing the driver exclusive access to the data.
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  
  static void drawVertexBufferObjectInterleavedMapped()
   {
      IntBuffer ib = BufferUtils.createIntBuffer(1);

      glGenBuffersARB(ib);
      int vcHandle = ib.get(0);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vcHandle);
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, (9 + 9) << 2, GL_STATIC_DRAW_ARB);

      {
         ByteBuffer dataBuffer = glMapBufferARB(GL_ARRAY_BUFFER_ARB, ARBBufferObject.GL_WRITE_ONLY_ARB, (9 + 9) << 2, null);

         // create geometry buffer (both vertex and color)
        FloatBuffer vcBuffer = dataBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer();

         vcBuffer.put(-0.5f).put(-0.5f).put(0.0f); // v
        vcBuffer.put(1).put(0).put(0); // c

         vcBuffer.put(+0.5f).put(-0.5f).put(0.0f); // v
        vcBuffer.put(0).put(1).put(0); // c

         vcBuffer.put(+0.5f).put(+0.5f).put(0.0f); // v
        vcBuffer.put(0).put(0).put(1); // c

         vcBuffer.flip();        

         glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
      }

      glVertexPointer(3, GL_FLOAT, /* stride */(3 * 2) << 2, /* offset */0L << 2); // float at index 0
     glColorPointer(3, GL_FLOAT, /* stride */(3 * 2) << 2, /* offset */(3 * 1) << 2); // float at index 3

      glDrawArrays(GL_TRIANGLES, 0, 3 /* elements */);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);


      // cleanup VBO handles
     ib.put(0, vcHandle);
      glDeleteBuffersARB(ib);
   }


Done!
Finally we can render our triangle, using the 7 strategies mentioned above:
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  
   static void render()
   {
      glClearColor(1, 1, 1, 1);

      // start drawing a triangle with the different strategies

      drawImmediateMode();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexArray();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexBufferObject();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexBufferObjectIndexed();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexBufferObjectInterleaved1();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexBufferObjectInterleaved2();

      glTranslatef(+0.05f, -0.05f, 0);
      drawVertexBufferObjectInterleavedMapped();
   }

To prevent the triangles to be rendered on top of eachother, a slight offset/translation is added after drawing each triangle.

Output:

Although I agree the output is far from entertaining, it should help you implementing your own geometry rendering strategy.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline CommanderKeith
« Reply #1 - Posted 2011-05-23 21:34:08 »

Great stuff, you could give courses with these notes. Succinct and symetrical in the way the strategies are laid out so only the differences can be seen.
Thanks for sharing

Offline static_flashlight

Senior Newbie




Software Engineer


« Reply #2 - Posted 2011-07-08 13:54:20 »

Thanks for posting this tutorial.  Unlike far too many examples online for LWJGL, this tutorial includes all the syntax required to actually use these features.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #3 - Posted 2011-07-08 14:59:35 »

Ofcourse, I needed it to work to create the screenshots Smiley

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

JGO Coder


Medals: 17



« Reply #4 - Posted 2011-07-10 06:15:47 »

Although it's easy to figure out, you're missing main():

1  
2  
3  
4  
5  
6  
    public static void main(String[] args) throws LWJGLException {
        System.out.println("Hello world from OpenGL!");

        initContext();
        renderLoop();
    }
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #5 - Posted 2011-10-18 21:36:01 »

Thanks. Added glMapBuffer(..) variant.

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

JGO Kernel


Medals: 342
Projects: 2
Exp: 5 years


I'm the King!


« Reply #6 - Posted 2012-11-03 22:11:05 »

Shouldn't the stride be 0 for all of these examples?

Offline matheus23

JGO Kernel


Medals: 106
Projects: 3


You think about my Avatar right now!


« Reply #7 - Posted 2012-11-03 22:16:22 »

It could also be pretty intresting for me to see a "port" of this code to how one would do it with your "MappedObject" library...
Smiley

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #8 - Posted 2012-11-03 22:44:29 »

@ra4king setting the stride to zero means you force the driver to make an attempt at calculating it. First of all, that only works in trivial use cases (as it would fail in some of these trivial examples). Second, if you don't see how the stride should be calculated, how are you ever going to understand them? This is a tutorial, which should explain it properly.


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

JGO Kernel


Medals: 342
Projects: 2
Exp: 5 years


I'm the King!


« Reply #9 - Posted 2012-11-03 22:50:49 »

Wait....stride is simply the offset between each color. If it is zero then that means the colors are specified in a row, or tightly packed. What is there to calculate? The stride should only be present for interleaved arrays.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #10 - Posted 2012-11-03 23:00:35 »

You misunderstood strides. Strides define the number of bytes between offsets of data, not the bytes between data. A stride of zero doesn't mean it's tightly packed, it means that all data (for every vertex) is at exactly the same byte offset (same memory address), which makes no sense whatsoever - and therefore is used as a special value, to instruct the driver to calculate it itself.

1  
vertexAttributeData[vertexIndex] = vertexIndex * stride + vertexAttributeOffset

You can see that a real zero-stride would create a series of zero-surface-area triangles (all vertex-attributes are read from the same memory address).

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

JGO Kernel


Medals: 342
Projects: 2
Exp: 5 years


I'm the King!


« Reply #11 - Posted 2012-11-03 23:11:55 »

Riven, I've used 0 as stride for all my VBO's and they render just fine...

You're also saying the Arcsynthesis explanation is wrong too :S

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #12 - Posted 2012-11-03 23:12:40 »

Who cares what some other tutorials tells you. Read the specs. You can also choose to be blissfully unaware of what strides really mean, and use 0 forever, until it turns out you've indeed misunderstood them all that time.

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

JGO Kernel


Medals: 342
Projects: 2
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2012-11-03 23:13:59 »

The specs agree with me! 0 means tightly-packed! Pointing

EDIT: More specifically:
Quote
stride
      Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 757
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2012-11-03 23:15:28 »

You, my dear, need some spoon feeding.

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

JGO Kernel


Medals: 342
Projects: 2
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2012-11-03 23:36:04 »

Well I got it now....thanks for your help <3

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.

CogWheelz (16 views)
2014-08-01 22:53:16

CogWheelz (15 views)
2014-08-01 22:51:43

CopyableCougar4 (18 views)
2014-08-01 19:37:19

CogWheelz (19 views)
2014-07-30 21:08:39

Riven (27 views)
2014-07-29 18:09:19

Riven (16 views)
2014-07-29 18:08:52

Dwinin (14 views)
2014-07-29 10:59:34

E.R. Fleming (35 views)
2014-07-29 03:07:13

E.R. Fleming (13 views)
2014-07-29 03:06:25

pw (44 views)
2014-07-24 01:59:36
Resources for WIP games
by CogWheelz
2014-08-01 18:20:17

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

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

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

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

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22
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!