Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (575)
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  
  Repeated GL Pointer Call Inquiry  (Read 840 times)
0 Members and 1 Guest are viewing this topic.
Offline Anteka

Junior Newbie





« Posted 2014-03-19 00:53:57 »

Hey everyone, I'm currently working on something for OpenGL ES 2, and I have a question regarding the glEnableVertexAttribArray() and glVertexAttribPointer() calls.

I more or less understand what they do. However, I'm curious as to if it's necessary to call them every single time you send data to the GPU. Basically I'm calling them once each for both the XYZ coordinates and the UV coordinates, then sending my data from a FloatBuffer with glBufferSubData(). I'm then calling glDrawElements() as I'm drawing via indices.

I'm wondering, though, if I can avoid making these four calls every single time I draw. Any advice regarding whether or not this is possible would be greatly appreciated.

If it was an option, I would just use VAOs, but I'd prefer not to use any of the extensions as I want to ensure device compatibility.

Thank you in advance!

Edit: Completely forgot to mention that I'm swapping between two VBOs and that they're dynamic. My index buffer is, of course, static.
Online The Lion King
« Reply #1 - Posted 2014-03-19 01:12:39 »

You can keep it on as your are doing draw calls, assuming you keep the same ones on for every draw call, you should turn them off after you are done doing draw calls, though you don't necessarily have to.

"You have to want it more than you want to breath, then you will be successful"
Offline Anteka

Junior Newbie





« Reply #2 - Posted 2014-03-19 01:30:27 »

Thank you, The Lion King, for the quick response!

By "keeping the same ones on for every draw call," do you mean if my buffer is static, or is that in regard to something else? One thing I completely failed to mention is that I'm swapping between two dynamic vertex buffers, and that I'm consistently filling them with new data.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online The Lion King
« Reply #3 - Posted 2014-03-19 01:34:38 »

That's not a problem, and I'll give you an example of what I meant. Sometimes I draw objects and pass in color values to the shader so I disable the texture cord attribute and turn on the color one. This is the only time you have to worry about it. If you don't have a similar situation don't worry about it

"You have to want it more than you want to breath, then you will be successful"
Offline theagentd
« Reply #4 - Posted 2014-03-19 01:41:57 »

Upload your vertex data to a VBO and glVertexAttribPointer() no longer <uploads> any data, it simply tells OpenGL where to find it. Finally you can set up your vertex attributes once in a VAO and you only have to bind the VAO before rendering.

Myomyomyo.
Offline Anteka

Junior Newbie





« Reply #5 - Posted 2014-03-19 04:18:53 »

Thanks for the responses thus far! I figured something out with regard to my current setup that might narrow down my inquiry. Previously I had tried calling those two methods only once--setting and forgetting them, in other words. But, I noticed it ended up making everything look choppy. The speed was the same, but things weren't quite smooth. So, I tried removing the VBO swapping I have going on, and it removed the choppiness. Basically, it was drawing from one VBO and ignoring the other, so it would only draw every other frame. In other words, it seems as though I'm required to call these two methods for each VBO I switch to. I'm assuming this is due to the fact that we have to inform OpenGL where to find data for that particular buffer, or something like that. Apologies for my lack of insight; I'm still not sure entirely how these two methods function on a lower level.

I guess what I'm wondering, then, is if there's any way to specify this data for both of the VBOs and have OpenGL remember it, if that's at all possible. While I've read the documentation, I'm not entirely sure what these two calls are doing under the hood. Also, theagentd, I would use a VAO but I'm using ES 2 and I don't want to use extensions.

Also, it might help if I post the general flow of my drawing method, so here it is.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
// Bind the active texture and VBO.
glBindTexture();
glBindBuffer();
// Call methods for XYZ coordinate data.
glEnableVertexAttribArray();
glVertexAttribPointer();
// Call methods for UV texture coordinate data.
glEnableVertexAttribArray();
glVertexAttribPointer();
// Send vertex data to the GPU.
glBufferSubData();
// Bind the IBO.
glBindBuffer();
// Draw the quads.
glDrawElements();


Thank you again for your help!
Offline theagentd
« Reply #6 - Posted 2014-03-19 23:41:40 »

Thanks for the responses thus far! I figured something out with regard to my current setup that might narrow down my inquiry. Previously I had tried calling those two methods only once--setting and forgetting them, in other words. But, I noticed it ended up making everything look choppy. The speed was the same, but things weren't quite smooth. So, I tried removing the VBO swapping I have going on, and it removed the choppiness. Basically, it was drawing from one VBO and ignoring the other, so it would only draw every other frame. In other words, it seems as though I'm required to call these two methods for each VBO I switch to. I'm assuming this is due to the fact that we have to inform OpenGL where to find data for that particular buffer, or something like that. Apologies for my lack of insight; I'm still not sure entirely how these two methods function on a lower level.

