PDA

View Full Version : OpenGL 1.5+ & ARB extentions



Maverick_75
12-13-2004, 11:19 PM
I would like to use OpenGL 1.5+ functionality. As I've read under windows we have access to version 1.1 only. All other functions we have to get via extentions or manualy get the proc address.

Although I'll request Opengl1.5 , I still would like to try if there is an ARB version of core functionality for older cards.

Here is my question, will the following code properly work?



...
void *myFunc = NULL;
...

...
myFunc = (void *) wglGetProcAddress("glWindowPos2i");
if (NULL == myFunc)
{
myFunc = (void *) wglGetProcAddress("glWindowPos2iARB");
}
if (NULL == myFunc) exit(0);
...

...
myFunc(10,10);
...Thanks in advance
PS: Any advices/critiques are welcome.

plasmonster
12-14-2004, 11:18 AM
In general, and as documented, it's always a good idea to query the extension string before you bind a function. Failure to do so may result in unexpected behavior. In short, don't do it that way, if you value your sanity.

There are many code examples of IsExtensionSupported() online if you need them. In a search, I'm sure some would turn up here or in the "advanced" forum.

Obli
12-14-2004, 01:25 PM
Originally posted by sgraham:
In general, and as documented, it's always a good idea to query the extension string before you bind a function. Failure to do so may result in unexpected behavior. In short, don't do it that way, if you value your sanity.I also wanted to bonk on that.
Check the extension string before fetching pointers to functions!
Unsupported funcs could also fetch with non-null address but could exploit bad behaviour.
On GLX, I heard the equivalent of wglGetProcAddres s always return non-zero (which does not make sense to me but that's what I've heard).


Originally posted by guyinhell:
There are many code examples of IsExtensionSupported() online if you need them.I never really used this extension but I still have to understand a single good reason to use it. It's much better, in my opinion, to stay with GetString(EXTENSIONS) and parse it correctly.

Fast way to check if an extension is present:
if(strstr(glGetString(GL_EXTENSIONS), "GL_ARB_fragment_program")) ret extensionIsPresent;
else ret failed;


Originally posted by Maverick_75:
will the following code properly work?
It's quite a bit I don't mess with pointers anymore but I think it won't (btw: can't you compile and see what happens?). :(
Little thing: there are a lot of extension loading libaries avaiable. I'm surprised no one told you that... but I understand you like fetching your stuff manually, which is The Right Way to do!

Why doesn't work?
Well, the idea of fetching core first then extenended name works. I already do that and it seems to work.
But...
"void*" is a pointer to a memory cell containing something not well identified.

"void (*)(int, int)" is a pointer to function. Well, I guess it is because I'm little stuck at this. But if I remember correctly that's the syntax required for WindowPos2i.

The extra syntax tells the compiler how to manage stack and is essential. Try what happens if you write it wrong! All the stack will get happily corrupted. Most of the time this is fatal and the program will be killed.

plasmonster
12-14-2004, 03:18 PM
I never really used this extension but I still have to understand a single good reason to use it.Obli, IsExtensionSupported is not an extension; it's a common name for a function that querries the extension string for the extension of interest. And as you know, one should take care to parse the extension string carefully; simply using strstr as you suggest could lead to problems. One should ensure that the entirety of the requested string is matched, not just a substring.

I'd also suggest using the function types provided in the extension headers to both declare and to cast function pointers. With a little thought and C/C++ macros, you can make quick work of this extension business.

Maverick_75
12-15-2004, 02:09 AM
Thanks for reply.

Yes I do check if those extentions are available first. And only after that I'm doing the stuff above.

The code seams to work properly for this functions.

I probably have not enougth knowledge in C/C++. What I would like to do is to use 1 function in my code, instead of using switch {} or other methods.

Hope I was clear :)

12-15-2004, 11:03 PM
Hi you., Sorry I use English language is very poor. I use opengl 1.5 too (dglopengl). If you want to progressik opengl on all card you can use the vertex program ARB. Suchikistia this:

In the InitOpenGL function :-
var VProgID: TGLUInt;
VProgAddr: TStringList;
begin
VProgramAddr.Create;
VProgramAddr.LoadFormFile('dol_vp_assembly.txt');
glGenProgramARB(1, @VProgID);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, PInt(VProgID));
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, Length(VProgramAddr.Text), Pbyte(Pchar(VProgramAddr)));
end;

and next step:
In the Render function you can use:-
procedure Render;
begin
glCearColor(..., ..., ..., ...);
glClear(......, ......);

//*** ENABLE TO FIXED FUNCTION PIPELINE ***
glEnable(GL_VERTEX_PROGRAM_ARB);
glBindProgramARB(1, PInt(VProgID));

ProcessGPU_FPS();
RenderWorld();
RenderModel();

SwapBuffer(DC);
end;

*** BUT IN THE glProgramStringARB is want to call all character assembly by vertex program assembly language in this sessiona I dus duran-ni 'dol_vp_assembly.txt' to find address all vertex and all environment in GPU pipeline ***

- Because GL_PROGRAM_FORMAT_ASCII_ARB is prosessonai el the all vertex and environment by ascii character into GPU pipeline.

- And if you want to want to great smooth the shading.
in example (the easy way):
a_vec
|\
| \
| \
b_vec | \ c_vec
+----\

in all vector (a_vec[x, y, z], b_vec[x, y, z], c_vec[x, y, z]) is use by:
normal_a_vec := Sqrt((x*x),(y*y),(z*z));
normal_b_vec := Sqrt((x*x),(y*y),(z*z));
normal_c_vec := Sqrt((x*x),(y*y),(z*z));
in the originally use:
fn_a_vec.x := x/normal_a_vec;
fn_a_vec.y := x/normal_a_vec;
fn_a_vec.z := x/normal_a_vec;

*** and math all vector to greater by normal light source in surface ***
use : a vector use progressionian by 1-(a_vec - c_vec)
use : b vector use progressionian by 1-(b_vec - a_vec)
use : c vector use progressionian by 1-(c_vec - b_vec)

That easily:
In the next time I will write my code and all mathematical to CD to post this it can be great normal polygon by light and len flares.

plasmonster
12-16-2004, 03:47 AM
The code seams to work properly for this functions.The code you gave, as it is, will not compile, unless something magical happens within the ellipses :)

And it's not so much a question of whether or not it works so much as it's a question of correctness. The extension string provides the driver developers with a way to advertise specific extensions that are intended for use. While you may be able to get a pointer to a function, this does not imply that it is usable; it means only that it has been exported.

You may want to look at the extension loading package that Obli mentioned. I've never used them, so I'll leave judgement to someone who has. But if you're determined to do it yourself, consider the following.

Suppose that in a header file, "Extensions.h", you had something like this:


#ifndef EXT
#define EXT(extension,type,name) extern type name;
#endif
...
// These names are in glext.h
EXT( GL_ARB_window_pos, PFNGLWINDOWPOS2IARBPROC, glWindowPos2iARB )
...
#undef EXTAnd in a corresponding source file you had something like this:


...

#define EXT( extension, type, name ) type name = NULL;
#include "Extensions.h"

void initExtensions()
{
#define EXT( extension, type, name )\
if( !isExtensionSupported(#extension) )\
exit(1);\
name = (type)wglGetProcAddress(#name);\
if( name == NULL )\
exit(1);

#include "Extensions.h"

#undef EXT
}

... Get the idea? This is just a rough example of what's possible. Chief among benefits of this approach is that we avoid typing the extension names more than once, thus averting a possible source of errors. We also get a fully automated system; we can add extensions to our header file as we see fit, with no additional actions required.

The one hitch to all this is the windowing system specific extensions. The problem is that in order to query the WGL extensions we need the WGL extensions string, which in turn is retrieved through an extension. We must therefore rely on wglGetProcAddress returning NULL if this extension isn't supported. In fact, it is specified to work in exactly that way:

http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_extensions_string.txt

Fortunately, this is the only WGL extension we must retrieve in this fashion; the rest may be queried in exactly the same way as before, using the WGL extension string instead of the one return by glGetString. So consider retrieving both strings up front--during context initialization, for example.