Hi !
Featured games (85)
games approved by the League of Dukes
Games in Showcase (623)
Games in Android Showcase (176)
games submitted by our members
Games in WIP (676)
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  
  VBOs and Textures  (Read 3143 times)
0 Members and 1 Guest are viewing this topic.
Offline Gjallar

JGO Coder

Medals: 23
Projects: 1

Follower of Nurgle

« Posted 2012-04-18 18:34:15 »

Good evening fellow nerds.

I've been searching through the depths of the internet but couldn't really find a solution for my problem.

I'm experimenting with VBOs since you hear every that glBegin()/glEnd() is a big no-no in terms of performance. I'm trying to put a neat texture (org.newdawn.slick.opengl.Texture) on my square.
This worked just fine with the no-no method as seen below.

   public void draw(float xPos, float yPos){
         glTexCoord2f(0, 0);
         glVertex2f(0, 0);
         glTexCoord2f(1, 0);
         glVertex2f((float)width, 0);
         glTexCoord2f(1, 1);
         glVertex2f((float)width, (float)height);
         glTexCoord2f(0, 1);
         glVertex2f(0, (float)height);

But now that I'm trying to do the same with a VBO I'm kind of running against a wall.
I have the following so far...

public class Tile extends Entity {
   final int amountOfVertices = 4;
    final int vertexSize = 3;
    int vboVertexHandle;

   public Tile(float x, float y, int width, int height, Texture texture) {
      super(x, y, width, height, texture);
        FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
        vertexData.put(new float[]{x, y, 0, x + width, y, 0, x + width, y + height, 0, x, y + height, 0});
        vboVertexHandle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
   public void draw(float xPos, float yPos){
      glTranslatef(xPos, yPos, 0);
      glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);
        glDrawArrays(GL_QUADS, 0, amountOfVertices);

Honestly, I'd lie if I'd say that I understand what exactly this code does but I guess I understand the "most important part"

    vertexData.put(new float[]{x, y, 0, x + width, y, 0, x + width, y + height, 0, x, y + height, 0});

Now I assume that I have to specify the Texture's coordinates just like the above, but everything I tried so far didn't seem to work.
Simply texture.bind() (of course) doesn't do the trick since I haven't specified it's coordinates. It just paints the whole Quad in the color of the first pixel of the .png file (i think?!?).

So yeah, help very much appreciated, I hope my post was detailed enough  Grin
Brb, shower.
Offline lhkbob

JGO Knight

Medals: 32

« Reply #1 - Posted 2012-04-18 22:34:18 »

You need to create another VBO for your texture coordinates. The glBindBuffer(), glBufferData(), etc. calls are basically the same except you fill it with your texture coordinates.

After you bind and configure the vertices (glBindBuffer(..., vboVertexHandle); glVertexPointer(...)) you need to configure the texture coordinates by calling glBindBuffer() with the texture vbo handle, and glTexCoordPointer().  You will also need to enable the GL_TEXCOORD_ARRAY client state (that name might be slightly incorrect, I'm doing this from memory).

Lastly, a more general note about VBOs and OpenGL:
A vertex in OpenGL is the composition of all of its attribute values. A vertex can have multiple attributes, such as position, normal vector for lighting, and texture coordinates.  If you need to have a position use different normals or texture coordinates depending on which polygon it belongs too, those permutations represent different vertices according to OpenGL, and you'd need to duplicate the position but specify the new values for the other attributes.

Since you're only doing tiles right now that are composed of single quads, this won't be a problem for you.

Lastly, with your current approach you're unlikely to see any significant performance gain with VBOs.  VBOs, as you've noticed, require more OpenGL calls to configure the correct state before rendering actually begins.  For very small meshes (i.e. your single quad tile), this configuration is going to outweigh the performance benefit gained from the faster actual rendering.  VBOs begin to shine when you start having hundreds and thousands of vertices used in a single draw call.

You can however pack all of your tiles that use the same texture into a single VBO and render multiple tiles at once.  When done properly this will be faster.  This should not dissuade from continuing your approach since the skills you're learning now will help you later on and VBOs are valuable tools to learn about, but don't be upset if the immediate gains aren't as big as you'd hope.

Offline msiggy

Senior Newbie

« Reply #2 - Posted 2012-07-13 16:14:12 »

Gjallar, I am in a similar situation to you. I am about to switch away from the fixed pipeline to try and find better performance. However the only thing i render in my game is textured quads. Did you see a performance increase by using VBO's for just textured quads?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #3 - Posted 2012-07-13 19:34:42 »

Generally speaking the performance difference will be negligible unless you are rendering thousands of sprites. However, if you have the time and dedication to spare, I’d still suggest going as far into the “programmable pipeline” as you can, rather than relying on the fixed function pipeline:
- It will make you a more skilled graphics programmer. You’ll have a better understanding of the pipeline and how to optimize for it.
- Your newfound knowledge will open up doors to some very cool areas – e.g. shader effects.
- Your graphics engine (and skills) will be easier to port to mobile devices and WebGL
- Your skills will be more applicable if you later decide to enter the game, animation or film industry.
- It will force you into a different way of thinking (using shaders, batches, etc) that will ultimately improve performance in many areas.

What kind of rendering technique you choose depends on what kind of hardware you are targeting:
- OpenGL 1.1 – OpenGL 2.0: Batch your sprites using vertex arrays
- OpenGL 2.0 – OpenGL 3.0: Batch your sprites using vertex arrays or VBOs
- OpenGL 3.0 + use geometry shaders or instancing -- if unsupported, fall back to batching with VBO/VAO

A 2D “sprite batch” works like this: You make a single large array of floats (technically a FloatBuffer). Let’s say you are rendering 2 triangles per sprite -- i.e. 6 vertices -- and the following eight attributes per vertex: position (x, y), texcoord (u, v) and color (r, g, b, a). If you’re expecting to render 1000 sprites per frame, your array might have a size of (1000 * 8 * 6) = 48,000 elements.

Then, your drawSprite() method wouldn’t actually do any rendering. Instead, it would just place the sprite’s vertex information (6 vertices each with position, colour and texcoords) into the array, and increment the index pointer. The actual rendering is done when (a) a new texture needs to be bound, (b) we have reached the capacity of our FloatBuffer, or (c) the user has forced a “flush.” Rendering the buffer requires glDrawArrays or something similar, and then resetting our index pointer to zero so we can start over. For an example of this in action, see LibGDX’s SpriteBatch.

If you are targeting < OpenGL 3.0, I’d personally suggest starting with vertex arrays instead of VBOs. They require less setup and tend to be easier to work with. Once you’re comfortable with vertex arrays, VBOs will be easier to grasp.

And in this case, VBOs won’t be any more performant. Generally VBOs are preferred because they allow us to hold vertex data on the GPU instead of transferring it every frame. But since most 2D sprite batches (like LibGDX’s) will be transferring the entire array every frame, you aren’t going to see much of an improvement, if any. (An exception to this might be mapped VBOs, which I haven’t tested.)

Offline theagentd

« JGO Bitwise Duke »

Medals: 564
Projects: 4
Exp: 8 years

« Reply #4 - Posted 2012-07-13 23:08:49 »


- The standard minimum requirement for anything today is DirectX 9 hardware, which is equal to OpenGL 2.x, VBOs are pretty much always supported since they we're introduced in OGL 1.5.
- Mapped VBOs can win you some performance since it avoids an extra copy of the data.

Pages: [1]
  ignore  |  Print  
You cannot reply to this message, because it is very, very old.

basil_ (42 views)
2015-09-30 17:04:40

shadowstryker (21 views)
2015-09-29 15:55:06

TheSpaceHedgehog (27 views)
2015-09-29 01:58:48

GamerC4 (50 views)
2015-09-24 21:10:38

GamerC4 (70 views)
2015-09-24 21:09:48

htuy (27 views)
2015-09-24 04:57:24

htuy (36 views)
2015-09-24 04:56:35

htuy (25 views)
2015-09-24 04:56:09

htuy (26 views)
2015-09-24 04:47:33

Roquen (64 views)
2015-09-21 12:54:28
Math: Inequality properties
by Roquen
2015-10-01 13:30:46

Math: Inequality properties
by Roquen
2015-09-30 16:06:05

HotSpot Options
by Roquen
2015-08-29 11:33:11

Rendering resources
by Roquen
2015-08-17 12:42:29

Rendering resources
by Roquen
2015-08-17 09:36:56

Rendering resources
by Roquen
2015-08-13 07:40:51

Networking Resources
by Roquen
2015-08-13 07:40:43

List of Learning Resources
by gouessej
2015-07-09 11:29:36 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‑
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!