Barış Uşaklı
Barış Uşaklı

Reputation: 13532

OpenGL attribute offset not working as intended

I am trying to figure out why the offset value used in glVertexAttribPointer isn't working as I expect it to.

The code is available at http://glbase.codeplex.com/

My vertex data is this :

glBase::Vector3 data1[]={
    glBase::Vector3(-0.4f,0.8f,-0.0f),  //Position
    glBase::Vector3(1.0f,0.0f,0.0f),    //Color
    glBase::Vector3(-.8f,-0.8f,-0.0f),  //Position etc
    glBase::Vector3(0.0f,1.0f,0.0f),
    glBase::Vector3(0.0f,-0.8f,-0.0f),
    glBase::Vector3(0.0f,0.0f,1.0f)
};

And the attribute binding happens like this :

program.bindVertexAttribs<float>(vbo1,0, "in_Position", 3, 6, 0);
program.bindVertexAttribs<float>(vbo1,1, "in_Color", 3, 6, 12);

bindVertexAttribs function is defined as follows :

template<typename T>
void bindVertexAttribs(const VertexBufferObject& object, GLint location,const std::string& name, unsigned int width, unsigned int stride, unsigned int offset)
{
    object.bind();

    glBindAttribLocation(m_ID, location, name.c_str());

    glVertexAttribPointer(location, width, GL_FLOAT, GL_FALSE, stride*sizeof(T),(GLvoid *)offset);
    glEnableVertexAttribArray(location);
}

This code doesn't render properly on my machine(ATI 5850,12.10 drivers) and renders the following :

enter image description here

If I change the attribute binding to :

program.bindVertexAttribs<float>(vbo1,0, "in_Position", 3, 6, 12);
program.bindVertexAttribs<float>(vbo1,1, "in_Color", 3, 6, 0);

I get the correct render like this :

enter image description here

This doesn't make sense to me as the position is the first 3 floats in the data array and color is the next 3 floats, then position again and so on. Am I missing something obvious?

Upvotes: 1

Views: 434

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473352

glBindAttribLocation(m_ID, location, name.c_str());

This does nothing; feel free to remove this line to see how much nothing it does.

If m_ID is a linked program object (and if it's not, then your code makes even less sense. Not unless you're using a VAO to capture your attribute array state), then this function will have no real effect. glBindAttribLocation only works before linking. You can't change the attribute binding after you link. So every object that uses a program needs to use the same attributes.

You should establish a proper convention for your vertex attribute names. When you create any program, you should apply your convention to the program before linking. That way, you know that in_position is always attribute 0, for example. You won't have to look it up with a pointless glGetAttribLocation call. And you won't be tempted to do the thing you're doing here, which doesn't work.

Upvotes: 2

Related Questions