I try to set up a scene consisting of different models. All of the corners of the surfaces can appear several times in different surfaces so I decided to use indexed rendering. But even between different models always the same points in a “point grid” are used. So one single VBO is enough for all the points, and every model defines its own IBO.
BUT: The texture coordinates differ in different models, even if the concerning vertex references point to the same vertex. Additionally always specifying the whole texture coordinates (2 floats) coasts a lot of memory. References for that purpose would be better, too.
So I’d actually like one reference buffer to point to all the vertices and another one to point to all the texture coordinates. And when rendering a point is composed of the reference in one IBO to the vertex and a reference in another IBO to the texture coordinate. Is this possible and if no, what would be an alternative?
Thx for your help!
Additionally you can read this topic. For instance, you can set one VBO for the vertices, one for the texture coordinates, all of this in a single VAO. This might be useful for you to set-up different VAOs for your different kind of renderings.
Ok so my current idea is to use shaders (similiar to your instancing proposal). But I can’t get all of my required data out of a single instance. Maybe I could simply fill in the VBO a lot of vertices, but they aren’t really used as vertices. It’s a ‘trick’ to save the references. For example I could save a 2D integer vector, with x-coordinate representing the index of the actual vertex to use and y-coordinate referencing the texture coordinates to use. Last the shader needs access to these elements, being referenced by the ‘fake vector’. But I think there should be data types for the shader making this possible.
no, you cant use “vector<type>” (the c++ standard library type) in shaders
you cant use pointers neither, nor references (the c++ feature “&”)
to access data in shaders, you have 3 options:
– you send the data via “vertex attributes” to the vertex shader
– you bind a “uniform block” and access the data in it via “vertex attributes” dynamically
– you bind a “shader storage block” and access the data in it via “vertex attributes” dynamically
– textures would be another way, however …
“indexed rendering” can use the same vertex data multiple times
but i disagree: 2 floats are not really "much"memory consumption: sizeof(float) * 2 = 8 bytes
[QUOTE=john_connor;1285007]no, you cant use “vector<type>” (the c++ standard library type) in shaders
you cant use pointers neither, nor references (the c++ feature “&”)[/QUOTE]
I’m not quite sure if I could explain the idea good enough:rolleyes:. At first you could initialize a VBO and make OpenGL interprete it as a list of 2D-integer-vertices. But then you write a shader and use the coordinates in a completely different way. You’re using the x-coordinate to access a seperate vertex buffer and the y-coordinate to access a seperate texture coordinate buffer… Would that be possible?
but i disagree: 2 floats are not really "much"memory consumption: sizeof(float) * 2 = 8 bytes
Oook, maybe I’m a little bit too exact concerning the memory issue. But there’s no harm in that…
that vertexbuffer has to be bound anywhere, so that you can access it in your shader
as i said before:
– binding it to a “uniform block”, you’ll have fast, read-only access and the storage amount is (very?) limited
– binding it to a “shader storage block”, you’ll have slower, read-&-write access and the storage amount is huge
GLuint uniformbuffer = 0;
glGenBuffers(1, &uniformbuffer);
glBindBufferBase(GL_UNIFORM_BUFFER, 5, uniformbuffer);
glBufferData(GL_UNIFORM_BUFFER, ... here your data ...);
Yeah ok, didn’t think of how to access the memory. Assumed there should be a possibility…
-Hm theoretically the storage in a uniform block should be enough ( if I didn’t do anything wrong 64kb for my computer)
-So will a shader storage block be slower then “normal” rendering in the end?
Thx for the example code. I’ll very likely use it
Why I’m so ‘curious’ about the referencing method: I calculated that with 4gb graphic memory you could increase the sight distance by a factor of 2 to 3km in the world of my application, when using the referencing model instead of the “normal” way. Of course that’s only theoretical, because rendering would be nether fast enough either…:whistle:
Btw: In your example really only indices are send to the rendering pipeline and not sth which pretends to be vertices for the shader. I don’t know much about this strategy so how would you store the index data into a VBO and render it?
as usual: put the attribute data (in this case: the indices) in array buffers (GL_ARRAY_BUFFER)
then invoke the vertexshader by calling:
glDrawArrays(…);
use glVertexAttribIPointer(…) instead of glVertexAttribPointer(…) to set the attribute “pipe” for integer-type variables
example:
GLuint arraybuffer = 0;
glGenBuffers(1, &arraybuffer);
glBindBuffer(GL_ARRAY_BUFFER, arraybuffer);
glBufferData(GL_ARRAY_BUFFER, ... here the indices you want to stream as attributes ...);
OK after hours of fixing infinite problems, I think there’s only one thing left, which doesn’t work: uniform blocks containing arrays. If I use a uniform block like this…
You need to either query the array stride or use the std140 layout. Either way, there is likely to be padding between the elements (std140 guarantees it, but it’s likely with an implementation-dependent layout).
Warning: Implementations sometimes get the std140 layout wrong for vec3 components. You are advised to manually pad your structures/arrays out and avoid using vec3 at all.
try using vec4 instead of vec3, declare the uniform block like this:
Next question :
Is it possible to define an input variable for a shader of type unsigned integer, which gets its values out of a vertex buffer object, which saves short values? So something like an automatic conversion between the buffer short content and the integer variable in the shader?
By the way: does the padding problem also exist for vec2-arrays? Should I use vec4’s there too? But isn’t that again waste of memory…?:whistle:
it all depends on the “memory layout”, read the section i’ve linked prevously
there are 10 rules about the “standard memory layout” (std), read them in page 137/138
Back to the vertex attributes: So when I for example define a uint in a shader, because there’s no suitable better integer type, could I pass GL_SHORT to the concerning vertexattrib-method? Will the value be converted automatically and correctly?
i’d try glVertexAttribIPointer(…, GL_UNSIGNED_SHORT, …)
since there is no 2 byte integer type in glsl, i assume that it will be converted into 4 byte integer type (int or uint)