0
\$\begingroup\$

I have a class terrain which create a grid of Quads. I do it like this

for(int z=0; z<_length;z++){
            for(int x=0; x<_width;x++){
                vertices.push_back(vec3((float)x*250, 0.f, (float)z*250));
    }
}
for(int z=0; z<(_length-1);++z){
    for(int x=0; x<(_width-1);++x){
        int index = z*_width+x; 
        Vertex _vertices[] = {
            Vertex(vertices.at(index),vec3(0, 0, 0)),
            Vertex(vertices.at(index+1),vec3(0, 0, 0)),
            Vertex(vertices.at(index+_width),vec3(0, 0, 0)),
            Vertex(vertices.at(index+1+_width),vec3(0,0,0))
        };

        unsigned short indices[]= {index,index + 1,index + 
            _width,index + 1,index +  _width,index +  _width + 1};
        Quad quad(_vertices, 4, indices, 6);
        squares.push_back(quad);
        i++;
    }
}

The vertices and the logic are correct, but the indices aren't, for some reason. here is the output for this code : enter image description here But when I change this indices to this :

            unsigned short indices[]= {0,1,2,1,2,3}; 

It works great : enter image description here

The problem is I don't understand why this line

        unsigned short indices[]= {index,index + 1,index + 
            _width,index + 1,index +  _width,index +  _width + 1};

doesn't work. And if it worked, my grid would consume a lot less ressources. If someone could explain me why it doesn't work, It would be great, thanks you. In case you need to know how I draw a Quad, here is the code :

class Quad{
public:
    Quad(Vertex *_vertices, int _n, unsigned short * _indices, unsigned short _numIndices){
        for(int i=0; i < _numIndices; i++){
            indices.push_back(_indices[i]);
        } 

        for(int i=0; i<_n; i++){
            vec3 v = vec3(_vertices[i].position, _lengthPower);
            position.push_back(v);                     
        }
        glGenVertexArrays(1, &mVertexArray);
        glBindVertexArray(mVertexArray);

        glGenBuffers(1, &mPositionBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*position.size(), position.data(), GL_STATIC_DRAW); 

        glGenBuffers(1, &mIndicesBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*indices.size(), indices.data(), GL_STATIC_DRAW); 

    }

    void draw(){
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
        glDisableVertexAttribArray(0);

    }
    ~Quad(){

    }
private:

    std::vector<unsigned short> indices; 
    std::vector<vec3> position; 
    GLuint mVertexArray; 
    GLuint mPositionBuffer; 
    GLuint mIndicesBuffer; 
};

I'm using, OpenGL, glm, glfw etc.

\$\endgroup\$
6
  • \$\begingroup\$ What is the indices.size() size value in your draw method? And if your indices are of length 6 (= unsigned short indices[]= {0,1,2,1,2,3}; ), why is it working? Or you draw each quad in separate VBO when you use those working indices above? \$\endgroup\$
    – wondra
    Commented Feb 12, 2015 at 21:13
  • \$\begingroup\$ It should be 6, it's a vector I fill in the constructor. Something wrong with it ? \$\endgroup\$
    – R00t
    Commented Feb 12, 2015 at 21:16
  • \$\begingroup\$ Yes, each quad has its own VBO. \$\endgroup\$
    – R00t
    Commented Feb 12, 2015 at 21:17
  • \$\begingroup\$ But every VBO store an array of vertices. glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*position.size(), position.data(), GL_STATIC_DRAW); \$\endgroup\$
    – R00t
    Commented Feb 12, 2015 at 21:21
  • \$\begingroup\$ Well... I thought you put all terrain vertices in same VBO(I should read better :) ) Why would you wanted separate VBOs for each quad? It would completely destroy performance(recommended size is 1-4MB). You can have separate VBO for each quad, but as far as I know, only one VBO can be be source for one draw call. (if you dont count multidraws, gs or non-vbo subustitutions like texture arrays) \$\endgroup\$
    – wondra
    Commented Feb 12, 2015 at 22:38

2 Answers 2

1
\$\begingroup\$

Cause each quad have it's own VBO all the index in the VBO will go from zero to three. But you are sending index from 0 to _width*_height as you were indexing the original array of vertexes (and not the subset you pass in each VBO). Basically you are rendering random memory.

\$\endgroup\$
1
\$\begingroup\$

The call glDrawElements(..., indices.size(), GL_UNSIGNED_SHORT, 0); tells your GPU roughly following:

for(unsigned short i = 0 /*last parameter*/; i < indices.size(); i += 3 /*3 vertices/triangle*/ )
{
   drawTriangle(VBO[indices[i]], VBO[indices[i + 1]], VBO[indices[i + 2]] );
}

Do you see what is wrong now? If the value of indices[i] is higher than your size of VBO, it is a problem.
Moreover, for VBO it is recommended to have around 1-4MB of vertices in it - only 4 vertices/VBO will very likely kill your performance. You might be interested in instancing instead.

big edit reason: cant read right(solved in comments)

\$\endgroup\$
2
  • \$\begingroup\$ So it's impossible to render the terrain in separate buffers ? In other words, it's impossible for triangles to share vertices if they're not int the same buffer ? If not, then I really didn't get your answer. Thanks for your time, I really appreciate \$\endgroup\$
    – R00t
    Commented Feb 12, 2015 at 22:25
  • \$\begingroup\$ @R00t Well... I thought you put all terrain vertices in same VBO(I should read better :) ) Why would you wanted separate VBOs for each quad? It would completely destroy performance(recommended size is 1-4MB). You can have separate VBO for each quad, but as far as I know, only one VBO can be be source for one draw call. (if you dont count multidraws, gs or non-vbo subustitutions like texture arrays) \$\endgroup\$
    – wondra
    Commented Feb 12, 2015 at 22:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .