Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (736)
Games in Android Showcase (224)
games submitted by our members
Games in WIP (813)
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  
  Lwjgl 3 - difficulties trying to use VBO's  (Read 1670 times)
0 Members and 1 Guest are viewing this topic.
Offline buddyBro
« Posted 2017-05-16 15:31:44 »

Intro, so I've spent a couple days trying to figure out the lwjgl 3 way of doing things with vbo's. This being the first time I'm hearing a lot of the terminology isn't making the resources/tutorials easy to understand. Nor do I want to begin at the very beginning, since I have a solid understanding of 3d rendering (though not of opengl or gpu's). Also, though I would like to take the time to learn opengl thoroughly eventually, at the moment, I just want to get my little experiment working.

Previously, I had been using Java graphics2D to draw polygons; e.g.,  brush.drawPolygon(xy[0], xy[1], xy[0].length);

However, I was not happy with the 15fps it was dipping too when polygon count would reach 15-20k. So I decided to try out lwjgl. Here's some code snippet I copied from a previous project before lwjgl 3 had come about, and was very happy with performance,
            glColor3fv(color);
            GL11.glBegin(GL11.GL_POLYGON);
            for (byte i = 0; i < vertices.length; i += 2)
               GL11.glVertex2d(vertices, vertices[i + 1]);
            GL11.glEnd();

But for learning's sake, I wanted to get a little familiar with the newer way of drawing in opengl. So I tried figuring out from tutorials and the online reference and eventually arrived at this working snippet (not included in the snippet is a glclear and glfwSwapBuffers that each happens once per frame):
            glColor3fv(color);
            FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
            verticesBuffer.put(vertices).flip();
            int vboID = glGenBuffers();
            glEnableVertexAttribArray(0);
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
            glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);
            glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
            glDrawArrays(GL_QUADS, 0, vertices.length);

Unfortunately, this last snippet, was dropping painfully slow even at 1000 polygon count, which was disappointing, but also indicated that must not be the correct way of doing things.
I'm not sure if I can group up all my draw's into 1 giant array and only call glDrawArrays once, since I think only the last glColor would then be applied to all the quads. Nor do I want to include the color per vertex, since doing so seems to require writing a shader or something, and that seems like overkill for my requirement.
Additionally, if it matters, vertexes are in 2D coordinates. I do the 3d -> 2d transformation and lighting -> color calculations with java+math rather than opengl. Hence my reluctance to write shaders or anything too complicated.

Thanks,
Offline elect

JGO Knight


Medals: 42



« Reply #1 - Posted 2017-05-16 15:43:22 »

forget glColor3fv, it's deprecated

this should be executed only once:

FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices).flip();
int vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);


and then in the loop

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glDrawArrays(GL_QUADS, 0, vertices.length);


If you need to change the vertices all together with the same transformation, you need to use matrices, otherwise bind again vboID and call glbufferSubData
Offline Riven
Administrator

« JGO Overlord »


Medals: 1310
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #2 - Posted 2017-05-16 16:08:48 »

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

It's showing its age somewhat, but should be enough to get you started Pointing

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline buddyBro
« Reply #3 - Posted 2017-05-17 03:56:48 »

Thank you both. I'll look at that intro and see what happens.

@Elect, just to clarify, you mean something like the following?

float[] accumulatedVerticies; // reset empty at beginning of each frame

void oncePerPolygon(float[] verticies) {
  glEnableVertexAttribArray(0);
  glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
  glDrawArrays(GL_QUADS, 0, vertices.length);
  // accumulatedVerticies = accumulatedVerticies . append . verticies;
}


void oncePerFrame() {
  FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(accumulatedVerticies.length);
  verticesBuffer.put(vertices).flip();
  int vboID = glGenBuffers();
  glBindBuffer(GL_ARRAY_BUFFER, vboID);
  glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);
}

If that's what you mean (though I have a feeling I misunderstood you), I could just move all but the last line of the oncePerPolygon into the oncePerFrame, and just have the oncePerPolygon create append to the accumulatedVerticies, right?

Well, I just tried that, having the following execute once per frame:

         x = new LinkedList<>();
         
         // here i loop over polygons and add vertices to x.

         float[] y = new float[x.size()];
         for (int i = 0; i < y.length; i++)
            y = x.get(i);
         
         FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(y.length);
         verticesBuffer.put(y).flip();
         int vboID = glGenBuffers();
         glEnableVertexAttribArray(0);
         glBindBuffer(GL_ARRAY_BUFFER, vboID);
         glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);
         glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
         glDrawArrays(GL_QUADS, 0, y.length);
         
         glfwSwapBuffers(window);

And the result was the same 1-3 fps at just a 1000 polygon count.
Yes vertices change every frame, since these are not 3d world coordinates, but the 2d screen-projected coordinates.
Offline abcdef
« Reply #4 - Posted 2017-05-17 04:47:58 »

You are creating a brand new vbo every frame, create the vbo once and update that vbo only if the data changes. By creating a new vbo every frame you are creating new memory blocks on the GPU every frame.

You are also creating a new FloatBuffer every frame. Don't. Create it once and reuse it.

