Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

c++ - OpenGL: INVALID_OPERATION following glEnableVertexAttribArray

I'm porting a functioning OpenGL app from Windows to OSX, and keep getting an "invalid operation" (code 1282) error after calling glEnableVertexAttribArray(). Here's the render method:

gl::Disable(gl::DEPTH_TEST);    
gl::Disable(gl::CULL_FACE);
gl::PolygonMode(gl::FRONT_AND_BACK,gl::FILL);

/// render full-screen quad
gl::UseProgram(m_program);

check_gl_error();

gl::BindBuffer(gl::ARRAY_BUFFER, m_vertexBuffer);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_indexBuffer);

check_gl_error();
GLint positionLocation = -1;

positionLocation = gl::GetAttribLocation(m_program,"Position");
check_gl_error();

/// positionLocation now == 0

gl::EnableVertexAttribArray(positionLocation);
//// ************ ERROR RETURNED HERE **********************
//// ************ ERROR RETURNED HERE **********************
check_gl_error();

gl::VertexAttribPointer(positionLocation,3,gl::FLOAT,false,3 * sizeof(GLfloat),(const GLvoid*)0);
check_gl_error();

gl::DrawElements(gl::TRIANGLES,m_indexCount,gl::UNSIGNED_SHORT,0);

check_gl_error();

gl::BindBuffer(gl::ARRAY_BUFFER,0);
check_gl_error();

gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER,0);
check_gl_error();

check_gl_error() just gets the last GL error and returns a somewhat-readable description thereof.

This code works fine under Windows. But, as I'm rapidly learning, that doesn't necessarily mean that it is correct. I've verified that all of the previously-bound objects (program, vertex buffer, index buffer) are valid handles. glGetAttribLocation() returns a valid location (0 in this case) for the Position attribute.

What are the failure cases for glEnableVertexAttribArray()? Is there some state that I've not set before this?

If I comment out the draw code, the window is cleared to my test color (red) (called from a method not shown in the code snippet) on every frame and everything else works fine, which implies that everything else is correct.

Suggestions?

Oh, for a GL state machine simulator that would tell me why it is an "invalid operation." (Or a reference to some mystical, magical documentation that describes required input state for each gl* call.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're seeing this error on OS X because it only supports the OpenGL Core Profile if you're using OpenGL 3.x or higher. Your code is not Core Profile compliant. You were most likely using the Compatibility Profile on Windows.

Specifically, the Core Profile requires a Vertex Array Object (VAO) to be bound for all vertex related calls. So before calling glEnableVertexAttribArray(), or other similar functions, you will need to create and bind a VAO:

GLuint vaoId = 0;
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);

On how to find out the error conditions: In this case, it's not nearly as easy as it should be. Let's say you work with a GL3 level feature set. In an ideal world, you would go to www.opengl.org, pull down the "Documentation" menu close to the top-left corner, choose "OpenGL 3.3 Reference Pages", click on glEnableVertexAttribArray in the left pane, and look at the "Errors" section on the page. Then you see that... GL_INVALID_OPERATION is not listed as a possible error.

Next, you might want to check if there's anything better in the latest version. You do the same, but choose "OpenGL 4 Reference Pages" instead. The error condition is still not listed.

By now you realize, like many before you, that these man pages are often faulty. So you go to the ultimate source: the specs. This time you choose "OpenGL Registry" in the Documentation menu. This gives you links to all the spec documents in PDF format. Again, let's try 3.3 first. Search for "EnableVertexAttribArray" in the document and there is... still no GL_INVALID_OPERATION documented as a possible error.

Last resort, checking the very latest spec document, which is 4.4. Again looking for "EnableVertexAttribArray", it's time for a heureka:

An INVALID_OPERATION error is generated if no vertex array object is bound.

I'm quite certain that the error also applies to GL3. While it's reasonably common for the man pages to be incomplete, it's much rarer for the spec documents to be missing things. The very closely related glVertexAttribPointer() call has this error condition documented in GL3 already.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...