Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » 3D game design + my skybox works!

This thread is locked; no one can reply to it. rss feed Print
 1   2   3   4 
3D game design + my skybox works!
Eric Johnson
Member #14,841
January 2013
avatar

A few things:

1. I'm brand new to OpenGL/WebGL, so I'm bound to make stupid mistakes.
2. I'm only interested in 2D for the time being.
3. My triangles are drawn to pixel space relative to the top left being the origin (0, 0) and are then converted to clip space in the vertex shader. I don't think the orientation of the vertices matter, but I could be wrong.

I'm no statistics guy, but won't at least half (or 2/3rd?) of those have the wrong orientation (clockwise vs counterclockwise) and be culled?

Those are pixel co-ordinates. I convert them to clip space in my vertex shader. I did this because I'm only concerned with 2D right now, and I want things to be indexed in pixel space at (0, 0) at the top left of the screen. I don't think the orientation of the vertices matter, but I could be wrong. The vertices essentially look like this: x1, y1, x2, y2, x3, y3. Those are X and Y pairs in pixels for the three points of the triangle.

Quote:

What hardware are you running on? CPU/videocard.

AMD FX 4300 @ 3.8 GHz and GTX 1060 (6GB).

I'm brand new to OpenGL/WebGL, so I'm bound to make stupid mistakes. I don't claim to know what I'm doing, but I'm trying.

Say I want to write a 2D graphics library in OpenGL. Say I have a drawTriangles() function that takes six floats as the X and Y points of the triangle. Each time I call it, it would create the buffer, bind it, set the vertices in pixels (later converted to clip space in the vertex shader), and then call drawArrays() to actually draw the points. If I do this many times, the performance will be terrible, because it's creating a new buffer each time. :-/ I'm not sure how I could fix this. I'm not sure how I could reuse buffers if the vertices are expected to change between frames. Is it possible to create a single triangle and then change its vertices without touching the buffer again? Like change it in the vertex shader itself by setting a uniform or something? If so, how?

Neil Roy
Member #2,229
April 2002
avatar

I'm no statistics guy, but won't at least half (or 2/3rd?) of those have the wrong orientation (clockwise vs counterclockwise) and be culled?

It's possible as clockwise winding = facing away from the camera. On flat 2D textures it won't make much of a difference unless you have backface culling enabled. But it's a good idea to stick to counterclockwise winding.

Quote:

I'M NO EXPERT on OpenGL, but, I believe the point of a VBO would be you build it once, and then say "draw my combined object." That's the savings.

Yeah, VBOs are still used with shaders. They are not display lists. They are as you said, a method to store all the object data on the video card for faster, easier access. You can also set things up for instancing which is a super fast way to redraw the same object over and over again with very little performance hit.

Here's a video I created of an asteroid field which has 20K asteroids, each one consists of over 576 vertices totaling around 11.5M vertices. But because the same asteroid object, already in video memory, is redrawn over and over again, just scaled, rotated and translated differently... it can do it blazingly fast.

video

It would be interesting to try doing this same demo with WebGL and see what sort of performance it gets. It's actually not all that much code for this, relatively speaking.

I don't think the orientation of the vertices matter, but I could be wrong.

The problem lies in the order which you send your vertices to WebGL/OpenGL. There is clockwise order, like... the upper left corner first, then the upper right, then the lower left... that would be clockwise, where as the upper left, then lower left, then upper right would be counter-clockwise. In OpenGL, the default order for a face which is... facing you, is counter-clockwise. If you send the vertices in clockwise order, that means the face is facing away from you and you are looking at the backside of it. Now if you have backface culling turned off, not much of a problem, you'll see both sides with a flat polygon. If you enable backface culling, you will see only the side which is facing you, and then it will become a problem.

Here's a good example I googled. You can see the texture on the counter clockwise winding, but not with the clockwise winding, because it is facing away from the camera.

{"name":"611377","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/8\/488ba0f25971e9c5ebc74c5f4a05c9ec.png","w":640,"h":320,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/8\/488ba0f25971e9c5ebc74c5f4a05c9ec"}611377

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

Neil Roy said:

You can also set things up for instancing which is a super fast way to redraw the same object over and over again with very little performance hit.

Could you tell me a little bit about "instancing"? This is the first I've heard of it.

Quote:

It would be interesting to try doing this same demo with WebGL and see what sort of performance it gets.

WebGL should be comparable in performance to however OpenGL ES 2.0 would perform natively. At least once everything's on the GPU. Any state changes done on the CPU would be slower than native though, due to the overhead of JavaScript.

Neil Roy
Member #2,229
April 2002
avatar

There's only one tutorial that I have found on the web about how to do this. Could be more, but I haven't seen any. Which surprises me as this is such an amazing thing as you could see in that last video (and your system is FAR better than mine, I only have an 8 year old CPU and GTX650 video!).

This uses a function called: glDrawElementsInstanced()

You create an array of matrices, in this case, 20000 in size to hold a matrix for each instance of the same object. This way you can use each matrix to change each object's transformation, rotation and scale.

I'll try and find the tutorial online again and post a link here, it was one of the better ones on OpenGL and shaders.

https://learnopengl.com/

The one on instancing is in the advanced opengl section.

Note: he has a PDF you can download of that site as well.

Edit: I just realized he does a FLAT 2D example first, so that's right up your alley!

On that website tutorial, he drew 100K asteroids at 57M vertices!!! My system is a tad slow at that number, I found 20K to be comfortable. You can do it on y our system though.

I almost forgot, I posted a link to a video on doing instancing in Java game programming! (I am "Night Hacker" on that site if you look in the comments).

video

This is a series you should check out, it seems right up your alley.

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

Thanks for the links and info, Neil. I'll check them out later in the day (it's 01:34 here; happy day of celebrating Jesus' resurrection, by the way).

Also, as far as triangles are concerned, I think I might be able to re-use a buffer and its vertices. Instead of creating or changing the buffer each time, I might be able to pass in some data to a few uniforms to change the vertices inside the vertex shader. Maybe I could get the current vertex count and then use one of the uniforms as appropriate. That would surely help some. Maybe gl_VertexID will do the trick?

Edit:

Looks like gl_VertexID isn't a thing in OpenGL ES 2 (nor WebGL by extension). :-/ Is there another way to get the current vertex count in a buffer?

Neil Roy
Member #2,229
April 2002
avatar

Did you check out that video? He does instancing in Java so that would probably be the best bet. Heck, the whole series should be amazing if you like developing for the web. What that guy does with Java and 3D is great. I skimmed though his tutorials, but didn't actually code much of them. What can I say, I like my C + OpenGL, I definitely don't want to use a limited version of OpenGL. ;)

I'm getting all pumped up to do some OpenGL stuff again, glad I read and replied in here. Been needing something to do, haven't been in the programming mood at all lately which sucks as I have been a die hard programmer since around 1980!! ;D

---
“I love you too.” - last words of Wanda Roy

Chris Katko
Member #1,881
January 2002
avatar

Sidenote:

AMD FX 4300 @ 3.8 GHz and GTX 1060 (6GB).

WHAT?!?!?!?!?

You are absolutely, CPU limited. Time to upgrade!

Average rating 4672 (single 1411): https://www.cpubenchmark.net/cpu.php?cpu=AMD+FX-4300+Quad-Core&id=1814

I've got the SAME videocard and a next generation (from yours) CPU, and I'm CPU limited on modern games! :o Here's mine:

Average rating 9019 (single 1534): https://www.cpubenchmark.net/cpu.php?cpu=AMD+FX-8370+Eight-Core&id=2347

And all my friends basically put my CPU to shame. My CPU costs like... $80-$110 nowadays and it's not even worth that.

https://www.cpubenchmark.net/high_end_cpus.html

If I just got a comparable Intel with the same videocard, I'd get at least 10-15 FPS more on PUBG (going from "decent" to "enjoyable" ~80 FPS with spikes down to 55)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Eric Johnson
Member #14,841
January 2013
avatar

I haven't checked out the video yet (it's late and I don't want to wake anyone with sound from a video). But I will later. ;) Also, the video is Java, not JavaScript. There's a difference. :P

I've devised a solution to the edit from my last post. Instead of passing the triangle's vertices in pixels and then converting them to clip space, I instead pass them like "normal" from -1.0 to 1.0. Then, in my shader, I have three uniforms: p1, p2, p3--they're all vec2. I then check the points of my triangle in the vertex shader and assign them to p1, p2, or p3 as needed. So this way I think I should be able to reuse the same buffer but change the vertices in the shader! It'll take some more testing to be sure.

Chris Katko
Member #1,881
January 2002
avatar

Neil Roy said:

Now if you have backface culling turned off,

Even with off, won't lighting be broken? IIRC, backface culling isn't just for performance, but the lighting/tangent math comes out backwards and broken.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Neil Roy
Member #2,229
April 2002
avatar

LMAO, yeah, I watched a video just the other day where some guy said "Javascript" is the worst name for a language ever because it is neither JAVA, nor is it a Scripting language. That really cleared up my confusion. ;)

Still, I would imagine there are similar solutions or hey, why not code in Java instead? <shrug> I don't know much about the differences. I'll stick to good old C, no bloody #, no bloody Obj, no bloody ++! ;) :P

Note: as for the tradition which takes place today, thanks for the kind sentiment, but no. I don't do it. I'll just leave it at that. I did have my unleavened bread and wine Thursday night though. That may give you a clue what I do. ;)

Even with off, won't lighting be broken?

Yep. If the face isn't facing you, it won't be lit properly. At least in 3D.

You CAN change the winding you prefer to CW if you wish, I don't know if WebGL supports changing it or not. In OpenGL it is glFrontFace(GLenum mode); where mode is either GL_CW or GL_CCW. It defaults to GL_CCW of course.

There's some good info on it here... https://www.khronos.org/opengl/wiki/Face_Culling

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

My test works! I can change the position of the vertices in my shader without changing my buffer! I'll have to test drawing multiple triangles soon to see if performance is improved any.

You are absolutely, CPU limited. Time to upgrade!

Yeah, I know. :P I've been meaning to upgrade since January, but am waiting for non Z370 motherboards to come out. I'll probably get the i5-8400.

Edit:

Neil Roy said:

I did have my unleavened bread and wine Thursday night though.

Happy post Passover.

Neil Roy
Member #2,229
April 2002
avatar

Happy post Passover

Thanks, it was a nice relaxing evening with the wife. Wine = Baby Duck.... love that stuff!!! :)

My CPU is an AMD Athlon II X3 440, 3.0 GHz (3 core), I think it is worse than yours. ;) My GPU is a GTX650. I bought it for $100 a few years ago, they now sell for $250! It's insane, I can't see me upgrading anything, anytime soon.

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

My test works! I can change the position of the vertices in my shader without changing my buffer! I'll have to test drawing multiple triangles soon to see if performance is improved any.

Compared to changing the buffer and drawing each triangle every frame, this method of changing the vertices' positions in the shader instead yields slightly better performance. The old way yields 1,800 triangles before the frame-rate dips, whereas the new way yields 6,200 triangles. That's 3.4 times better.

This is not as good as storing the vertices' points and drawing them all in one drawArrays() call, but it does allow for each triangle to have its own color now.

I think it could still do better. I might get a little bit more performance by sending the new vertex positions to the shader as an array so I only have one function call instead of three (one for each point of the triangle). I'll have to look into instancing and doing more with buffers later. I'm calling it a night (or uh, morning now, I guess) for now though. I'll give it another go later.

Chris Katko
Member #1,881
January 2002
avatar

but it does allow for each triangle to have its own color now.

I believe there IS a way to have vertex buffer objects, but change them. Like have the same model data, but use "red color" or "taco texture".

But I've not done it. I might look it up this weekend.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Eric Johnson
Member #14,841
January 2013
avatar

I believe there IS a way to have vertex buffer objects, but change them.

I'll have to research that then. I might just be CPU bound, like you said. Even so, I can draw ~6,000 mutable triangles per frame at sixty frames per second using WebGL. That's already ~4 times better than the browser's built-in canvas 2D API, so I'm content for now.

I'll continue to look into other avenues for optimizing rendering, like maybe instancing (still haven't taken a look yet, Neil).

Neil Roy
Member #2,229
April 2002
avatar

Instancing involves things that repeat a lot, so it is limited, but if you have a scene with say, a lot of trees, all basically the same tree, or tiles of grass, it would benefit them. And when you look at 2D scenes (which you do 2D), much of a scene has a lot of repetition. That is where instancing shines and there is a WebGL command for it...

ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount);

I found a website where someone goes into it with what looks like Javascript to me...

https://blog.tojicode.com/2013/07/webgl-instancing-with.html

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

I was on that page just earlier. I haven't had the chance to try it out just yet. I'll give it a go now though.

By the way, what benefit is there to using drawElements() over drawArrays()? I can't think of a situation where I'd use drawElements()... drawArrays() seems more convenient.

Neil Roy
Member #2,229
April 2002
avatar

From what I understand (and I am fairly new to this as well)... it has to do with how much data you are sending to the card, which is always the main bottleneck in OpenGL or any graphics for that matter.

In general the DrawElements method should be faster, because if Vertices are shared by two or more faces (and it should be like that), than they aren't sent trough the bus twice or more.

In something as simple as a 3D cube, you have 6 faces, each face has two triangles. That's 12 triangles, each has three vertices, which equals 36 vertices total, even though the cube only has 8 vertices, so that's a lot of waste.

On a cube, one vertex on one corner is shared by up to six polygons (triangles), depending on they are set up.

Anyhow, 36-8 = 28 vertices being sent that don't need to be. And each vertex has three floats = 12 bytes per vertex = 36 bytes per vertex, plus any texture info, plus any colour info, multiply that by 36, that's a huge amount of wasted time, and that's just a simple cube! ;)

EDIT: Ooops, messed up my math, that's 6 faces per cube.

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

Neil Roy said:

In general the DrawElements method should be faster, because if Vertices are shared by two or more faces (and it should be like that), than they aren't sent trough the bus twice or more.

That makes sense. It shouldn't matter for me though so long as I stick to 2D. But good to know.

So I've done some experimenting since my last post...

I might get a little bit more performance by sending the new vertex positions to the shader as an array

That ended up being a bust. I can use an array in my shader, but I still have to create three variables to access the three elements of the array, and I still have to set the uniform three times per render call. So no savings here.

Also, what's the advantage to setting a uniform in a vertex shader to then pass to a varying instead of just setting a uniform in a fragment shader?

I did some tests and there appears to be no differences in performance. I guess if I don't intend on passing any color data from the vertex shader to the fragment shader, I should just stick with setting a uniform in the fragment shader instead of using a varying. That'll save a line or so in my vertex shader at least.

Here's something else I figured out: if you declare a uniform in a shader but don't use it, glGetUniformLocation() returns null. That tripped me up for almost an hour until I realized this...

Also, I haven't been able to get instancing to work right. I don't think it really matters for the 2D games I make anyway. How many triangles does one reasonably need? I just wanted to beat canvas 2D in performance, which I've already done, so that shall suffice for now.

Neil Roy
Member #2,229
April 2002
avatar

That makes sense. It shouldn't matter for me though so long as I stick to 2D. But good to know.

Well, even in 2D, if you have a quad, that is four vertices. But if it is made up of two polygons, that equals 6 vertices. Two vertices are being sent twice. Which equals:

2 vertices * 3 floats * 4 bytes per float = 24 bytes
texture co-ordinates equals 2 floats * four bytes per float = 8 bytes
colour information = 3 floats * 4 bytes per float = 12 bytes

Total wasted bytes equals 24 + 8 + 12 or 44 bytes per quad, possibly 56 bytes if you have normal information, unlikely with just 2D, but you would with 3D.

