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?
how to use glVertexAttribPointer()
Re: how to use glVertexAttribPointer()
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.
Re: how to use glVertexAttribPointer()
Thanks for reply.
I learn the way what the irrlicht engine have done to get the function pointers in COpenGLExtensionHandler
And add corresponding extension functions
Seems like working well.
Thanks
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");
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);
Thanks
Re: how to use glVertexAttribPointer()
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?
Is Mac OSX based upon the X window solution?
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: how to use glVertexAttribPointer()
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.
Re: how to use glVertexAttribPointer()
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.
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.
Re: how to use glVertexAttribPointer()
Irr should open a GL 2.1 context, so having more able drivers shouldn't make a difference.
Re: how to use glVertexAttribPointer()
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
This function is OK to render the vertex array with vertex attribute data.
For VBO rendering, I just modify this way
And VBO cannot be displayed now.
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);
}
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
}
Re: how to use glVertexAttribPointer()
Well, find the problem myself
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.
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.