Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (778)
Games in Android Showcase (231)
games submitted by our members
Games in WIP (856)
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  
  Looking for some advice  (Read 25345 times)
0 Members and 1 Guest are viewing this topic.
Offline DrakosKai

Senior Newbie


Medals: 3



« Posted 2016-04-14 21:48:56 »

I'm looking for some advice/point me in the right direction.  Basically I'm trying to go from building a shape using a VAO/VBO where you directly specify all the information, and migrate the code to a place where I can specify the positions/numbers of shapes dynamically.

https://github.com/Drakoskai/funtimes-with-jogl

So here's some of my current thoughts at the moment:

Seems like each shape instance needs to have its own buffers and reference to the VBO id

Not sure about the VAO do I need multiple VAO's?

I'd like the shape to initialize it's own buffers and fill them at the appropriate times.


Looking for some direction on the next step, any help is much appreciated Smiley
Offline gouessej
« Reply #1 - Posted 2016-04-15 18:03:44 »

Hi

You should look at elect's examples including this one and post your question on the official JogAmp forum as your question seems to be specific to our API.

Instead of reinventing the wheel, I advise you to study the source code of the most famous engines/frameworks with JOGL renderers, for example JMonkeyEngine 3, LibGDX, JogAmp's Ardor3D Continuation, Java3D, ...

Julien Gouesse | Personal blog | Website | Jogamp
Offline elect

JGO Knight


Medals: 60



« Reply #2 - Posted 2016-04-15 20:00:13 »

So here's some of my current thoughts at the moment:

Seems like each shape instance needs to have its own buffers and reference to the VBO id

Not sure about the VAO do I need multiple VAO's?

I'd like the shape to initialize it's own buffers and fill them at the appropriate times.


Looking for some direction on the next step, any help is much appreciated Smiley


A basic/starting approach corresponds to your current thoughts, each shape/mesh with its own buffer id. Once you loaded the geometry on the gpu, if you don't need it anymore on the cpu, you can clear it (BufferUtils.destroyDirect for direct buffers, because otherwise you don't have the security they are gonna be removed). The mesh will obviously have also the vbo id as you say.

Vao was a brilliant idea poorly implemented.
It is useful just to avoid to set up again and again the vertex layout, that is glVertexAttribBinding/glVertexAttribFormat/glEnableVertexAttribArray and so on. But actually if you manage your vertex attributes wisely (that Semantic.java gives you very good chances) you just need to create only one (or very few) vao and keep it bound forever.

Think about it, most of meshes (usually) are gonna need always the same vertex attributes: position, normal, texture coordinates, matrices and so on.
You do not need to change the vertex attribute format, you need to change only the binding buffer where the shader will fetch the data from at the given time

Remember also to clean resources when you are done with one mesh on the gpu (buffer deletion and so on)
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #3 - Posted 2016-04-17 13:49:43 »

A basic/starting approach corresponds to your current thoughts, each shape/mesh with its own buffer id. Once you loaded the geometry on the gpu, if you don't need it anymore on the cpu, you can clear it (BufferUtils.destroyDirect for direct buffers, because otherwise you don't have the security they are gonna be removed). The mesh will obviously have also the vbo id as you say.

Vao was a brilliant idea poorly implemented.
It is useful just to avoid to set up again and again the vertex layout, that is glVertexAttribBinding/glVertexAttribFormat/glEnableVertexAttribArray and so on. But actually if you manage your vertex attributes wisely (that Semantic.java gives you very good chances) you just need to create only one (or very few) vao and keep it bound forever.

Think about it, most of meshes (usually) are gonna need always the same vertex attributes: position, normal, texture coordinates, matrices and so on.
You do not need to change the vertex attribute format, you need to change only the binding buffer where the shader will fetch the data from at the given time

Remember also to clean resources when you are done with one mesh on the gpu (buffer deletion and so on)


Thank you! this is exactly the information I was looking for to help me connect Step A to Step B.  It's also pretty awesome to see this response since your tutorial is actually the one I was working off of Smiley


Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #4 - Posted 2016-04-17 15:33:15 »