So you end up sending 168 bytes per quad instead of only 112. Multiply that by the number of quads in your scene and it could add up quickly.

Also, if you have a tiled game, than the corners of the quads will also share vertices with the quads neighbouring them, which could be as many as eight vertices at a corner all sharing the same vertex, so even at a mere vertex + texture and no colour or normal information, that's 32 bytes per vertex times 8 vertices equals 256 bytes for that corner verses only 32 for one vertex, which is 224 bytes wasted per corner in a tiled environment.

---
“I love you too.” - last words of Wanda Roy

Chris Katko
Member #1,881
January 2002
avatar

Neil Roy said:

From what I understand (and I am fairly new to this as well)... it has to do with how much data you are sending to the card, which is always the main bottleneck in OpenGL or any graphics for that matter.

Yeah, that's what I was getting at. When doing our kind of games, the bus is the first, major bottleneck you hit. And usually, you hit it, because you're doing something wrong.

And don't take that personal. I mean, we all learn the "wrong" way because we learned when computer architectures had a different layout. Just like how in A5, we have to deal with locked bitmaps because back in A4 days, memory bitmaps were FASTER than video bitmaps and you just wrote to them freely.

But the key point is, with "new" (pretty old!) OpenGL and DirectX, you want to frame your "question" of how you draw instead of: Here's a single list of stuff, each treated uniquely. You do: Here's lists of related stuff. And either each list is drawn once, or, you "mutate" the lists and draw the same list multiple times and mutate it from what's in the list into what you want (typically with a shader).

