how to use glVertexAttribPointer()

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

how to use glVertexAttribPointer()

Post by riveranb »

I want to use OpenGL vertex attribute array features with the irrlicht engine.
But when I call functions like
glEnableVertexAttribArray () or glVertexAttribPointer (), etc...
I got the following errors
1>.\COpenGLDriver.cpp(1443) : error C3861: 'glEnableVertexAttribArray': identifier not found

I am pretty sure that glEnableVertexAttribArray are the OpenGL 2.0 spec. featured procedure,
so that I think these functions should be no problem to use, just like glEnableClientState(), glVertexPointer(), glNormalPointer(), etc.

Maybe there's something wrong of what I've done?
Or I have to include glew.h (glew library) to call glewInit() to enable these OpenGL procedures?

Could anyone help me to solve this problem?
Or tell me how to add the procedure address (in COpenGLExtensionHandler ?) to activate these funcitons?
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: how to use glVertexAttribPointer()

Post by hendu »

Sounds like you're on Windows. MS has not updated their GL headers after 1.1, so to use any functions added after that version on Win you need to use the function pointers.
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Post by riveranb »

Thanks for reply.

I learn the way what the irrlicht engine have done to get the function pointers in COpenGLExtensionHandler

Code: Select all

 
pGlGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) wglGetProcAddress("glGetAttribLocation");
pGlEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray");
pGlDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glDisableVertexAttribArray");
pGlVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer");
 
And add corresponding extension functions

Code: Select all

 
GLint extGlGetAttribLocation(GLuint program, const char * name);
void extGlEnableVertexAttribArray(GLuint index);
void extGlDisableVertexAttribArray(GLuint index);
void extGlVertexAttribPointer(GLuint index, GLint size, GLenum type, bool normalized, GLsizei stride, const void * pointer);
 
Seems like working well.
Thanks
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Post by riveranb »

BTW, for linux and Mac OSX, they both utilize IRR_OGL_LOAD_EXTENSION to obtain the correct opengl extension function pointers?
Is Mac OSX based upon the X window solution?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: how to use glVertexAttribPointer()

Post by hybrid »

No, we never implemented extension pointers for OSX. You can only use those functions which have a proper implementation in the official GL headers under OSX.
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Post by riveranb »

oops, that's a bad news for me.


Well, now another problem comes to me,
It's about the vertex attribute belonged to a VBO with the glsl shader usage.

When I modify the code to send the vertex attribute data to glsl shader via the vertex array (COpenGLDriver :: drawVertexPrimitiveList) method,
it looks like OK, everything is drawn correctly.

But when I apply the mesh buffer as one vbo (COpenGLDriver :: drawHardwareBuffer) in irrlicht engine, it is missing on the screen.
I've checked some OpenGL spec. on internet, and I guess the main reason is because my OpenGL version is 4.2,
Is this OpenGL / GLSL version already deprecate functions like glVertexPointer / glNormalPointer / glColorPointer /....?
Instead, I have to use glVertexAttribPointer for all original built-in attribues in GLSL ( gl_Position, gl_Normal, gl_Color, gl_TexCoordx, ....)?

I have rarely few experiences on OpenGL 3.x+, so I am still try to figure it out.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: how to use glVertexAttribPointer()

Post by hendu »

Irr should open a GL 2.1 context, so having more able drivers shouldn't make a difference.
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Post by riveranb »