I was studying NASA's WorldWind's source code and what I see them doing is using this Geometry class to group the buffers involved. It looks like WorldWind caches the Geometry and then recalls it if needed instead of purging it.  My version isn't caching it or recalling it since I'm working on such a simple level(I am just trying to understand the basics of the rasterization process).  Are you saying that I should purge the geometry after it has been loaded by disposing the buffers in this class?  Or is this a dumb approach entirely?

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  
public class Geometry {

    private final int[] mode;
    private final int[] count;
    private final int[] size;
    private final int[] glType;
    private final Buffer[] buffer;

    public Geometry() {
        this.mode = new int[4];
        this.count = new int[4];
        this.size = new int[4];
        this.glType = new int[4];
        this.buffer = new Buffer[4];
    }

    public int getMode(GLBuffer type) {
        return this.mode[type.id()];
    }

    public void setMode(GLBuffer type, int mode) {
        this.mode[type.id()] = mode;
    }

    public int getCount(GLBuffer type) {
        return this.count[type.id()];
    }

    public int getSize(GLBuffer type) {
        return this.size[type.id()];
    }

    public int getGLType(GLBuffer type) {
        return this.glType[type.id()];
    }

    public Buffer getBuffer(GLBuffer type) {
        return this.buffer[type.id()];
    }

    public void setElementData(int mode, int count, int[] src) {
        this.setMode(ELEMENT, mode);
        this.buffer[ELEMENT.id()] = GLBuffers.newDirectIntBuffer(src);
        this.size[ELEMENT.id()] = 1;
        this.glType[ELEMENT.id()] = GL.GL_UNSIGNED_INT;
        this.count[ELEMENT.id()] = count;
    }

    public void setVertexData(int size, float[] src) {
        this.buffer[VERTEX.id()] = GLBuffers.newDirectFloatBuffer(src);
        this.size[VERTEX.id()] = size;
        this.glType[VERTEX.id()] = GL.GL_FLOAT;
        this.count[VERTEX.id()] = 3;
    }

    public long getSizeInBytes(GLBuffer type) {
        return this.bufferSize(type);
    }

    private long bufferSize(GLBuffer type) {
        long sz = 0L;
        if (this.buffer[type.id()] != null) {
            sz = this.sizeOf(this.glType[type.id()]) * this.getCount(type) * this.size[type.id()];
        }
        return sz;
    }

    private long sizeOf(int glType) {
        long sz = 0L;
        switch (glType) {
            case GL2.GL_BYTE:
                sz = 1L;
                break;
            case GL2.GL_SHORT:
            case GL2.GL_UNSIGNED_SHORT:
                sz = 2L;
                break;
            case GL2.GL_INT:
            case GL2.GL_UNSIGNED_INT:
            case GL2.GL_FLOAT:
                sz = 4L;
                break;
            case GL2.GL_DOUBLE:
                sz = 8L;
                break;
        }
        return sz;
    }
Offline gouessej
« Reply #5 - Posted 2016-04-17 18:43:18 »

Once you loaded the geometry on the gpu, if you don't need it anymore on the cpu, you can clear it (BufferUtils.destroyDirect for direct buffers, because otherwise you don't have the security they are gonna be removed).
Only my deallocation helper does it correctly, your source code comes from JMonkeyEngine 3, it handles only some basic cases.

Julien Gouesse | Personal blog | Website | Jogamp
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #6 - Posted 2016-04-17 19:09:58 »

Once you loaded the geometry on the gpu, if you don't need it anymore on the cpu, you can clear it (BufferUtils.destroyDirect for direct buffers, because otherwise you don't have the security they are gonna be removed).
Only my deallocation helper does it correctly, your source code comes from JMonkeyEngine 3, it handles only some basic cases.

I'm not really trying to build an optimal professional engine for the purpose of making a game, I'm trying to understand the pipeline.  But, I guess thanks for letting me know.
Offline elect

JGO Knight


Medals: 60



« Reply #7 - Posted 2016-04-18 07:32:19 »