For example, you can pack basically ANY information you want into a VBO, and then send that to your shaders WITH the vertex/color/etc data. (Or simply re-purpose the color data if you're not using it.) Then, you use that data to do your extra stuff.

But the key thing is, less individual operations, and more categorical operations. Don't color a texture manually every frame by reading and writing bytes (low level operation), tell the GPU to "color it". (High level operation)

And if you need new high-level operations, you add shaders for that.

I guess it's easier to explain in 3-D games, like Neil explained. You want tons of trees, don't send a bunch of tree vertices. You send a command "draw a tree at X,Y". If you want to modify your trees? Either store various snapshots of those trees, or, use a shader to modify them as they're drawn. (Geometry Shader, IIRC, works on a "primitive (group of vertices) at a time")

Another example: (IIRC) Most 3-D models of people in games are stored in "default shape" (arms spread out, legs not bent). And then a shader bends the joints. Every time you draw that guy, it ends up a completely different angle, mutated object. But still, all you had to tell the GPU was "draw a [guy], with joint angles [3,15,6226]". It's completely mutable, but you never had to resort to sending individual data points across the bus!

[edit]

Quote:

which is always the main bottleneck in OpenGL or any graphics for that matter.

I forgot to highlight this part though. Like I said, it's one major bottleneck for us. But there are plenty of bottlenecks. But if you're doing things "Wrong", this is the first bottleneck you hit. There's more performance to be had by doing more changes.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Neil Roy
Member #2,229
April 2002
avatar

Another example: (IIRC) Most 3-D models of people in games are stored in "default shape" (arms spread out, legs not bent). And then a shader bends the joints

Yeah, 3D characters in games have "bones". Each bone is attached to certain vertices and you move the bone which adjusts the character's body accordingly.

You can create 3D humans with a free program called MakeHuman (awesome program!) which allows you to easily create characters, human or alien looking (fun to play with) and it will add in bones for you and then you can export it for something like Blender, also free and work from there. It's meant to creating characters for games so useful even for 2D games. Add bones, export to Blender, then use Blender with the bones to pose it and render different positions for your game if it's only 2D.

I've not played with actual characters in a 3D game yet, but that is my understanding. Blender has some simple bone functions you can use and mess with. There's tutorials on it on Youtube as well.

But yeah, the databus is the slowest part of any computer due to the distances it has to travel and that won't go away anytime soon. It's why your RAM is always really close to your CPU, but notice how far away the card slots are, the video slot is always the closest one, but still a distance away for electricity to travel. It's why instancing is so fast, you only upload one VBO to your video card, then tell it where to draw it. You can scale it, rotate it etc... so it looks a little different. You could even upload a texture array, so you have an array of textures the same size then select which one each time you draw it, it's more involved but is something I would like to look into for my own games.

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

I believe there IS a way to have vertex buffer objects, but change them.

I was able to successfully combine a vertex buffer and color buffer into one buffer this evening. It took some fooling with the stride and offset of vertexAttribPointer, but it works. The performance is terrible with 1,000+ draw calls though, because the buffer is being created each frame, just like before. But at least I now know how to combine buffer data.

Neil: I haven't figured out how to use instancing yet. Learning OpenGL and GLSL this past week has been time well spent, but it has also been incredibly frustrating... Instancing doesn't sound like it'd help me. I want to draw thousands of mutable triangles per frame. Instancing sounds like it just copies and pastes fixed vertices and moves them around with a matrix. That would be good for fixed models (like trees, asteroids, cars, and so forth) whose vertices won't change, but it doesn't sound helpful for my situation. I could be wrong though...

But what I've found to work best so far is to just pass a few uniforms to adjust my vertices in the shader. That way I create the buffer data only once, and each draw call I just send the uniform data and draw the triangles. It might perform slightly better to forego creating any buffer data, and to just manually send the attribute data per frame... but I'll have to test it to know either way. What would be best though would be if I could batch all of the vertices, but that'd require changing the buffer every frame...

Neil Roy
Member #2,229
April 2002
avatar

You do not need to recreate a VBO each frame. The whole point of them is that when you create them, they are on the video card and you just refer to them when you wish to use them. Sending them to the card EACH FRAME would be horribly slow!

I created a skybox in my asteroids demo. It creates a VAO and a VBO for it. The VBO etc... are created once outside of the main loop...

// skybox VAO
unsigned int skyboxVAO, skyboxVBO;
glGenVertexArrays(1, &skyboxVAO); // Create Vertex Array Object
glGenBuffers(1, &skyboxVBO);  // Create a Vertex Buffer Object
glBindVertexArray(skyboxVAO);  // Enable the VAO we created
glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);  // Bind the VBO to the VAO
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW); // Store the vertices for the skybox in our VBO
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);  // Tell OpenGL how the data in the VBO is organized

//plus more code to load the cubemap and skybox shader etc.

Inside my main loop it is...

// skybox shader is enabled before this as well
glBindVertexArray(skyboxVAO);  // Enable the VAO which contains our VBO
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);  // Use our cubemap
glDrawArrays(GL_TRIANGLES, 0, 36);  // Render our skybox using the VAO/VBO and cubemap

That's all that is called inside the main loop. The VBO is bound in the VAO, you can have several VBOs in a VAO, the actual data is in the VBO(s). Again, I am still fairly new to this, but slowly getting a grasp of it. ;)

I do know the point of a VBO is so you have all the data for that object loaded on the video card at once, then you just tell the video card when you are using it. The VBO is stored in the VAO (you can have more than one VBO in a VAO). The speed comes in the fact that it is already on the card and doesn't need to be reloaded. ;)

In the above code, you bind the vertex array, which tells your program which VAO you are now using. You then bind a texture to it and draw the arrays which contain the triangles as I showed above. No need to recreate it all, you use glBindVertexArray() (or the WebGL equivalent) to tell the program which VAO you are now using. It will remain bound (the one in use) until you call glBindVertexArray(0); which unbinds it.

Watch this video for a great description of what VAOs and VBOs are.

video

Edit: added more comments and better described my source

---
“I love you too.” - last words of Wanda Roy

Eric Johnson
Member #14,841
January 2013
avatar

Thanks for the explanation and video. The WebGL 1.0 spec doesn't natively support VAOs. :-/ Maybe that's my problem... I think there's an extension for it though, I'll have to check.

 1   2   3   4 


Go to: