6 Replies Latest reply on Sep 10, 2010 9:47 PM by salehqt

    Vertex attribute binding in GLSL

    salehqt
      call to glVertexAttribPointer always fails

      Call to glVertexAttribPointer always fails. after looking up in some other forums, I thought it might be the problem with binding attributes to shader variables. I checked attribute locations in shader program and it correctly maps in_Position to 0 index slot. EnableVertexAttribArray on index slot 0 does not give any error but glVertexAttribPointer fails with GL_INVALID_OPERATION. 

      It happens to all my OpenGL programs which make use of shaders. Even ones which does not directly use VertexAttribPointer and use old-style VertexPointer call.

      Same scenario happens with freeglut sample program, smooth_opengl3, in both Windows and Linux.

       

      GPU: Radeon HD5830 

      OS: Ubuntu 64-bit 10.04 & Windows 7 32-bit

      Driver: Catalyst 10.6

       

        • Vertex attribute binding in GLSL
          frali

          Could you please provide the program? You know the function certainly works for most of the cases, we need more information.

            • Vertex attribute binding in GLSL
              salehqt

              Easiest way to reproduce the error:

              1. Download freeglut-2.6.0.tar.gz from http://freeglut.sourceforge.net/  and extract it

              2. Open C++ project file from VisualStudio2008Static folder and Build the project

              3. Switch startup project to smooth_opengl3 and run it.

              4. You will see OpenGL 0x502 error on console output.

              5. Tracking down the error you will see it happens at call to VertexAttribPointer. 

               

                • Vertex attribute binding in GLSL
                  macbirdie

                  Hello, I have a very simple application for windows, doing some basic setup of the context, loading, compiling shaders, setting up vertex array objects for a colored square and rendering the scene.

                  It worked in OpenGL 3.2 context in February with Catalysts 10.2 and 10.3 IIRC, but in 10.7 and 10.8 it's no longer working, failing at glVertexAttribPointer with GL_INVALID_OPERATION.

                  If I change context to 3.1, it works just fine.

                  Some simplest example apps demoing OpenGL 3.2 don't work as well.

                   

                  It fails at the first glVertexAttribPointer call already.
                  Here are relevant parts of the code, nothing special, really.

                   

                  Creating context:

                   

                  PIXELFORMATDESCRIPTOR pfd;
                  memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR) );
                  pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
                  pfd.nVersion = 1;
                  pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
                  pfd.iPixelType = PFD_TYPE_RGBA;
                  pfd.cColorBits = 32;
                  pfd.cDepthBits = 24;
                  pfd.iLayerType = PFD_MAIN_PLANE;

                  const int nPixelFormat = ::ChoosePixelFormat( _dc, &pfd );
                  if(nPixelFormat == 0)
                  return false;

                  const BOOL result = ::SetPixelFormat( _dc, nPixelFormat, &pfd );

                  if( !result )
                  return false;

                  HGLRC tempContext = ::wglCreateContext( _dc );
                  ::wglMakeCurrent( _dc, tempContext );

                  initAPI();

                  int major, minor;
                  getGLVersion(&major, &minor);

                  if(major < 3 || (major == 3 && minor < 2))
                  {
                  ::MessageBox(NULL, _T("OpenGL 3.2 not supported!"), _T("Error!"), MB_ICONERROR);
                  return false;
                  }

                  major = 3;
                  minor = 2;

                  wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
                  if(wglCreateContextAttribsARB != NULL)
                  {
                  m_hrc = NULL;
                  int attribs[] =
                  {
                  WGL_CONTEXT_MAJOR_VERSION_ARB, major,
                  WGL_CONTEXT_MINOR_VERSION_ARB, minor,
                  WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
                  WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
                  0
                  };

                  m_hrc = wglCreateContextAttribsARB(_dc, NULL, attribs);
                  }
                  else
                  {
                  ::MessageBox(NULL, _T("OpenGL 3.x Rendering Context function was not retrieved!"), _T("Error!"), MB_ICONERROR);
                  ::wglMakeCurrent( NULL, NULL );
                  ::wglDeleteContext( tempContext );
                  return false;
                  }

                  ::wglMakeCurrent( _dc, m_hrc );
                  assert( ::glGetError() == GL_NO_ERROR );
                  ::wglDeleteContext( tempContext );

                  if (!m_hrc)
                  {
                  ::MessageBox(NULL, _T("OpenGL 3.x Rendering Context was not created!"), _T("Error!"), MB_ICONERROR);
                  return false;
                  }

                  return true;

                   

                   

                   

                   

                   

                  And setting up the scene:
                  GLenum err;
                  //::wglMakeCurrent(dc, m_hrc);
                  //assert( ::glGetError() == GL_NO_ERROR );

                  m_pProgram = new GLProgram();
                  m_pVertexShader = new GLShader( VERTEX_SHADER );
                  m_pFragmentShader = new GLShader( FRAGMENT_SHADER );

                  bool success;
                  success = m_pVertexShader->load( "minimal_vs.glsl" );
                  assert( success );
                  success = m_pFragmentShader->load( "minimal_fs.glsl" );
                  assert( success );

                  success = m_pVertexShader->compile();
                  assert( success );

                  success = m_pFragmentShader->compile();
                  assert( success );

                  m_pProgram->attachShader( m_pVertexShader );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->attachShader( m_pFragmentShader );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->bindAttribLocation( 0, "in_Position" );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->bindAttribLocation( 1, "in_Color" );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->bindFragDataLocation( 0, "out_Color" );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->link();
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  m_pProgram->use();
                  assert( (err = ::glGetError()) == GL_NO_ERROR );


                  ::glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glClearDepth( 1.0f );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glEnable( GL_DEPTH_TEST );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glDepthFunc( GL_LEQUAL );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  GLfloat * v = new GLfloat[ 12 ];
                  GLfloat * c = new GLfloat[ 12 ];
                  v[0] = -0.8f; v[1] = 0.8f; v[2] = -1.0f;
                  v[3] = 0.8f; v[4] = 0.8f; v[5] = -1.0f;
                  v[6] = -0.8f; v[7] = -0.8f; v[8] = -1.0f;
                  v[9] = 0.8f; v[10] = -0.8f; v[11] = -1.0f;

                  c[0] = 1.0f; c[1] = 0.0f; c[2] = 0.0f;
                  c[3] = 0.0f; c[4] = 1.0f; c[5] = 0.0f;
                  c[6] = 0.0f; c[7] = 0.0f; c[8] = 1.0f;
                  c[9] = 1.0f; c[10] = 0.0f; c[11] = 1.0f;

                  ::glGenBuffers( 2, &m_vboID[0] );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glEnableVertexAttribArray( 0 );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0] );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );
                  ::glBufferData( GL_ARRAY_BUFFER, 12 * sizeof( GLfloat ), v, GL_STATIC_DRAW );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );
                  ::glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)NULL );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  ::glEnableVertexAttribArray( 1 );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );
                  ::glBindBuffer( GL_ARRAY_BUFFER, m_vboID[1] );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );
                  ::glBufferData( GL_ARRAY_BUFFER, 12 * sizeof( GLfloat ), c, GL_STATIC_DRAW );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );
                  ::glVertexAttribPointer( (GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, NULL );
                  assert( (err = ::glGetError()) == GL_NO_ERROR );

                  delete [] v;
                  delete [] c;

                  ::glDrawBuffer( GL_BACK_LEFT );
                  assert( ::glGetError() == GL_NO_ERROR );

                    • Vertex attribute binding in GLSL
                      Taz1024

                      Try inserting this after glGenBuffers:

                      GLuint ArrayObject;

                      glGenVertexArrays(1, &ArrayObject);

                      glBindVertexArray(ArrayObject);

                       

                      From section 2.8 of the GL 3.2 spec:

                       

                      An INVALID_OPERATION error is generated if any of the *Pointer commands specifying the location and organization of vertex array data are called while zero is bound to the ARRAY_BUFFER buffer object binding point (see section 2.9.6),and the pointer argument is not NULL.

                      It broke my stuff as well and I thought it was a bug, but apparently it's how forward compatible contexts are supposed to work.