I guess what I'm wondering, then, is if there's any way to specify this data for both of the VBOs and have OpenGL remember it, if that's at all possible. While I've read the documentation, I'm not entirely sure what these two calls are doing under the hood. Also, theagentd, I would use a VAO but I'm using ES 2 and I don't want to use extensions.

Also, it might help if I post the general flow of my drawing method, so here it is.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
// Bind the active texture and VBO.
glBindTexture();
glBindBuffer();
// Call methods for XYZ coordinate data.
glEnableVertexAttribArray();
glVertexAttribPointer();
// Call methods for UV texture coordinate data.
glEnableVertexAttribArray();
glVertexAttribPointer();
// Send vertex data to the GPU.
glBufferSubData();
// Bind the IBO.
glBindBuffer();
// Draw the quads.
glDrawElements();


Thank you again for your help!

First some information on shader attributes. Let's say you have a shader with two vertex attributes:
in vec3 position
bound to location 0 and
in vec2 texCoords
bound to location 1. You bind this shader. Then you bind your VBO, enable vertex attribute location 0 and call glVertexAttribPointer() for location 0 with correct values to read some position data from your VBO.

What does this do? If you answered "tells OpenGL where it should read data for the shader attribute 'position' from and also how OpenGL should interpret the data in that VBO", you'd be wrong. Although that is the result, that is not what these calls do. These calls have no connection with the currently bound shader. When you call glEnableVertexAttribArray(0), OpenGL does not enabled the position attribute; it simply says that "attribute 0 should be read from an array". What "attribute 0" refers to has not been decided yet, and may be changed if a different shader is bound. Hence, it's perfectly okay to completely change the order of the above commands and get the exact same result as above:

Bind VBO --> enable vertex attribute 0 --> glVertexAttribPointer(0, ...) ---> bind shader.

The actual connection isn't done until you actually render something. When you call glDrawArrays(...) or glDrawElements(), OpenGL will look at the vertex attributes of the current shader and do the following (some kind of pseudo code:

1  
2  
3  
4  
5  
6  
int location = locationOfAttribute(attributeName); //= 0 for "position"
if(glEnableVertexAttribArray(location) has been enabled){
    read data from the VBO that was bound when glVertexAttribPointer(location, ...) was called and interpret it as specified by glVertexAttribPointer(location, ...).
}else{
    use value of glVertexAttrib*(location, ...);
}

The fact that the attribute information about which attributes are enabled and what their values are is global state in OpenGL means that if you ever want to read attributes in more than one way in your entire program, you'll need to set up your vertex attributes each time you want to read them in a different way or from a different VBO from your last render call.



VAOs are meant to solve this. Called Vertex ARRAY Objects, these objects do not store any data actual data (the vertex data still lies in VBOs), but it does store vertex attribute state, so vertex attribute state is no longer global; it is tied to the currently bound VAO. Therefore, you can do the following once:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
int vao = glGenVertexArrays();
glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, myVbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ...);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, myIbo);

glBindVertexArray(0); //Unbind the VAO.


At this point, glEnableVertexAttribArray(0) and glVertexAttribPointer(0, ...) are "stored" in the VAO, including which buffer was bound when glVertexAttribPointer() was called (myVbo). Also, the VAO will store the call to glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, myIbo) for reading vertices. It will however NOT store the call to glBindBuffer(GL_ARRAY_BUFFER, myVbo). Which buffer is currently bound is stored when glVertexAttribPointer() is called. When we later want to render stuff, we can simply do the following:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
//Update VBO
glBindBuffer(GL_ARRAY_BUFFER, myVbo);
glBufferSubData(...);


glUseProgram(myShader);
glBindTexture(...);
glBindVertexArray(myVao);

glDrawElements(...);

VAOs are meant to do exactly what you're trying to do (to avoid having to set up vertex attributes each frame), and it cannot be done without VAOs.




More information: https://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object

Myomyomyo.
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.

Longarmx (33 views)
2014-10-17 03:59:02

Norakomi (25 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (26 views)
2014-10-15 16:18:58

TehJavaDev (50 views)
2014-10-14 00:39:48

TehJavaDev (50 views)
2014-10-14 00:35:47

TehJavaDev (40 views)
2014-10-14 00:32:37

BurntPizza (63 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (74 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

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

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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!