a_learner
a_learner

Reputation: 61

OpenGL using std::vector with glm::vec3

I'm having the following issue.

I've loaded 8 glm::vec3 into a std::vector, such that:

std::vector <glm::vec3> vertices;

returns:

0.250000 -0.250000 -0.250000
0.250000 -0.250000 0.250000
-0.250000 -0.250000 0.250000
-0.250000 -0.250000 -0.250000
0.250000 0.250000 -0.250000
0.250000 0.250000 0.250000
-0.250000 0.250000 0.250000
-0.250000 0.250000 -0.250000

if:

for(int i{0}; i<8; i++){
    std::cout<<"\n";
    for(int j{0}; j<3; j++){
    std::cout<<vertices[i][j]<<" ";
    }
}

When I pass the following code into OpenGL,

glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), &vertices[0],  GL_DYNAMIC_DRAW);  

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

glBindVertexArray(buffer);  

my shader program loads and the window opens, however there is no cube.

A slight alteration to the first line,

glBufferData(GL_ARRAY_BUFFER, sizeof(vert), &vert, GL_DYNAMIC_DRAW); //Here

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindVertexArray(buffer); 

while taking vectors from,

const GLfloat vert[9] =
{-0.5,-0.5, 0.0,
  0.0, 0.5, 0.0,
  0.5,-0.5, 0.0};

and a pretty red triangle is drawn onto the screen.

My question: Is it possible to use a vector container in combination with glm? If so, how can it be implemented?
My hypothesis:The glVertexAttribPointer function is reading sequentially from the starting address of the vertices container. The elements of the vertices container are fragmented throughout my memory.

Upvotes: 6

Views: 20732

Answers (4)

eklukovich
eklukovich

Reputation: 11

I don't think you are allowed to pass complex types to the shader. I have always created a struct with a float array for the positions:

struct vertex{
    GLfloat positions[3];
};

Then to use in your code:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) * vertices.size(),
             &vertices[0],  GL_DYNAMIC_DRAW);  

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

glBindVertexArray(buffer);  

Upvotes: 1

alexpanter
alexpanter

Reputation: 1578

C++11's std::vector has a built-in function data(), which returns a pointer to the underlying data, such that [data(), data() + size()] is a valid range for the vector.

Furthermore, you don't need to ask for any data pointers when working with arrays of glm::ivec types. The following code example is perfectly valid OpenGL code and will render without trouble:

glm::vec3 vertices[] = {
    glm::vec3(0.0f,  0.0f, 0.0f),
    glm::vec3(0.0f,  1.0f, 0.0f),
    glm::vec3(1.0f,  1.0f, 0.0f)
};
int sizeVertices = sizeof(vertices) / sizeof(glm::vec3);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// ...
glDrawArrays(GL_LINES, 0, sizeVertices);

Upvotes: 0

Tare
Tare

Reputation: 616

Do you have back face culling enabled? Because if you have no view matrix set up or your camera is inside the cube, then you probably see only the back faces, which may be culled, whereas in your second example the triangle faces you with its front face, thus being visible.

Upvotes: 0

Axalo
Axalo

Reputation: 2953

In your glBufferData() &vertices[0] should probably have been, &vertices[0].x.
That's because &vertices[0] points to a glm::vec3 but you want it to point to a float
because that's what OpenGL expects.

Upvotes: 2

Related Questions