I was studying NASA's WorldWind's source code and what I see them doing is using this Geometry class to group the buffers involved. It looks like WorldWind caches the Geometry and then recalls it if needed instead of purging it.  My version isn't caching it or recalling it since I'm working on such a simple level(I am just trying to understand the basics of the rasterization process).  Are you saying that I should purge the geometry after it has been loaded by disposing the buffers in this class?  Or is this a dumb approach entirely?

Everything depends on what are your needs.

I mean, how is that geometry you are using? Static (living for at least a couple of seconds) or dynamic (updated each frame)?

Ps: Gouessej is right, so until you stay "under" Oracle you should be fine with that small utils of mine
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #8 - Posted 2016-04-18 20:16:08 »

I'm not sure how often it will need to be regenerated.  I think that the shape will be static.  Ie, a triangle will start the same as any triangle and then be skewed/scaled based on the that particular instance.  So I guess the basic geometry would be static before being rasterized.
Offline elect

JGO Knight


Medals: 60



« Reply #9 - Posted 2016-04-19 08:51:24 »

I'm not sure how often it will need to be regenerated.  I think that the shape will be static.  Ie, a triangle will start the same as any triangle and then be skewed/scaled based on the that particular instance.  So I guess the basic geometry would be static before being rasterized.

Good, then I'd say to start with a simple and basic approach and create a Mesh class. I mean, if you want to do something similar you can do it of course, but I always prefer starting with a simple approarch first and then optimize later, if I feel the needing.
For example, keep everything inside your Mesh class and then move all the buffer stuff to a Geometry class when you see Mesh growing too much.

Write a generic mesh handiling vbo/ibo and then you have multiple choise, you may want to hardcode the geometry initialization in the constructor, or passing it from the extern, or extending the Mesh for each of the shape you want to build, if they are standards (such as cube/sphere/etc), and do the init there..
Once you upload the geometry to your vbo/ibo, delete the direct buffer
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #10 - Posted 2016-04-19 17:57:46 »

I tried to add the z coordinate to the Triangle (my code evolved directly from your hello triangle) ha! it totally exploded in my face with GL errors.  Tracked the issue down and fixed it:

(I changed all the vec2s to vec3s but this piece slipped by me)

Shader status invalid: 0(37) : error C1068: too much data in type constructor

1  
gl_Position = transform.modelToClipMatrix * vec4(position,0 , 1);


1  
gl_Position = transform.modelToClipMatrix * vec4(position, 1);
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #11 - Posted 2016-04-19 18:21:12 »

I tried to create a second Triangle with different properties but there seems to be a problem.  I think I need to do something with the VBO/IBO/Transform pointer offsets.

Will get back to this later today.

GLDebugEvent[ id 0x502
   type Error
   severity High: dangerous undefined behavior
   source GL API
   msg GL_INVALID_OPERATION error generated. <program> has not been linked, or is not a program object.
   when 1461089778622
   source 4.5 (Core profile, arb, debug, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.5.0 NVIDIA 364.72 - hash 0x7fc2948c]

https://github.com/Drakoskai/funtimes-with-jogl/blob/master/src/test/java/com/drakos/GLTest.java

Offline elect

JGO Knight


Medals: 60



« Reply #12 - Posted 2016-04-20 06:45:07 »

I tried to add the z coordinate to the Triangle (my code evolved directly from your hello triangle) ha! it totally exploded in my face with GL errors.  Tracked the issue down and fixed it:

(I changed all the vec2s to vec3s but this piece slipped by me)

Shader status invalid: 0(37) : error C1068: too much data in type constructor

1  
gl_Position = transform.modelToClipMatrix * vec4(position,0 , 1);


1  
gl_Position = transform.modelToClipMatrix * vec4(position, 1);


Explosions are good, direct and visible, what would one like more than that?  Tongue

Remember always to apply changes on the server side (java code) and client one (glsl)

GLDebugEvent[ id 0x502
   type Error
   severity High: dangerous undefined behavior
   source GL API
   msg GL_INVALID_OPERATION error generated. <program> has not been linked, or is not a program object.
   when 1461089778622
   source 4.5 (Core profile, arb, debug, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.5.0 NVIDIA 364.72 - hash 0x7fc2948c]

https://github.com/Drakoskai/funtimes-with-jogl/blob/master/src/test/java/com/drakos/GLTest.java

This 99% follows a glsl compiler error. Look just one step previous than the first error of this kind  Wink
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #13 - Posted 2016-04-21 12:06:24 »


Remember always to apply changes on the server side (java code) and client one (glsl)

This 99% follows a glsl compiler error. Look just one step previous than the first error of this kind  Wink

I found it.  I have the code doing what I want it to do.  I'm finally in place where I feel I have control over the pipeline and I can see the results of the things I am doing to measure them. 

I've been thinking of glsl as a procedure that takes instructions and places them in the local memory of the gpu and then streams/batches data in to be operated on.  Since the instructions are so close to the gpu and the gpu is optimized for floating point calculations it's very efficient. When the batch is complete the instructions are discarded in favor of the next instructions for the next data set.  I could be wrong with my visualizing but that's the mental model that I've built from my studying of the architecture thus far.  It seems very similar to part of some parallel processing algorithms on the standard cpu where instructions are loaded in the L1 cache and then data is brought to the cpu in batches to be worked on.  This avoids an expensive heap traversal during an operation since all the information is in the L1 cache already.
Offline elect

JGO Knight


Medals: 60



« Reply #14 - Posted 2016-04-21 13:04:43 »

I found it.  I have the code doing what I want it to do.  I'm finally in place where I feel I have control over the pipeline and I can see the results of the things I am doing to measure them.  

Feels good, doesnt?  Cool Grin

Ps: if you by measuring meant profiling, remember that for measuring gpu time, you have to use gpu timers

I've been thinking of glsl as a procedure that takes instructions and places them in the local memory of the gpu and then streams/batches data in to be operated on.  Since the instructions are so close to the gpu and the gpu is optimized for floating point calculations it's very efficient. When the batch is complete the instructions are discarded in favor of the next instructions for the next data set.  I could be wrong with my visualizing but that's the mental model that I've built from my studying of the architecture thus far.  It seems very similar to part of some parallel processing algorithms on the standard cpu where instructions are loaded in the L1 cache and then data is brought to the cpu in batches to be worked on.  This avoids an expensive heap traversal during an operation since all the information is in the L1 cache already.

Actually glsl code gets first translated to byte code and then to gpu code, you can have a look at this post.

Anyway, if you think about glsl in "graphics terms", today is a really limited vision... nowadays you have much more freedom given that since version 4.3 we have now Compute Shader. Under these conditions modern OpenGL has became a very powerful api integrating both gpgpu and graphics together in the same api.

You may want to take a look to the computing samples here to have an idea.
Offline DrakosKai

Senior Newbie


Medals: 3



« Reply #15 - Posted 2016-04-23 18:49:06 »

Moving along pretty well, I changed the triangle into a pyramid and I separated the mesh from the shape class. 
Offline gouessej
« Reply #16 - Posted 2016-05-14 15:41:28 »

Ps: Gouessej is right, so until you stay "under" Oracle you should be fine with that small utils of mine
No your "util" is very basic and handles only a few cases with Oracle Java.

Julien Gouesse | Personal blog | Website | Jogamp
Pages: [1]
  ignore  |  Print  
 
 

 
hadezbladez (361 views)
2018-11-16 13:46:03

hadezbladez (194 views)
2018-11-16 13:41:33

hadezbladez (363 views)
2018-11-16 13:35:35

hadezbladez (91 views)
2018-11-16 13:32:03

EgonOlsen (2193 views)
2018-06-10 19:43:48

EgonOlsen (2229 views)
2018-06-10 19:43:44

EgonOlsen (1386 views)
2018-06-10 19:43:20

DesertCoockie (2023 views)
2018-05-13 18:23:11

nelsongames (1677 views)
2018-04-24 18:15:36

nelsongames (2313 views)
2018-04-24 18:14:32
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
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!