My friend mentioned me that the VBO utilization should be the same for any versions of OpenGL.
So if I am working fine on vertex array rendering with glsl shader, it should also be fine for the vertex buffer object rendering with the same shader.
(Because I didn't use define to specify a glsl version in my glsl shader codes.)
I am not sure though, but I will try to use glMapBuffer to check my buffer content.

And I explain what I have done for sending vertex attribute data in VBO.
I just modify the COpenGLDriver::drawVertexPrimitiveList to add a new function --> COpenGLDriver::drawAttributedVertexPrimitiveList

Code: Select all

 
void COpenGLDriver::drawAttributedVertexPrimitiveList(const void * vertices, u32 vertexCount,
        const void * indexList, u32 primitiveCount, const SVertexAttributeGL * attribArgs, u32 attribCount,
        E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
{
        if (!primitiveCount || !vertexCount)
                return;
         if(attribCount>0 && !attribArgs)
                return;
         if (!checkPrimitiveCount(primitiveCount))
                return;
         CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, attribArgs, attribCount, vType, pType, iType);
 
        if (vertices && !FeatureAvailable[IRR_ARB_vertex_array_bgra] && !FeatureAvailable[IRR_EXT_vertex_array_bgra])
                createColorBuffer(vertices, vertexCount, vType);
         // draw everything
        setRenderStates3DMode();
         if (MultiTextureExtension)
                extGlClientActiveTexture(GL_TEXTURE0_ARB);
         glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);
        if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
                glEnableClientState(GL_NORMAL_ARRAY);
        for(u32 i=0 ; i<attribCount ; i++)
                extGlEnableVertexAttribArray(attribArgs[i].locIndex);
         if (vertices)
        {
#if defined(GL_ARB_vertex_array_bgra) || defined(GL_EXT_vertex_array_bgra)
                if (FeatureAvailable[IRR_ARB_vertex_array_bgra] || FeatureAvailable[IRR_EXT_vertex_array_bgra])
                {
                        switch (vType)
                        {
                                case EVT_STANDARD:
                                        break;
                                case EVT_2TCOORDS:
                                        break;
                                case EVT_TANGENTS:
                                        break;
                                case EVT_ATTRIB:
                                        glColorPointer(GL_BGRA, GL_UNSIGNED_BYTE, sizeof(S3DVertexAttrib), &(static_cast<const S3DVertexAttrib *>(vertices))[0].Color);
                                        break;
                        }
                }
                else
#endif
                        glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
        }
         switch (vType)
        {
                case EVT_STANDARD:
                        break;
                case EVT_2TCOORDS:
                        break;
                case EVT_TANGENTS:
                        break;
 
                case EVT_ATTRIB:
                        if (vertices)
                        {
                                glNormalPointer(GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), &(static_cast<const S3DVertexAttribSkin_MG*>(vertices))[0].Normal);
                                glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), &(static_cast<const S3DVertexAttribSkin_MG*>(vertices))[0].TCoords);
                                glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), &(static_cast<const S3DVertexAttribSkin_MG*>(vertices))[0].Pos);
                        }
                        else
                        {
                                glNormalPointer(GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), buffer_offset(12));
                                glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertexAttribSkin_MG), buffer_offset(24));
                                glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), buffer_offset(28));
                                glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), 0);
                        }
                         if (MultiTextureExtension && CurrentTexture[1])
                        {
                                extGlClientActiveTexture(GL_TEXTURE1_ARB);
                                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                                if (vertices)
                                        glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), &(static_cast<const S3DVertexAttribSkin_MG*>(vertices))[0].TCoords);
                                else
                                        glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexAttribSkin_MG), buffer_offset(28));
                        }
                        // send vertex attribute array pointers
                        for(u32 i=0 ; i<attribCount ; i++)
                        {
                                if(vertices)
                                        extGlVertexAttribPointer(attribArgs[i].locIndex, attribArgs[i].componentSize, attribArgs[i].dataType, 
                                                attribArgs[i].normalized, sizeof(S3DVertexAttrib), attribArgs[i].pointer);
                                else
                                        extGlVertexAttribPointer(attribArgs[i].locIndex, attribArgs[i].componentSize, attribArgs[i].dataType,
                                                attribArgs[i].normalized, sizeof(S3DVertexAttrib), buffer_offset(attribArgs[i].bufferOffset));
                        }
                        break;
        }
         renderArray(indexList, primitiveCount, pType, iType);
         if (MultiTextureExtension)
        {
                if (vType==EVT_TANGENTS)
                {
                        extGlClientActiveTexture(GL_TEXTURE2_ARB);
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                if ((vType!=EVT_STANDARD) || CurrentTexture[1])
                {
                        extGlClientActiveTexture(GL_TEXTURE1_ARB);
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
                extGlClientActiveTexture(GL_TEXTURE0_ARB);
        }
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        for(u32 i=0 ; i<attribCount ; i++)
                extGlDisableVertexAttribArray(attribArgs[i].locIndex);
}
 
This function is OK to render the vertex array with vertex attribute data.
For VBO rendering, I just modify this way

Code: Select all

 
//! Draw hardware buffer
void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
{
        if (!_HWBuffer)
                return;
        updateHardwareBuffer(_HWBuffer); //check if update is needed
        _HWBuffer->LastUsed=0; //reset count
#if defined(GL_ARB_vertex_buffer_object)
        SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;
        const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
        const void *vertices=mb->getVertices();
        const void *indexList=mb->getIndices();
        if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER)
        {
                extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
                vertices=0;
        }
        if (HWBuffer->Mapped_Index!=scene::EHM_NEVER)
        {
                extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
                indexList=0;
        }
        if(mb->existVertexAttributes())
                drawAttributedVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3,
                        mb->getVertexAttributeArguments(), mb->getVertexAttributeCount(),
                        mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType());
        else
                drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType());
        if (HWBuffer->Mapped_Vertex!=scene::EHM_NEVER)
                extGlBindBuffer(GL_ARRAY_BUFFER, 0);
        if (HWBuffer->Mapped_Index!=scene::EHM_NEVER)
                extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
}
 
And VBO cannot be displayed now.
riveranb
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Post by riveranb »

Well, find the problem myself :D

in COpenGLDriver :: drawHardwareBuffer()

if(mb->existVertexAttributes())
drawAttributedVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3,
mb->getVertexAttributeArguments(), mb->getVertexAttributeCount(),
mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); <---- I passed the vertex array buffers again, which should pass null pointers.

should be
drawAttributedVertexPrimitiveList( vertices, mb->getVertexCount(), indexList, mb->getIndexCount() / 3,
mb->getVertexAttributeArguments(), mb->getVertexAttributeCount(), ..... );


And vbo CAN be displayed with my glsl shader now, haha.
Post Reply