Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (761)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (845)
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  
  (Ending Discussion to other Thread) How do Vbo Textures work?  (Read 3022 times)
0 Members and 1 Guest are viewing this topic.
Offline Therobodavo

Junior Devvie


Medals: 2
Exp: 2 years



« Posted 2015-07-07 15:02:38 »

So, I know I just had a post with 40 replies, but I want to clarify one thing.

I got VBO's to work. I got them to render a texture and move, but I don't know exactly how to set a different texture for each object.

I'm assuming that with VBO's, you want to use a sprite sheet for animations and what not (switch Texture Coordinates), but what about a completely different texture for each object? I think I got it all working ok up to this point, but it's being weird.

So I have an "Abstract Creature" Class which just has default stuff for every creature.

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  
public void initVBO()
   {
     
      glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
     
      vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
        vertexData.put(new float[]{x, y, x + width, y, x + width, y + height, x, y + height});
        vertexData.flip();
       
        textureData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
        textureData.put(new float[]{0, 1, 1, 1, 1, 0, 0, 0});
        textureData.flip();

        vboVertexHandle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

       
        vboTexCoordHandle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
        glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
   }
   public void updateVBOCoords()
   {
      vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
        vertexData.put(new float[]{x, y, x + width, y, x + width, y + height, x, y + height});
        vertexData.flip();
       
        vboVertexHandle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
   }
   public void updateVBO()
   {
     
       updateVBOCoords();
     
       GL11.glColor3f(0.5f,0.5f,1.0f);
       
         glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
         glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);
         
         glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
         glTexCoordPointer(vertexSize, GL_FLOAT, 0, 0L);

         glEnableClientState(GL_VERTEX_ARRAY);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
         
         glDrawArrays(GL_QUADS, 0, amountOfVertices);
         
         glDisableClientState(GL_VERTEX_ARRAY);
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   }


As you can see, this is all of the code regarding creating/rendering the VBO. At the moment, I just draw it every frame through this code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
   public void drawCreature()
   {
      getInput();
      currentWeapon.draw();
     
      if (hasinit == false)
      {
         setTexture("PNG", "Enemy.png");
         initVBO();
         hasinit = true;
      }
      updateVBO();
   }


setTexture just uses slick to get a texture in my source file and sets it to a local variable within my "Tile" Class. The Abstract Creature Class Inherits the Tile class. So, whenever I create a new creature, I just copy the drawCreature method, and change the setTexture to the correct image.

The problem I'm having is.... everything is staying as the Enemy Picture. This wasn't happening before in immediate mode, so I feel like it's once again something that I don't understand with VBO's. I never create the VBO until drawCreature, so I don't know why it always uses the Enemy picture.

If anyone has better advice for how I go about Textures in VBO's, let me know.

To be clear, this is for a 2D Side Scoller Game, and I'm using OpenGL 2. I don't even have spritesheets at the moment, I just want to be able to set the textures according to each creature I create. (So Enemy1 may have a Enemy1.png... and so on)

When I comment this line out:

1  
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());


It still renders the Enemy.png. So that just confuses me :/
Offline thedanisaur

JGO Knight


Medals: 59



« Reply #1 - Posted 2015-07-07 15:30:29 »

Well you're commenting out
1  
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
but  you still have a setTexture() method that I assume does a binding, so of course you're going to still have that texture bound. As for why every VBO has the enemy texture is because you're never changing the bound texture so openGL just uses your last bound texture.

Now, if you want to have each object render with a different texture it'll depend on how you're objects are rendered. If you have one object in each VBO then it's as simple as binding another texture before drawing the VBO. If however you're packing multiple objects into your VBO you'll need to send a texture list to your shader and index into that list to pull the correct texture.

Every village needs an idiot Cool
Offline Therobodavo

Junior Devvie


Medals: 2
Exp: 2 years



« Reply #2 - Posted 2015-07-07 15:41:46 »

This is setTexture btw.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
   public void setTexture(String type, String dir)
   {
      try
      {
            // load texture from PNG file
            texture = TextureLoader.getTexture(type, ResourceLoader.getResourceAsStream(dir));
        }
      catch (IOException e)
      {
            e.printStackTrace();
        }
    }


I'm not binding here, but yolo I might as well.

Ok I just added it so it binds in setTexture instead of what I had. It still renders the Enemy.png.

Also setTexture updates what texture is stored.... and

1  
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());


is just like texture.bind() I would assume right?

So in a sense, the texture should be updated? As for my rendering of the vbo... I have a mthod here:

1  
2  
3  
4  
5  
6  
7  
   public void draw()
   {  
      if(this.isLiving() == true)
      {
         this.drawCreature();
      }
   }


and that runs every frame in my level class.

I mean, there's only so much that I can change here lol. Is it something in VBO's like the first texture attacked to it is the only one ever? But even then I don't get why this would be an issue.

Edit: Each object has one texture, that's all I want. If I add animations later, I'll make it a spritesheet or something.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline quew8

JGO Knight


Medals: 53



« Reply #3 - Posted 2015-07-07 16:13:00 »

The texture that will be drawn is the texture that is bound at the time you call glDrawArrays(). So...

1  
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());


Put this line somewhere in your updateVBO() method (confusingly named method by the way when what it does is draw the contents of the VBO) BEFORE the call to glDrawArrays().
Offline thedanisaur

JGO Knight


Medals: 59



« Reply #4 - Posted 2015-07-07 16:13:17 »

OK, so if each object has only one texture and you have only one object per VBO then you'll do something like this every draw call:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
//enable shader

glActiveTexture(GL_TEXTURE0 + texture.id);//Tell openGL which texture bind position you're using for the next texture you bind
glBindTexture(GL_TEXTURE_2D, texture.id);//Bind the texture

//set uniforms
//set attributes
//draw
//disable attributes
//disable shader


If you forget to set the active texture then you'll always be using the same bind position, which is fine, unless you're only binding the texture during initialization, in which case you'll never bind a different texture so the last texture you bind will always be drawn at that bind position.

Every village needs an idiot Cool
Offline Therobodavo

Junior Devvie


Medals: 2
Exp: 2 years



« Reply #5 - Posted 2015-07-07 17:11:08 »

You sure? I'm using OpenGL 2 and it says glActiveTexture(int) isn't a method. :/ I googled it, and it said that was for OpenGL 4.

Edit:

I googled the method and someone said that the code for it was this

1  
2  
3  
4  
void glActiveTexture(GLenum textureUnit)
{
    currentTextureUnit = GL_TEXTURE0 - textureUnit;
}
Offline thedanisaur

JGO Knight


Medals: 59



« Reply #6 - Posted 2015-07-07 17:30:34 »

It's been around since at least 2.0, I thought earlier, but my reference doesn't say so.

https://www.opengl.org/sdk/docs/man/html/glActiveTexture.xhtml

FYI, you don't have to use active texture, you must call glBindTexture() every frame - unless you have one for your entire project, but and you might as well set it up so that you can set active textures for when you start multi-texturing with normal maps and such.

Every village needs an idiot Cool
Offline KaiHH

JGO Kernel


Medals: 521



« Reply #7 - Posted 2015-07-07 17:31:49 »

I googled it, and it said that was for OpenGL 4.
glActiveTexture is OpenGL 1.3, actually.
And the code you posted, is a) wrong: if any it should be textureUnit - GL_TEXTURE0, and b) this is - if anything - driver code, which you cannot just emulate or implement yourself in Java (where should the variable 'currentTextureUnit' come from?), as it changes the OpenGL state and affects other OpenGL functions, such as glBindTexture.
Offline Therobodavo

Junior Devvie


Medals: 2
Exp: 2 years



« Reply #8 - Posted 2015-07-07 17:50:32 »

Oh, I have to call it every frame? :/ I'll go try it, but when I did that before (with immediate mode), it caused mad frame lag and was unplayable.
Offline Therobodavo

Junior Devvie


Medals: 2
Exp: 2 years



« Reply #9 - Posted 2015-07-07 18:12:50 »

Ok so it works fine now, I get what I did wrong. I just needed to bind the texture every frame I guess :/. It's running fine for what I'm rendering, but I need to try with projectiles and everything. I just made it so I only "set" the texture once, and just bind it every frame.

Thanks for all the help Smiley.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline thedanisaur

JGO Knight


Medals: 59



« Reply #10 - Posted 2015-07-07 18:21:46 »

@Therobodavo: I can tell you right now glBindTexture() will not be a point of contention for cpu cycles, it is one of the fastest openGL calls. All it does is grab a pointer and say here's the texture to use.

Make sure to watch out for rebuilding textures every frame, you don't want to do that. Calls like this will get you into trouble if you do them every frame (don't mind the gl. prefix):
1  
2  
3  
4  
5  
6  
7  
8  
9  
gl.glGenTextures(1, texture.m_id, 0);
      gl.glBindTexture(GL.GL_TEXTURE_2D, texture.m_id[0]);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrap_func);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrap_func);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
      gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, texture.m_bytes_per_pixel, texture.m_width, texture.m_height,
                  0, texture.m_type, GL.GL_UNSIGNED_BYTE, texture.m_image_data);
      gl.glGenerateMipmap(GL.GL_TEXTURE_2D);

Every village needs an idiot Cool
Pages: [1]
  ignore  |  Print  
 
 

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

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

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

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

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

nelsongames (810 views)
2018-04-24 18:14:32

ivj94 (1251 views)
2018-03-24 14:47:39

ivj94 (395 views)
2018-03-24 14:46:31

ivj94 (1058 views)
2018-03-24 14:43:53

Solater (413 views)
2018-03-17 05:04:08
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

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
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!