Hot answers tagged

10

What you're looking for is instancing. You simply call glDrawArraysInstanced​ or glDrawElementsInstanced​, passing the number of instances that you want. There are two ways to then determine per-instance data: The gl_InstanceID vertex shader input tells you which instance is currently being processed. Your vertex shader can have an internal mechanism for ...


9

This is a complex question with a lot of small details that really matter, the performance will vary based on platform and application. So you should profile for possible bottlenecks before investing in optimizations. That said, firstly, I assume you should reduce uploads and updates as much as you can, for example use instancing. Secondly, note that GPUs ...


8

For small data like this, you want glBufferSubData, sweet and simple :) Later on you probably should look into glMapBuffer though, as it is how you work with data larger than a few kilobytes quickly.


7

In this code, normals are not indexed. They most certainly are. They merely share the same index as the position. What you want is not generally possible. All vertex attributes must use the same index. You must convert your multi-indexed data to single-indices per vertex. There are techniques you could use to avoid this, but they generally require semi-...


6

I would expect glDrawArrays to be fastest on both the GPU and CPU for this scenario, primarily because you're saving the GPU memory bandwidth otherwise used for fetching the index data and the CPU cost of managing the index buffer. I do not expect glDrawRangeElements to be any faster than glDrawElements - in fact, I would expect it to be slightly slower. ...


5

If this is for desktop OpenGL or OpenGL|ES 3 and you're doing a common 2D sprite-style engine, you won't have a lot of repeat geometry. Everything is quads. You only need a single vertex buffer and index buffer (describing a quad). Use instancing to put all the transformation matrices for your scene objects into a single buffer and then draw that single ...


5

I can't say to be expert of this subject, and in my game project(s) I have concentrated more on 3D side, so my 2D side is pretty simple generally using things made for 3D side; and obviously, my perspective is at gaming side, so my 2D graphics is more about blitting sprites than geometry. From that perspective, 1) Squares and rectangles are pretty easy. I ...


5

Your main question seems to be: What would be the best way to draw frequently (really frequently, basically every frame) changing geometry with modern OpenGL? In most ways, there's no big difference between 2d and 3d OpenGL. The graphics pipeline has that one extra coordinate, Z, which won't be used as much in 2d, but that's about it. There's a few ways ...


4

Yes, your UVs are being mapped to the vertices, not to the indices -- that's the way that vertex buffers work. Your vertex isn't just the position -- it's also the color, normal, texture coordinate, and any other attributes which you've attached to it. In a case like the one here, you'll actually need a separate copy of each vertex for each face, because ...


4

My hunch is that it's the creation of the VBO each time. If you data is truly dynamic you could try not using the VBO at all and just passing interleavedBuffer to glVertexPointer, etc. That leaves what happens in the hands of the driver. Probably it will copy your data into a buffer somewhere internally, but in a more optimal way since it has more ...


4

I put together a greedy meshing implementation for voxel data which includes various attributes (https://www.youtube.com/watch?v=0OZxZZCea8I). I understand you're looking to merge voxel faces even when they aren't the same voxel type - but it would seem that the only way to do that is to send the set of voxel types represented by the quad into the shader ...


4

You are currently putting the position data into one VBO (vertexBuffer[0]) and the color data into another one (vertexBuffer[1]). But when drawing you bind both buffers one after the other, so the second binding will just override the previous one. Then you set the pointers as if both attributes were in the same buffer. This is slightly messed up. The gl......


4

I pasted together a running version here (just for demo purposes, I hacked around your existing names and structures) Like I said, your indices were wrong. How you got your MVP matrix I don't know, but it still looks wrong, maybe you transposed it or printed it out transposed. Also, the way you used glBindAttribLocation() and glBindFragDataLocation() is ...


4

If you don't do any optimization you are rendering up to ~half a billion vertices, you can: Remove faces/vertices where blocks touch, and don't issue draw calls for chunks that lay outside of the FOV. Beyond that you can do more advanced vismap approaches, and merge faces when possible. If you still think there is something wrong, i suggest you edit your ...


4

There is a lot of misinformation floating around here. Buffer Objects were introduced into core in OpenGL 1.5. They existed in extension form as far back as OpenGL 1.4. Vertex Buffer Objects are basically an evolution of ATi's original Vertex Array Object extension. That extension has the unfortunate honor of sharing its name with a completely different ...


4

Yes, doing several draw calls is slower than one. This is why state changes are expensive. There are techniques (like instancing) that fight this, but they're still more expensive than simply doing a single draw call. To combine several VBOs into one, they must have the same state (i.e, same shader, same textures, etc), and they must be static (i.e, not ...


4

There are many cleaver ways of drawing 2D geometry with modern shader-centric OpenGL. The method that I usually choose and find the most straightforward is with simple batching. On startup, create a system-side buffer of 2D vertexes (the batch). This buffer can have a fixed size or can be resizable (like a std::vector in C++). Also create a VBO with the ...


4

Yes, sending your mesh data to the GL every time you render it would be very wasteful. You should only be doing that if your data has changed from one frame to another (e.g. you are computing animations in the CPU). Otherwise, you shouldn't have to re-submit data if the model/mesh was not changed. Apparently, the problem with your program is that you are ...


4

The way you are rendering voxels is extremely ineffective. For each cube you have to do calculations, set uniforms, and worst of all bind textures(This is usually a very expensive operation) Typically effective voxel rendering involves multiple techniques to speed up rendering: Rendering in chunks: You split your world into neatly sized proportions, which ...


4

I try to answer the question. I think that you should go with indices, for few reasons: 1) In any case, indexing is free operation at GPU side, you don't take penalties there. (added) Of course, indices are random access operations, and can hurt GPU memory cache performance. 2) Indexing may allow GPU vertex cache to make those few optimizations for ...


4

deleteBuffer will delete the buffer in WebGL (and OpenGL) but I'm just curious, is there any reason not to just reuse the same buffer just put new data in it? (eg. have a pool of buffers?)


3

Obviously the destructor get´s called at some point and deletes your VBO before you draw it, my guess is that you create a temporary object somewhere, which get´s deleted or have an issue with copies or assignments. Example: QuadTemplate quad; void foo() { QuadTemplate quad2(); quad2.vbo = CreateVBO(); //function that creates VBO quad = quad2; ...


3

Based on my experience, you should go on with your VBO per class solution. I don't know whats your target platform, but any computer should be able to handle a couple thousand VBOs without problem, especially as you are talking about a 2D game, which is less likely to have many vertices. It depends on the usage and target platform tough. But as a general ...


3

VBOs have been available since OpenGL 1.4 as an extension and were added to the core in OpenGL 1.5. You can use either version depending on your needs, if you strictly want to use OpenGL 3.1 with the core profile only, then VBOs are your only option. If you want to use compatibility profile, you can always use the deprecated functions. Keep in mind that "...


3

you can step away from glDrawArrays and instead use glDrawElements and use a GL_ELEMENT_ARRAY_BUFFER​ buffer that hold the indexes of the vertexes you want to draw the element buffer would then contain {0,1,2,9,10,11,...} and so on. In you comments I see that you want this to draw a "light" object for quick updates, you can add all other triangles after ...


3

You don't need to call glVertexAttribPointer for the indexes; the indexes are found from the bound GL_ELEMENT_ARRAY_BUFFER during the drawElements call (which is saved in the VAO state IIRC). However indexes start from 0 so the contents of your index buffer are flawed they should be: {0,1,2,2,3,0}


3

TLDR: VBOs makes a huge difference in performance. One simple reason to use them would be that OpenGL ES (mobile devices) don't support glBegin(...)/glEnd() so you have to use glDrawArrays() but not necessarily VBOs. The main reason to use VBOs is that it allows the OpenGL driver to keep the vertex data in GPU memory, rather than CPU memory which forces ...


Only top voted, non community-wiki answers of a minimum length are eligible