Remember a vbo is just a pointer to memory on the gpu that holds vertex data and the FloatBuffer is the memory the CPU uses to hold the data locally and update the GPU when necessary.
Offline buddyBro
« Reply #5 - Posted 2017-05-17 14:59:54 »

@abcdef, per your suggestion, I've moved the floatBuffer creation to once per execution instead of once per frame, and just do .clear each frame. Likewise moved the int vboID = glGenBuffers(); line to once per execution instead of per frame.


        // once per execution
   FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(1000 * 100 * 10);
   int vboID = -1;

   public void oncePerFrame() {
         x = new LinkedList<>();
         
         glClear(GL_COLOR_BUFFER_BIT);

               // here i loop over polygons and add vertices to x.
         
         float[] y = new float[x.size()];
         for (int i = 0; i < y.length; i++)
            y = x.get(i);
         
         if (vboID == -1) {  // once per execution
            vboID = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, vboID);
         }

         verticesBuffer.clear();
         verticesBuffer.put(y).flip();
         glEnableVertexAttribArray(0);
         glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_DYNAMIC_DRAW);
         glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
         glDrawArrays(GL_QUADS, 0, y.length);
         
         glfwSwapBuffers(window);
      }

And did not see any improvements.

I feel bad for posting prior to having a chance to reading Riven your link, but just wanted to try and provide update on the suggestions. I'll be reading that as my next step.
Offline abcdef
« Reply #6 - Posted 2017-05-18 12:39:43 »

Can you define what you mean by once per execution and once per frame?
Offline buddyBro
« Reply #7 - Posted 2017-05-18 14:04:09 »

By once per execution, I mean it will execute on initialization or first frame, but no more.
By once per frame, I mean it will be executed on each iteration of the game/draw loop
Offline abcdef
« Reply #8 - Posted 2017-05-18 14:55:20 »

Why are you updating every single vertex each frame?
Offline buddyBro
« Reply #9 - Posted 2017-05-18 15:01:45 »

Because I'm projecting the 3d world coordinates to 2d screen coordinates myself. Hence, since the camera moves every frame, the vertices will be modified as well.
Is this indicative that I'm approaching this the wrong way? I.e., if I'm modifying all vertices every frame, should I not be using vbo's?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

« JGO Spiffy Duke »


Medals: 945
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #10 - Posted 2017-05-18 15:14:53 »

Aside: Never use Java's LinkedList! And in any language, you'd never willingly use LinkedList::get(index), as the whole point of LinkedLists is that they are not random access.

Another aside: why project the 3D coordinates yourself when OpenGL can do this for you? Then you simply update the camera's frustum matrix every frame instead, and the coordinates of your vertices never actually change.

Cas Smiley

Offline buddyBro
« Reply #11 - Posted 2017-05-23 14:56:26 »

Thank you everyone for helping!  Smiley

@Riven, I followed the examples in that link, and got it to work. Thanks for the link Smiley
@Elect Thanks for pointing that out, I'm now using colors the way those examples do rather than glColor3fv.
@Princec, those examples were just to show the results of attempting the suggestions, I converted the linked lists to arrays once I followed the link's example and got the code to work. I will keep that 2nd aside in mind for future projects I do, but for this one, the majority of the project is to do the projection manually and only feed lwjgl the 2d screen coordinates.

Here's the code that I put together closely following the link example,

            bufferLen = 0;
            colorLen = 0;
            glClear(GL_COLOR_BUFFER_BIT);
            painterQueue.paint(this); // this fills out vertexArray and colorArray, and increments bufferLen and colorLen
            painterQueue.drawReady = false; // to indicate to engine thread to we're ready to draw another frame
            
            vertexBuffer.clear();
            vertexBuffer.put(vertexArray).flip();
            colorBuffer.clear();
            colorBuffer.put(colorArray).flip();
            
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_COLOR_ARRAY);
            
            glColorPointer(3, GL_FLOAT, 0, colorBuffer);
            glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
            glDrawArrays(GL_QUADS, 0, bufferLen / 2);
            
            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_COLOR_ARRAY);

            glfwSwapBuffers(window);
Pages: [1]
  ignore  |  Print  
 
 

 
cybrmynd (138 views)
2017-08-02 12:28:51

cybrmynd (158 views)
2017-08-02 12:19:43

cybrmynd (153 views)
2017-08-02 12:18:09

Sralse (168 views)
2017-07-25 17:13:48

Archive (646 views)
2017-04-27 17:45:51

buddyBro (766 views)
2017-04-05 03:38:00

CopyableCougar4 (1300 views)
2017-03-24 15:39:42

theagentd (1264 views)
2017-03-24 15:32:08

Rule (1237 views)
2017-03-19 12:43:22

Rule (1312 views)
2017-03-19 12:42:17
List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05

SF/X Libraries
by SkyAphid
2017-03-02 06:38:56

SF/X Libraries
by SkyAphid
2017-03-02 06:38:32

SF/X Libraries
by SkyAphid
2017-03-02 06:38:05

SF/X Libraries
by SkyAphid
2017-03-02 06:37:51
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!