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!

how to use glVertexAttribPointer()

Postby riveranb » Sun Dec 11, 2011 3:43 pm

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?
riveranb
 
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Postby hendu » Mon Dec 12, 2011 2:15 pm

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.
hendu
 
Posts: 1559
Joined: Sat Dec 18, 2010 12:53 pm

Re: how to use glVertexAttribPointer()

Postby riveranb » Wed Dec 14, 2011 2:34 am

Thanks for reply.

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

cpp Code: Select all
 
pGlGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) wglGetProcAddress("glGetAttribLocation");
pGlEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray");
pGlDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glDisableVertexAttribArray");
pGlVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer");
 


And add corresponding extension functions
cpp 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()

Postby riveranb » Wed Dec 14, 2011 2:36 am

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?
riveranb
 
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Postby hybrid » Wed Dec 14, 2011 9:29 am

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.
hybrid
Admin
 
Posts: 13946
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany

Re: how to use glVertexAttribPointer()

Postby riveranb » Wed Dec 14, 2011 9:53 am

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.
riveranb
 
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am

Re: how to use glVertexAttribPointer()

Postby hendu » Wed Dec 14, 2011 10:27 am

Irr should open a GL 2.1 context, so having more able drivers shouldn't make a difference.
hendu
 
Posts: 1559
Joined: Sat Dec 18, 2010 12:53 pm

Re: how to use glVertexAttribPointer()

Postby riveranb » Fri Dec 16, 2011 4:28 am

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

cpp 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
cpp 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()

Postby riveranb » Fri Dec 16, 2011 7:04 am

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.
riveranb
 
Posts: 28
Joined: Fri Sep 23, 2011 9:37 am


Return to Advanced Help

Who is online

Users browsing this forum: Google Feedfetcher, penguin03 and 1 guest