An OpenGL game template found in xcode 4.2 (What happens in this code? !!)

Hello, I tried to understand what was going on in this part of the code as far as I could, but I had no luck.

glGenVertexArraysOES(1, &_vertexArray); glBindVertexArrayOES(_vertexArray); glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); glBindVertexArrayOES(0); 

This belongs to the template for creating OpenGL games on xcode 4.2. However, I am completely confused, and I would be very pleased if someone could explain this to me.

First, how can I generate and bind _vertexArray without adding anything to it?

Secondly, IF gCubeVertexData is an array of 216 with the following:

 GLfloat gCubeVertexData[216] = { // Data layout for each line below is: // positionX, positionY, positionZ, normalX, normalY, normalZ, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 

I would suggest that im process this array for the next command in which I include GLK attributes and that Im uses pointers (still using the pre-bound). But if I'm not mistaken, the syntax is: (attribute for the set, vertex size, type, false, structure size (which, in my opinion, is not 24), and the offset from the data (where does this come from?))

and the last question, why am I now binding 0 to an array of vertices?

EDIT: be honest. I tried exploring opengl on different sites, but I could only come across theory, not practice. That is why I asked this question.

+4
source share
1 answer

Ok, step by step:

 glGenVertexArraysOES(1, &_vertexArray); glBindVertexArrayOES(_vertexArray); 

This binds and generates a vertex array object (VAO). VAO now contains no data. It just contains all the state associated with the arrays / vertex attributes, such as activated attributes or settings made with glVertexAttribPointer .

 glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); 

A vertex buffer object (VBO) is now created and linked, which is essentially a simple data buffer managed by OpenGL and copies vertex data into it.

Look at this data:

 GLfloat gCubeVertexData[216] = { // Data layout for each line below is: // positionX, positionY, positionZ, normalX, normalY, normalZ, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 

Your data is laid out as a bunch of floats (32 bits / 4 bytes each), and every six values ​​represent a vertex, which, in turn, consists of a position (3 floats) and normal (3 floats).

 glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 

This indicates the first attribute (position) containing 3 float values ​​for each vertex, in increments of 24 bytes between each vertex. This means that it is 24 bytes from the beginning of the attribute values ​​(position in this case) of one vertex to the beginning of the attribute data of the next vertex. Indeed, 24 bytes is the size of 6 floats and therefore the data of one vertex in our vertex data, so this exactly matches. The last parameter says that the position data starts at the beginning of the current associated VBO (which contains our vertex data), since it is the first attribute in our vertex data.

 glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); 

Indicates a second attribute (normal) containing 3 float values ​​for each vertex, again in increments of 24 bytes, since they were obtained from the same data. Thus, from one normal to another it is also 24 bytes (6 floats). Now the last parameter says that normal data starts 12 bytes (3 floats) after the start of the current associated VBO (which contains our vertex data). This is necessary because normal is the second attribute in our vertex data, so we need to “jump over” the first three values ​​(which are the position) to get to the normal data. If we used 0 again, we would have taken the same data as for the positions.

 glEnableVertexAttribArray(GLKVertexAttribPosition); glEnableVertexAttribArray(GLKVertexAttribNormal); 

Finally, they activate the attributes for rendering.

 glBindVertexArrayOES(0); 

So now it binds the default value (no) of VAO, since we are done with specifying it. I assume that all this piece of code is part of some initialization procedure. So now, when we later want to display our vertex data, perhaps using glDrawArrays , we only need to bind VAO with glBindVertexArray before calling the draw method and each vertex array state made by glEnableVertexAttribArray or glVertexAttribPointer to get the values ​​set when VAO was bound by the latter, as in our initialization procedure. If you will not use VAO, you will have to call glBindBuffer , and two glEnableVetrexAttribArray and glVertexAttribPointer each time you want to draw this vertex data.

But all of these explanations suggest that you are more or less familiar with these concepts. If all these words do not tell you anything, you should start by exploring some real learning resource before trying to decrypt the code of other people.

+21
source

Source: https://habr.com/ru/post/1384823/


All Articles