PDA

View Full Version : Wierd glLockArraysEXT() segfault occurring.



KallDrexx
12-15-2002, 07:12 PM
I know this may sound like a newbie question but I didn't really see much extension talk in the beginners forum so I thought it was more appropiate here. I was making a small opengl app that tested rendering multiple triangles nad quads using both display lists and vertex arrays. While writing it I started to write the code to take advantage of locking/unlocking the va. Unfortunatly I never used extensions or their functionsbefore and I coudln't figure out what i was doing wrong (compile errors and such) and since I was on a deadline I gave up and went on with the test. Recently I found ogl.org's all about extensions article and I then understood what i was doing wrong and how to understand what extensions do and how to use them.

So I got bored and i wanted to see if I coudl get the ufnctions working. I got it to compile, and in my class when it loads up the VA I then check for GL_EXT_compiled_vertex_arrays extension and if it's supported, set the function pointers for glLockArraysEXT() and glUnlockArraysEXT(). I put the glUnlockArraysEXT() in my class' destructor and I put the LockArraysEXT() at the end of the loading function (with the parameters). However using gdb and running it it seg faults on the glLockArraysEXT() line BUT what's weird is the crash is being reported in the glUnlockArraysEXT() (which ahs no reason to be called since it's in the destructor). the backtrace is this:

#0 0x08052313 in glUnlockArraysEXT ()
#1 0x0804bd98 in cTerrain::loadFoliage (this=0x40912008) at terrain.cpp:311
#2 0x0804b53f in initGL () at dltest.cpp:118
#3 0x0804b7cf in main (argc=1, argv=0xbffffcd4) at dltest.cpp:223

the terrain.cpp:311 is just glLockArraysEXT(0, 2); Does this make sense to anyone?

Also on a side but related question. When I was declaring the typdef for PFNGLLOCKARRAYSEXTPROC the specs say the function uses 2 parameters, int first and sizei count. However in order to get it to compile i had to change sizei to int. with sizei I get:
terrain.cpp:14: conflicting types for `typedef void (* PFNGLLOCKARRAYSEXTPROC)(...)'
/usr/include/GL/glext.h:2301: previous declaration as `typedef void (* PFNGLLOCKARRAYSEXTPROC)(int, int)'

Anyone know why? I don't know if that's related to the first problem or not.

Also what exaclty is the count parameter? rather what is it a count of? I tried 2 (2 array types are being used) and 4 (4 vertecies are in the arrays).

Sorry for these somewhat newbish questions.

--KallDRexx

Jan
12-16-2002, 08:13 AM
I know those problems with initializing and checking for extensions. I needed quite long to figure it out and i still have problems in doing it myself.
I also found out that "sizei" seems to be a definition that is used in the extension specs, which should be changed into int (or typedefed).
However if you want to be sure that all your extensions are intialized properly, than you should use the "Extension loading library". It is really helpfull.

You can find it at http://www.levp.de/3d/

There is also another extension loading library, which is as far as i know exactly the same as the one mentioned above, only with another name. You can find the link to it in the news of opengl.org. (Itīs called GLEW).

Jan.

zeckensack
12-16-2002, 08:39 AM
1)The GL prefix is omitted in most OpenGL related documentation.

Change sizei to GLsizei and you get the right datatype (if you include gl/gl.h, that is).

2)There's no need to declare PFNGLLOCKARRAYSEXTPROC yourself. Include glext.h or an extension header from your favourite vendor (I have glati.h, you may need something else). It should already be declared there. glext.h can be downloaded from the extension registry (http://oss.sgi.com/projects/ogl-sample/registry/) .

3)Post your extension loading code. Maybe you got a NULL pointer, or you have a typo in there or something.

KallDrexx
12-16-2002, 10:53 AM
ah ok thanks. GLsizei compiled but didn't help it really. Here's the code samples (havne't tried with including the glext.h yet)



// Check to see if we can lock/unlock arrays
char *extList = (char *) glGetString(GL_EXTENSIONS);
if (extList && strstr(extList, "GL_EXT_compiled_vertex_array"))
{
// get the address of the compiled array extensions
glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)
SDL_GL_GetProcAddress("glLockArraysEXT");
glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)
SDL_GL_GetProcAddress("glUnlockArraysEXT");
printf("GL_EXT_compiled_vertex_array is supported\n");
}
else
{
printf("GL_EXT_compiled_vertex_array not available\n");
}
printf("about to lock arrays\n");
if (glLockArraysEXT)
{
glLockArraysEXT(0, 2);
printf("Arrays locked!\n");
}


thanks.

I've seen that extension loading library before but I would rather know how it all works now and see what i'm doing wrong right now. I'll check it out though. I don't see how it does the functions but I ahvne't looked much into it. Thanks for the link tho it does have some good info.

ah that glext is nice, now i dont' have to worry about PFNBLAHPROC names nad stuff!

--KallDrexx

[This message has been edited by KallDrexx (edited 12-16-2002).]

zeckensack
12-16-2002, 11:18 AM
The code looks good. Does it work if you skip your own declaration of PFNblabla and use the glext.h version?

I suspect there's some calling convention stuff going wrong (__stdcall or so).

How do you declare PFNGLLOCKARRAYSEXTPROC (sheesh!)?

KallDrexx
12-16-2002, 11:25 AM
no it crashes the same way without the PFN declaration/using glext.h's declaration so I know it's not that..

[edit] but if you still want to know this is how i declared them (uncommented of course)
//typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (int first, GLsizei count);
//typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);

--KallDrexx

[This message has been edited by KallDrexx (edited 12-16-2002).]

Coriolis
12-16-2002, 12:22 PM
Have you verified that the function pointers are valid at the point of the crash? Also, releasing a resource in the destructor is usually only a good idea if you grab the resource in the constructor. It could be that both pointers are invalid, so calling the lock causes an exception to be thrown, which forces the destructor to get hit for the class causing the unlock to get called causing it to throw an exception which is the one for which you actually get the message.

KallDrexx
12-16-2002, 05:21 PM
Well i'm not quite sure where else to put the unlock function but I can move it. But if you look at the code I pasted above I if (glLockArraysEXT)
{
glLockArraysEXT(0,2);
}

so yeah I am checking, unless that's nto the way to do it but thats ussually how i check a pointers not NULL.

also noone still has explained to me about what the count actually is the count of. If someone coudl do that too I would appreciate it.

--KallDrexx

KallDrexx
12-16-2002, 05:37 PM
ok put glUnlockArraysEXT() after my main game loop and still the same bt:


#0 0x08052313 in glUnlockArraysEXT ()
#1 0x0804bd98 in cTerrain::loadFoliage (this=0x40912008) at terrain.cpp:313
#2 0x0804b53f in initGL () at dltest.cpp:119
#3 0x0804b7cf in main (argc=1, argv=0xbffffcd4) at dltest.cpp:224


terrain.cpp:313 is indeed glLockArraysEXT(0,2); so i'm stumped.. is this making sense to anyone?

--KallDrexx

zeckensack
12-16-2002, 06:20 PM
You lock/unlock a region of the vertex array.

first is the offset into the array.
size is the number of vertices.

So if you have a vertex array holding 5000 vertices, you'd
glLockArraysEXT(0,5000);
to lock it completely, or
glLockArraysEXT(2500,2500);
to lock the second half of it.

Just like the arguments to glDrawArrays.

KallDrexx
12-16-2002, 06:36 PM
ah ok, i set it to glLockArraysEXT(0, 55000 * 4);

since i'm rendering 55000 quads. Still crashes at the same spot. Though looking around I found out about VARS, and is there still a point to locking/unlocking arrays since you can just use VARs?

--KallDrexx

pbrown
12-19-2002, 06:43 PM
When you call LockArraysEXT(first, count), you are effectively making a few promises to the driver, including:

(1) for every array enabled at LockArraysEXT time, elements <first> through <first> + <count> - 1 of the array hold valid data, and

(2) for every array enabled at LockArraysEXT time, you're not going to screw with the data until you call UnlockArraysEXT.

As one naive example, a software T&L engine might pre-transform all the vertices in the range, and use the transformed results for subsequent rendering (assuming the matrices don't change). A hardware T&L driver might copy the array contents into AGP or video memory and then process DrawElements calls by sending indices. In general, a driver will take your hint and try to make things faster for your device.

But you do need to keep your end of the bargain. You need to set up your pointers before calling LockArraysEXT. You need to make sure that the index range you give LockArraysEXT holds valid data for all vertices. When you render between LockArraysEXT and UnlockArraysEXT, you have to make sure that you don't pass any indices outside of the locked index array. And you need to make sure you don't overwrite the data, since in the examples above, your changes may have no effect (you'd get the "wrong" results).

Do any of these things wrong and "undefined" results may ensue. For uninitialized pointers (and also possibly out-of-range indices), "undefined" results could well include crashes.

Hope this helps,
Pat