Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Manual Data Formatting (Interleaving Buffer Data)

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2012
    Posts
    11

    Manual Data Formatting (Interleaving Buffer Data)

    Hello once more all,

    To the point, I have three sets of data I want to merge and upload to a buffer, those sets being Vertex, Normal, and Texcoord.
    Do you know of an efficient, or more viable way to combine those three sets into one, than what I am presenting below?
    Is this a correct technique, or am I not comprehending the index structure well enough?

    I plan on formating my three sets of data to correspond with my index pattern, being the standard (VNTVNTVNTVNT) or (Vertex,Normal,Texcoord).
    OpenGL Context, 4.0+.
    Code :
    	int* Indices = Mesh->Index;
     
    	int size = Mesh->Index_count;
    	float* Interleaved = new float[size];
     
    	for(int i=0; i<size;)
    	{
    		Interleaved[i] = Mesh->VERTEX.mData  [Indices[i]];
    		i++;
    		Interleaved[i] = Mesh->NORMAL.mData  [Indices[i]];
    		i++;
    		Interleaved[i] = Mesh->TEXCOORD.mData[Indices[i]];
    		i++;
    	}
     
    	// I believe both the interleaved and index buffers to have the same element count.
     
            GLuint Buffer_Interleaved,Buffer_Index;
     
    	glGenBuffers(1,&amp;Buffer_Interleaved);
    	glGenBuffers(1,&amp;Buffer_Index);
     
    	glBindBuffer(GL_ARRAY_BUFFER,Buffer_Interleaved);
    	glBufferData(GL_ARRAY_BUFFER,size*sizeof(float),Interleaved,GL_STATIC_DRAW);
     
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,Buffer_Index);
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER,size*sizeof(int),Indices,GL_STATIC_DRAW);
     
    	delete [] Interleaved;

    Additionally, I would like to know how to use glDrawElements() with my newly formatted data.
    Books and web references are lacking a good amount of clarity to me.

    Any relative words of wisdom are words enough to suffice thanks.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,726

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Pedantic grammar note: Index is the singular form of indices. "Indice" or "indicie" is not a word.

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2012
    Posts
    11

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Haha, I knew something felt wrong when writing it.
    I'll get to fixing my many errors.

    Every bit helps, though I still need the above questions to be addressed.

  4. #4
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    941

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Quote Originally Posted by DanielSaucen
    Do you know of an efficient, or more viable way to combine those three sets into one, than what I am presenting below?
    Can you explain what do you mean by "an efficient" way? You are interested in how you should layout your GPU vertex data or you want to avoid the additional copy to the temporary array?

    Btw, there are several problems with your code (at least as far as I understand how it should work):
    1. You actually copying your data in Vx Nx Tx Vy Ny Ty etc. order which I think it's incorrect, but maybe I'm wrong. It's hard to figure out what you're doing.
    2. You read the vertex data indexed by the indices, actually that defeats the purpose of hardware indexing and in this form only DrawArrays would work for you. You should remove the indirection (i.e. replace the array index "Indices[i]" simply with "i").

    Quote Originally Posted by DanielSaucen
    Additionally, I would like to know how to use glDrawElements() with my newly formatted data.
    Books and web references are lacking a good amount of clarity to me.
    The OpenGL specification clearly describes how DrawElements is working. You should give it a try. The spec is usually the best documentation.

    Also, there are tons of sample applications all around the internet. Just use your favorite search engine and search for VBO samples.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    723

    Re: Manual Data Formatting (Interleaving Buffer Data)

    by merge do you mean display as one mesh? It makes a difference when displaying

  6. #6
    Junior Member Newbie
    Join Date
    Feb 2012
    Posts
    11

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Sorry, to clarify:

    I am dealing with a mesh object, that is split into the three components that make it drawable, being Vertex, Normal, and Texcoord. I simply want to combine the three elements into a single buffer, though I'm not exactly sure how, after combined, to specify the pattern to let OpenGL know the offsets.

    To sum my question up into two parts:
    Is the above code I wrote (with Vertex[i] instead of Vertex[Index[i]]...ect), actually creating a valid format that matches my index pattern? (Vertex,Normal,Texcoord)

    How do I use glVertexAttribPointer() before drawing to specify the correct offset for that single, combined, buffer object? I would very much appreciate a specific example, rather than yet another link to the wiki page that I've refereed to, and failed using.

    Many thanks for your patience.

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Dec 2007
    Location
    Hungary
    Posts
    941

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Not exactly, actually you have to do something like the following:

    Code :
            int* Indices = Mesh->Index;
     
    	int indexCount = Mesh->Index_count;
            int vertexCount = Mesh->Vertex_count;
     
            typedef struct _SvertexData {
                float vertex[4];
                float normal[3];
                float texcoord[2];
            } vertexData;
     
    	vertexData* Interleaved = new vertexData[vertexCount ];
     
    	for(int i=0; i<vertexCount; ++i)
    	{
                    Interleaved[i].vertex[0] = Mesh->VERTEX.mData[i*4+0];
                    Interleaved[i].vertex[1] = Mesh->VERTEX.mData[i*4+1];
                    Interleaved[i].vertex[2] = Mesh->VERTEX.mData[i*4+2];
                    Interleaved[i].vertex[3] = Mesh->VERTEX.mData[i*4+3];
     
                    Interleaved[i].normal[0] = Mesh->NORMAL.mData[i*3+0];
                    Interleaved[i].normal[1] = Mesh->NORMAL.mData[i*3+1];
                    Interleaved[i].normal[2] = Mesh->NORMAL.mData[i*3+2];
     
                    Interleaved[i].texcoord[0] = Mesh->TEXCOORD.mData[i*2+0];
                    Interleaved[i].texcoord[1] = Mesh->TEXCOORD.mData[i*2+1];
    	}
     
            GLuint Buffer_Interleaved,Buffer_Index;
     
    	glGenBuffers(1,&amp;Buffer_Interleaved);
    	glGenBuffers(1,&amp;Buffer_Index);
     
    	glBindBuffer(GL_ARRAY_BUFFER,Buffer_Interleaved);
    	glBufferData(GL_ARRAY_BUFFER,vertexCount*sizeof(vertexData),Interleaved,GL_STATIC_DRAW);
     
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,Buffer_Index);
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER,indexCount*sizeof(int),Indices,GL_STATIC_DRAW);
     
    	delete [] Interleaved;
     
            glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertexData), offsetof(vertexData, vertex));
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertexData), offsetof(vertexData, normal));
            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertexData), offsetof(vertexData, texcoord));

    However, the code I wrote is completely based on assumptions as you haven't described how your data is layed out in the Mesh->VERTEX, Mesh->NORMAL and Mesh->TEXCOORD arrays. The actual, properly working code could be very different.
    Disclaimer: This is my personal profile. Whatever I write here is my personal opinion and none of my statements or speculations are anyhow related to my employer and as such should not be treated as accurate or valid and in no case should those be considered to represent the opinions of my employer.
    Technical Blog: http://www.rastergrid.com/blog/

  8. #8
    Junior Member Newbie
    Join Date
    Feb 2012
    Posts
    11

    Re: Manual Data Formatting (Interleaving Buffer Data)

    A few questions to help me clarify my last qualms, I should be set and extremely happy after getting these tidbits.
    I have no problems with short yes or no answers.

    glVertexAttribPointer:

    1.) Does it require me to enable states, such as glEnableClientState(GL_INDEX_ARRAY)?

    2.) When referring to Position arrays, must I include the fourth coordinate W, or is it set to 0 by default?

    3.) Is it needed that I pack and upload all my data in a structure, as you exemplified in the above code?

    4.) I noticed you did not include a stride in the example code, but gave a byte size.
    Why would it be the size of the entire array, rather than something like 3*sizeof(float)?
    ...sizeof(vertexData)...

    5.) My offset is 0,1,2. (V,N,T). How does this translate to the buffer offset?
    I find this very confusing as I can't tell if it should be literal, or sizeof(float). Do you have any examples?

    glDrawElements():

    1.) When specifying the count of triangles, is it okay to use (Index_Count/3)/3?
    (Vertex,Normal,Texcoord)/3 = (Vertex)/3 = (Triangle Count), is this logic correct?

    I can't thank you enough for both the examples, and continued help throughout the day.
    My problems should be solved after I get these last bits of clarity.

  9. #9
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,421

    Re: Manual Data Formatting (Interleaving Buffer Data)

    Did you look at the Wiki?
    http://www.opengl.org/wiki/VBO_-_just_examples

    2)By default, W is 1.0

    3) No. Example, you can just fill in a float array. BTW, a memory location is just a memory location. As a programmer, you should know by now how RAM memory (or any kind of computer memory) works.

    4) How will GL know the start of the next vertex?

    5) Buffer offset are in bytes.
    If you want to read documents, there is the spec of course but there is also the Wiki
    http://www.opengl.org/wiki/Vertex_Buffer_Object
    http://www.opengl.org/wiki/VBO_-_more
    http://www.opengl.org/wiki/VBO_-_just_examples

    1) glDrawElements takes the number of indices
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  10. #10
    Junior Member Newbie
    Join Date
    Feb 2012
    Posts
    11

    Re: Manual Data Formatting (Interleaving Buffer Data)

    SOLVED

    There we are, took me a while to absorb the info.
    I do understand RAM and dynamic memory allocation, though I had rather than one big easy to solve question, I had a multitude of smaller, more prickly questions that were able to prevent me from a complete understanding.

    In any case, my problems are solved, and I owe the community, and the posters on my thread such as you, Aqnuep, and with his quick grammar lesson, Reinheart.

    Once again, thanks for the extended help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •