简体   繁体   中英

Multiple datatypes within a vertex buffer (openGL)

I'm studying openGL and am attempting to write a basic program. I either misunderstand something, or simply cannot find the answers I'm looking for.

I am trying to add data (of multiple data types) to a vertex buffer. I don't know if this is bad practice or not. But I figured it would save a lot of space using int for some of my data instead of floats for everything.

Is it possible to add multiple data types into a single vertex buffer? If so, how? Is there a best practice with this?

I know how to define each attribute with glVertexAttribPoint but then how did I add the data with glBufferSubData ? Right now, my problem is that glBufferSubData requires an array and arrays can only have 1 datatype, I believe.

Sidestepping your actual question:

But I figured it would save a lot of space using int for some of my data instead of floats for everything.

No, you don't save anything. sizeof(int) == sizeof(float) on all platforms you're going to be concerned about.

Anyway, you can mix multiple datatypes perfectly fine inside a buffer object, the key here is the stride parameter for glVertexAttribPointer. This is usually called a "array of structs". The following (C) is perfectly fine:

struct foo {
    GLfloat a[2];
    GLbyte b[3];
};

enum { N = 10 };

foo arr[N];

glBufferData(GL_ARRAY_BUFFER, N*sizeof(foo), arr, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(foo), (void*)offsetof(foo, a));
glVertexAttribPointer(0, 3, GL_BYTE,  GL_FALSE, sizeof(foo), (void*)offsetof(foo, b));

Now here's something important to know about "arrays of structs": They are usually less efficient than "structs of arrays" for two reasons:

  • Elements of a structure must be self-aligned; depending on what's inside a structure that requirement may mandate the use of padding bytes, ie use more space

  • If only a subset of elements in a structure are required, due to the way memory fetches work on GPUs, a lot of the data being loaded is thrown away. On GPUs usually streches of consecutive memory are fetched, which usually caches very well due to the high locality of most graphics operations.

In this appnote by Nvidia they're calling it "streams" instead of "arrays.

https://developer.nvidia.com/gpugems/gpugems2/part-iv-general-purpose-computation-gpus-primer/chapter-33-implementing-efficient

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM