I am trying to draw two different meshes using OpenGL 4.1. At any given time, only one of the meshes will be drawn, and my goal is to switch between them. I am storing the vertex and index data for the meshes in an object, which below, is called g_obj. So, the data for the first mesh is gotten by g_obj->vertices_ and g_obj->indices, and the data for the second mesh is gotten from g_obj->vertices_linear_ and g_obj->indices_linear_.
My horrible idea is to have distinct VBO's and VAO's for each mesh. Then on the draw call, I would simply bind the appropriate VAO and then do glDraw*. However, my code segfaults on the first draw call (see below).
enum VAO_ID
{
VAO,
VAO_LINEAR,
NUM_VAOS
};
enum BUFFER_ID
{
VERTEX_BUFFER,
VERTEX_BUFFER_LINEAR,
INDEX_BUFFER,
INDEX_BUFFER_LINEAR,
NUM_BUFFERS
};
enum ATTRIBUTE_ID
{
VERTEX_POSITION,
VERTEX_COLOR
};
GLuint g_vaos[NUM_VAOS];
GLuint g_buffers[NUM_BUFFERS];
further down, I create vertex/index buffers and vertex array objects:
void bufferGeometry()
{
// create vertex buffers and vertex array object
glGenVertexArrays(NUM_VAOS, g_vaos);
glGenBuffers(NUM_BUFFERS, g_buffers);
// rotational grating
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_ * sizeof(vertex2D),
g_obj->vertices_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_ * sizeof(GLushort),
g_obj->indices_,
GL_STATIC_DRAW);
glBindVertexArray(g_vaos[VAO]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
// linear grating
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_linear_ * sizeof(vertex2D),
g_obj->vertices_linear_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_linear_ * sizeof(GLushort),
g_obj->indices_linear_,
GL_STATIC_DRAW);
glBindVertexArray(g_vaos[VAO_LINEAR]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
}
then, here is the draw call:
glBindVertexArray(g_vaos[VAO]);
g_obj = &g_grating_uno;
glUseProgram(g_program);
glUniform3fv(g_trans_scale_location, 1, g_obj->trans_scale_);
glDrawElements(GL_TRIANGLES, g_obj->num_indices_,
GL_UNSIGNED_SHORT, (const GLvoid *)0);
Which segfaults at the glDrawElements line.
I know that the general "performant" strategy is to pack data from both meshes in single VBO's, and since the data format is the same between the two meshes, then I only need one VAO. But, since I am lazy, I was wondering if anyone can see why my existing strategy does not work or cannot work or if you think the problem lies elsewhere. My guess is that it has to do with my bufferGeometry() function. I am a little weak in my understanding of how VAO's are linked to specific VBO's, if they are at all. Thanks, and sorry for being dumb!
you should repeat the call to bind the element buffer between the glBindVertexArray:
glBindVertexArray(g_vaos[VAO]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBindVertexArray(0);
the element buffer binding is part of the VAO state and gets reset when a new VAO gets bound.
Ah, fixed it (I think) by binding the VAO's before binding the VBO's:
void bufferGeometry()
{
// create vertex buffers and vertex array object
glGenVertexArrays(NUM_VAOS, g_vaos);
glGenBuffers(NUM_BUFFERS, g_buffers);
// rotational grating
glBindVertexArray(g_vaos[VAO]);
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_ * sizeof(vertex2D),
g_obj->vertices_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_ * sizeof(GLushort),
g_obj->indices_,
GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
// linear grating
glBindVertexArray(g_vaos[VAO_LINEAR]);
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_linear_ * sizeof(vertex2D),
g_obj->vertices_linear_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_linear_ * sizeof(GLushort),
g_obj->indices_linear_,
GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
}
Related
I am trying to create two separate objects to be rendered at the same time, a cube and a sphere. The issue is once I add the code for the sphere, the cube
is missing some faces etc.
Here is my code:
glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices[0], g_pMeshVertices[0], GL_DYNAMIC_DRAW);
glGenBuffers(1, &g_IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces[0], g_pMeshIndices[0], GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &g_VAO);
glBindVertexArray(g_VAO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
glEnableVertexAttribArray(positionIndex);
glEnableVertexAttribArray(normalIndex);
/////////////////////////////////////////ORN///////////////////////////////////////////////
glGenBuffers(1, &ornVBO);
glBindBuffer(GL_ARRAY_BUFFER, ornVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices[1], g_pMeshVertices[1], GL_DYNAMIC_DRAW);
glGenBuffers(1, &ornIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ornIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces[1], g_pMeshIndices[1], GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &ornVAO);
glBindVertexArray(ornVAO);
glBindBuffer(GL_ARRAY_BUFFER, ornVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ornIBO);
glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
glEnableVertexAttribArray(positionIndex);
glEnableVertexAttribArray(normalIndex);
So it renders the sphere fine, but then all the cubes have missing triangle faces. I think I have narrowed it down to being an issue with the IBO side but I can't quite figure it out.
Here is the image: https://puu.sh/vLBSm/1617b5d996.png
Next to and behind the sphere and the cube are other cubes ignore those, they have the same issue but are purposefully there. I just can't work out how to display both properly. and Im sure it has something to do with this:
glGenBuffers(1, &ornIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ornIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces[1], g_pMeshIndices[1], GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &ornVAO);
In the ORN code, you are overwritting the index buffer binding of the first VAO.
At this point:
glGenBuffers(1, &ornIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ornIBO);
g_VAO is still active, so the index buffer binding is replaced by ornIBO. To solve that you should unbind g_VAO before starting the ORN code:
glBindVertexArray(g_VAO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
glEnableVertexAttribArray(positionIndex);
glEnableVertexAttribArray(normalIndex);
//Unbind!!
glBindVertexArray(0);
I am working on a simple 3D Engine. I currently have a working setup with multiple VAO's which I can switch between during the render loop, but they all are not using index buffers.
I'm now trying to add a new VAO composed of 4 VBO's: vert position, color, normal and indices.
Everything compiles and runs but the drawing calls to the second VAO (with indexed vertices) do not render. I'm sure there is a problem with my setup somewhere, so I've added this code which includes all the VAO and VBO generations, calls, and uses. Does anything in this code seem wrong, and is this the correct way to set it all up?
VAO1 has 3 buffers: position, color, normals
VAO2 has 3 buffers: position, color, normals and vertex indices
//Initalize vaos and vbos
GLuint vao1, vbo1[3];
GLuint vao2, vbo2[4];
//Generate Vertex arrays:
glGenVertexArrays(1, &vao1);
glGenVertexArrays(1, &vao2);
//Generate Buffers:
glGenBuffers(3, vbo1);
glGenBuffers(4, vbo2);
//Initalize Bufferdata vectors:
vector<GLfloat> VertPosBuffer1Vector;
vector<GLfloat> VertNormalBuffer1Vector;
vector<GLfloat> VertColorBuffer1Vector;
vector<GLfloat> VertPosBuffer2Vector;
vector<GLfloat> VertNormalBuffer2Vector;
vector<GLfloat> VertColorBuffer2Vector;
vector<GLuint> VertIndexBuffer2Vector;
//Fill Buffers:
//(not included but all vectors are filled with data)
//VAO 1
glBindVertexArray(vao1);
//Vertex position buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo1[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertPosBuffer1Vector.size(), &VertPosBuffer1Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
//Vertex color buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo1[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertColorBuffer1Vector.size(), &VertColorBuffer1Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
//Vertex normal buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo1[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertNormalBuffer1Vector.size(), &VertNormalBuffer1Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(2);
//VAO 2
glBindVertexArray(vao2);
//Vertex position buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo2[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertPosBuffer2Vector.size(), &VertPosBuffer2Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
//Vertex color buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo2[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertColorBuffer2Vector.size(), &VertColorBuffer2Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
//Vertex normal buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo2[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*VertNormalBuffer2Vector.size(), &VertNormalBuffer2Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(2);
//Vertex index buffer:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2[3]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*VertIndexBuffer2Vector.size(), &VertIndexBuffer2Vector[0], GL_STATIC_DRAW);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(3);
//unbind vao
glBindVertexArray(0);
//bind first vao
glBindVertexArray(vao1);
and
//RENDERLOOP
//render objects from vao1 using:
glDrawArrays(GL_TRIANGLES, start, size);
//switch vao
glBindVertexArray(0);
glBindVertexArray(vao2);
//render objects from vao2 using:
glDrawElements(
GL_TRIANGLES,
start,
GL_UNSIGNED_INT,
(void*)0
);
I have checked that the data in my buffers are correct.
Is it correct that the shader doesn't take in any information of indices? The shader will be the same as if I didn't use an index buffer?
Thank you
The indices are not a vertex attribute. So what you need to do is remove these two lines:
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(3);
I also noticed that you are using the variable "start" as the count argument for glDrawElements. I don't know the values of start and size, but I assume you should use "size" as the second argument in glDrawElements.
With OpenGL shaders, I want to render two objects. Each is defined by a set of vertex positions and vertex indices for the triangles. When I make my buffers, I use the following code:
// Object 1 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object1_vertices_size, object1_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Object 1 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object1_indices_size, object1_indices, GL_STATIC_DRAW);
// Object 2 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object2_vertices_size, object2_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Object 2 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object2_indices_size, object2_indices, GL_STATIC_DRAW);
And then when I render my scene, I use the following code:
// Object 1
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);
// Object 2
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);
However, this results in only object 2 being drawn. What am I doing wrong?
If you have openGL 3.3+ you should use a VAO:
glBindVertexArray(vao1);
// Object 1 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object1_vertices_size, object1_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Object 1 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object1_indices_size, object1_indices, GL_STATIC_DRAW);
glBindVertexArray(vao2);
// Object 2 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object2_vertices_size, object2_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
// Object 2 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object2_indices_size, object2_indices, GL_STATIC_DRAW);
and then you only need to bind the right vao when drawing:
// Object 1
glBindVertexArray(vao1);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);
// Object 2
glBindVertexArray(vao2);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);
otherwise you will need to repeat the bind and glVertexAttribPointer calls between draws:
// Object 1
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);
// Object 2
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);
If this is all the code present, then there are several problems:
One has to enable vertex attributes by calling glEnableVertexAttribArray.
In the drawing code you are only rebinding the index buffer, but not the vertex buffer. Both, glBindBuffer(GL_ARRAY_BUFFER,... and glVertexAttribPointer change the current state, so you are overriding the first objects setting with the second ones. If you really want to work without VAOs, you'll have to bind the correct buffer before each draw call and update the glVertexAttribPointer
There is no VAO in use (VAOs are mandatory when working in Core profile but I would recommend using them also in compatibility mode)
How usually people draw several objects in OpenGL 3.3+?
I have 2 objects: a terrain and a sphere. For each object i have 2 arrays(of vertices and indices). I tried to set different VBO and IBO(like this):
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_VBOsphere);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOsphere);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
but looks like GPU calculates/draw everything only after closing of this function and I see only a sphere. So, what should I do?
It looks like you misunderstood the implications of binding a buffer, and the correct sequence of calls.
You expected that in this sequence, the draw call would get its vertices from the VBO with id m_VBO:
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);
That's not the way it works. The current GL_ARRAY_BUFFER binding has absolutely no effect on the draw call.
You need to have the right VBO bound when glVertexAttribPointer() is called. Beyond the direct arguments that specify values for the setup of the corresponding attribute (format, stride, etc), this call also specifies that the currently bound VBO is used as the source for the attribute data.
Therefore, you need the glVertexAttribPointer() calls for each object, and call them after binding the corresponding VBO.
The call sequence is then:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_VBOsphere);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOsphere);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
If you want to reduce the number of setup calls you need before each draw call, look up Vertex Array Objects (VAO).
In my project I'd like to edit given vertex position which is already in GPU.
Do I need to reload whole model or there is an function to change needed vertex.
This is how I pass mesh to GPU
void Mesh3v3n2t::PassToGPU()
{
glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);
glGenBuffers(1, &VboId);
glBindBuffer(GL_ARRAY_BUFFER, VboId);
glBufferData(GL_ARRAY_BUFFER, 32*vertices.size(),vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, (void*)12);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, (void*)24);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenBuffers(1, &IndexBufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*4, indices.data(), GL_STATIC_DRAW);
}
You can use glBufferSubData. You may want to rethink the GL_STATIC_DRAW usage hint if you're going to be doing this frequently, but it's not necessary.