Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-05

How to use OpenGL 2.0 fatures

21 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Lord Satan

Hi all,

I am trying to use FPCs OpenGL bindings instead of my own under Linux. But just replacing my bindings with the FPC ones does not seem to be enough as I get a segfault. GDB shows that using a OpenGL 2.0 core function crashes my program. I have seen that there are extension loading routines in glext.pas. Normally this is only needed on Windows (at least neither Linux nor OS X need this) but I think for cross plattform support this technique was introduced. Does it mean that all other Windows restrictions are also true? Meaning that only unextended OpenGL 1.2 is directly supported and that all other functions (even if they are core functions in newer OpenGL versions) need to be loaded? I could not find any documentation about this and would really appreciate it if someone could guide me in the right direction.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

dmitry boyarintsev
to Lord Satan

Hello Lord Satan

uses
...gl, glext...

...
  if not Load_GL_version_2_0 then begin
    writeln('OpenGL 2.0 is not supported');
    Halt;
  end;
...

Load_GL_version_2_0 function is declared at glext unit. you should call it before calling ANY 2.0 OpenGL function. also check out functions result, to see if an opengl driver supports 2.0 version.
ANY OS must call it (both Linux and OSX), otherwise function variables are not initialized!

thanks,
dmitry

Reply by email

Lord Satan
to dmitry boyarintsev
ANY OS must call it (both Linux and OSX), otherwise function variables are not initialized!

But this is an FPC restriction not an OpenGL one. My own OpenGL headers did not need this and they worked. Anyway, thanks for the information.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Marco van de Voort
to Lord Satan

In our previous episode, Lord Satan said:

Show quoted text 7 lines
On Sat, 9 May 2009 22:29:51 +0400 dmitry boyarintsev wrote: > ANY OS must call it (both Linux and OSX), otherwise function variables > are not initialized! But this is an FPC restriction not an OpenGL one. My own OpenGL headers did not need this and they worked. Anyway, thanks for the information.

I don't know if it is the case for this specific header, but I always try to make the initialization explicit. This mainly because then in case of changed library names the user can simply override by passing the new name to the initialization routine.

Note that there is a difference in an own header (that is usually part of the project), and a header that is mainly used precompiled. The latter has to last longer.

Reply by email

Lord Satan
to dmitry boyarintsev: Hello Lord Satan uses ...gl, glext... ... if not Load_GL_version_2_0 then begin…
Show quoted text 9 lines
uses ...gl, glext... ... if not Load_GL_version_2_0 then begin writeln('OpenGL 2.0 is not supported'); Halt; end; ...

This does not work for me. I added it to the Init function of my render engine (as I know that at this time I have a valid OpenGL context) to no avail. My code keeps crashing at this call (in a different unit, so I tried calling Load_GL_version_2_0 there too, with the same result):

if glIsBufferARB(VertexBuffer)=GL_TRUE then (asmtypes.pas:2212)

The backtrace is not very helpfull for me:

#0 0x0000000000000000 in ?? ()
#1 0x0000000000750491 in CREATEBUFFERS (this=0x7fb7e83cd200) at asmtypes.pas:2212

So I tried just loading the VBO extension:

if not glext_LoadExtension('GL_ARB_vertex_buffer_object') then begin
  writeln('VBO is not supported');
  Halt;
end;

Resulting in this:

#0 0x0000000000760a6f in GLEXT_EXTENSIONSUPPORTED ( EXTENSION=0xb39788 'GL_ARB_vertex_buffer_object',
SEARCHIN=0x7f7988ac2320 'GL_ARB_color_buffer_float GL_ARB_depth_texture GL_ARB_draw_buffers GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB'...) at gllibs/glext.pp:4268
#1 0x000000000076c7f3 in LOAD_GL_ARB_VERTEX_BUFFER_OBJECT () at gllibs/glext.pp:7591
#2 0x00000000007736c3 in GLEXT_LOADEXTENSION (
EXT=0xb2d788 'GL_ARB_vertex_buffer_object') at gllibs/glext.pp:9509

This is on Ubuntu 9.04 64-bit.
My card and driver support OpenGL Version 2.1.2, so that is not the problem.

Anyone any ideas?

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

dmitry boyarintsev
to Lord Satan
This does not work for me. I added it to the Init function of my render engine (as I know that at this time I have a valid OpenGL context) to no avail. My code keeps crashing at

glIsBufferARB function is loaded by Load_GL_ARB_vertex_buffer_object call it on Render engine initialization.

i'm not sure, if you neet ARB function, since it's extension function, rather than OpenGL version function.
Anyway, you might want to use glIsBuffer function, it's loaded by calling Load_GL_version_1_5

hope it helps.

thanks,
dmitry

Reply by email

Lord Satan
to dmitry boyarintsev
hope it helps.

It does, thanks.
So it looks like I have to init all OpenGL versions from 1.2 to 2.0 to make sure that all OpenGL 2.0 core functions are initialized. Is this true?

Nonetheless, I don't understand why the ARB version does not work. AFAIK it has the same entry points as the core functionality and OpenGL versions are required to support the ARB version of functions even if the non ARB version is in the core now.

Am I doing something wrong or is extension loading broken?

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

dmitry boyarintsev
to Lord Satan
So it looks like I have to init all OpenGL versions from 1.2 to 2.0 to make sure that all OpenGL 2.0 core functions are initialized. Is this true?

Judging from glext, it's true.
You'll also need to initialize any OpenGL extension you might to use.

> Nonetheless, I don't understand why the ARB version does not work. AFAIK it has the same entry points as the core functionality and OpenGL versions are required to support the ARB version of functions even if the non ARB version is in the core now.

ARB function should be loaded as well.
hmm, if you failed to load glIsBufferARB function, but did successfully loaded glIsBuffer function, why don't you bind them into single one?

  if glIsBufferARB = nil then  glIsBufferARB := @glIsBuffer;

thanks,
dmitry

Reply by email

Lord Satan
to dmitry boyarintsev
> So it looks like I have to init all OpenGL versions from 1.2 to 2.0 to make sure that all OpenGL 2.0 core functions are initialized. Is this true? Judging from glext, it's true.

This makes no sense to me. I can submit a patch so that all lower version functions are loaded when the higher version is loaded (hope it is understood what I mean). I already modified the glext file and just want to know if there is any interest or if the current behaviour has any advantages I fail to see.

why don't you bind them into single one? if glIsBufferARB = nil then glIsBufferARB := @glIsBuffer;

Because I only need one working function. I am just trying to understand the limitations of the bindings as there seems to be no documentation. If I will use them, I'd like to improve the current situation and make them as standard complient as possible.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Michalis Kamburelis
to Lord Satan: On Sun, 10 May 2009 17:54:49 +0400 It does, thanks. So it looks like I have to init all…
Lord Satan wrote 6 lines
Nonetheless, I don't understand why the ARB version does not work. AFAIK it has the same entry points as the core functionality and OpenGL versions are required to support the ARB version of functions even if the non ARB version is in the core now.

No. OpenGL doesn't have to support the extension entry points, even when it supports the same functionality in core already. Vendor is free to remove the extensions, and support only the "core" functions.

Also, sometimes when functionality is promoted from ARB extension into core it's slightly changed (although in 99% cases it stays the same). Example is the GLSL shaders, that expose (very slightly) different API through ARB extensions and through core 2.0 specification.

Basically, what is exposed through extensions is completely orthogonal to what is exposed through core functionality, so they should be initialized separately. In particular cases, you can make tricks like

  if glIsBufferARB = nil then glIsBufferARB := @glIsBuffer;

but this should be left to the final programmer that knows that "ARB_vertex_buffer_object" behavior is identical to how it works in core.

Michalis

Reply by email

Michalis Kamburelis
to Lord Satan: On Sun, 10 May 2009 18:46:26 +0400 This makes no sense to me. I can submit a patch so…
Lord Satan wrote 13 lines
On Sun, 10 May 2009 18:46:26 +0400 dmitry boyarintsev wrote: >> So it looks like I have to init all OpenGL versions from 1.2 to >> 2.0 to make sure that all OpenGL 2.0 core functions are >> initialized. Is this true? > Judging from glext, it's true. This makes no sense to me. I can submit a patch so that all lower version functions are loaded when the higher version is loaded (hope it is understood what I mean). I already modified the glext file and just want to know if there is any interest or if the current behaviour has any advantages I fail to see.

You mean you want to change Load_GL_version_2_0 to also call Load_GL_version_1_5 under the hood, and then Load_GL_version_1_5 to call Load_GL_version_1_4 under the hood and so on? I guess that's Ok, go for it.

Be aware that this will *not* work for OpenGL 3.x versions, where 3.0 deprecates and 3.1 removes some functions. Since 3.1, OpenGL versions are *not* guaranteed to be backwards compatible. Programmer will have to call Load_GL_version_3_1 and Load_GL_version_2_0 (or check ARB_compatibility) separately, since these are orthogonal.

I guess this is the advantage of current approach: it doesn't assume that OpenGL versions are backwards compatible, and indeed they don't have to be since 3.1.

But for GL 2.x and lower, sure, this will work fine.

Michalis

Reply by email

Lord Satan
to Michalis Kamburelis
Show quoted text 7 lines
Lord Satan wrote: > On Sun, 10 May 2009 18:46:26 +0400 dmitry boyarintsev > wrote: You mean you want to change Load_GL_version_2_0 to also call Load_GL_version_1_5 under the hood, and then Load_GL_version_1_5 to call Load_GL_version_1_4 under the hood and so on?

Yes.

I guess that's Ok, go for it.

Will do.

Be aware that this will *not* work for OpenGL 3.x versions, where 3.0 deprecates and 3.1 removes some functions.

I know. But this is only true for a 'forward compatible context'. Otherwise old functionality is fully supported. Btw the header do not even support 2.1 so no need to think about 3.x anytime soon. ;)

Thanks for the input.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Lord Satan
to Lord Satan

On Sun, 10 May 2009 23:47:07 +0200
Lord Satan wrote:

I uploaded the patch to the bug tracker as issue #0013687

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Michalis Kamburelis
to Lord Satan
Lord Satan wrote 5 lines
On Sun, 10 May 2009 23:47:07 +0200 Lord Satan wrote: I uploaded the patch to the bug tracker as issue #0013687

Looking quickly at the patch, it doesn't seem to set Result values correctly. For example, all Load_GL_version_xxx will always return true, if only the first Load_GL_version_1_2 will return true. If you call Load_GL_version_2_0, it will do "Result := Load_GL_version_1_5". If it set Result to true, then Result will remain true --- even if some gl 2.0 function, like glBlendEquationSeparate, will not exist and cause Exit.

Change this e.g. to follow each

  Result := Load_GL_version_1_5;

by

  if not Result then Exit;
  Result := FALSE;

... to make sure that Load_GL_version_2_0 returns true *only* if both Load_GL_version_1_5 succeeded *and* all functions on level 2.0 succeeded.

Michalis

Reply by email

dmitry boyarintsev
to Michalis Kamburelis
I am just trying to understand the limitations of the bindings as there seems to be no documentation.

The binding treats OpenGL versions in the same way as any other extension. Only new version function are loaded on demand. This makes the binding very *flexible*.
Because some obsolete functions might be removed in future OpenGL versions.

Instead of changing the binding, why don't you just declare a single utility function for your needs?

function Load_required_GL_version: Boolean;
begin
  Result := Load_GL_version_1_2 and
            Load_GL_version_1_3 and
            Load_GL_version_1_4 and
            Load_GL_version_1_5 and
            // add any other extension you might need here
            // load_GL_ARB_vertex_buffer_object and
            Load_GL_version_2_0;
end;

Chaning the binding might also break some existing code written with using it.

thanks,
dmitry

Reply by email

Marco van de Voort
to dmitry boyarintsev

In our previous episode, dmitry boyarintsev said:

Show quoted text 22 lines
> I am just trying to understand the > limitations of the bindings as there seems to be no documentation. The binding treats OpenGL versions in the same way as any other extension. Only new version function are loaded on demand. This makes the binding very *flexible*. Because some obsolete functions might be removed in future OpenGL versions. Instead of changing the binding, why don't you just declare a single utility function for your needs? function Load_required_GL_version: Boolean; begin Result := Load_GL_version_1_2 and Load_GL_version_1_3 and Load_GL_version_1_4 and Load_GL_version_1_5 and // add any other extension you might need here // load_GL_ARB_vertex_buffer_object and Load_GL_version_2_0; end; Chaning the binding might also break some existing code written with using it.

And document some of your problems here:

http://wiki.freepascal.org/OpenGL

(no rants, just short and to the point the stuff that needs to be done)

Reply by email

Lord Satan
to dmitry boyarintsev: The binding treats OpenGL versions in the same way as any other extension. Only new…
The binding treats OpenGL versions in the same way as any other extension.

Which isn't a good thing IMHO. The artificial limitation that you have to load higher version functions like extensions is just because M$ did and does not want to support OpenGL properly. As stated neither Linux nor OS X need this. So the bindings actually cripple the functionality of not M$ users. In C/C++ you can just include gl.h and glext.h and are done with it (as long as you don't work under Windoze).

Only new version function are loaded on demand. This makes the binding very *flexible*. Because some obsolete functions might be removed in future OpenGL versions.

OpenGL up to 2.1 is fully backward compatible. Although there does not seem to be a requirement to do so, I don't know of any extension that ever got removed from the driver. Doing so would break older programs relying on the functionality, which no vendor likes to do. It is just not good when old games don't work anymore just because you updated your driver from 1.5 to 2.0.

Instead of changing the binding, why don't you just declare a single utility function for your needs?

I don't want any workarounds. I want a clean and sane set of bindings that is not a major PITA to use. I don't have any need to switch to FPCs bindings. I don't support Windows and I have my own bindings where I don't even have to load extensions. I just check the string if the functionality is there and if so use it. I was just thinking that it would be a better idea to not do double work and therefor I am in the process of testing the FPC bindings. Unfortunately FPCs bindings are based on Delphi ones and all the limitations and annoyances I talk about originate from this fact. If you are a Windows user you will not notice much trouble as under Windows it is the normal way of using OpenGL (in any programming language). If you are not a windows user it is a major PITA.

Chaning the binding might also break some existing code written with using it.

May be. If this is a problem and nothing shall be changed then I am just wasting my time here. Tell me and I am back to my own stuff.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Lord Satan
to Michalis Kamburelis: Looking quickly at the patch, it doesn't seem to set Result values correctly. For…
Show quoted text 5 lines
Change this e.g. to follow each Result := Load_GL_version_1_5; by if not Result then Exit; Result := FALSE;
Instead I moved the Load_GL_version_x_x calls to the end of the functions. Replacing Result:=TRUE;
... to make sure that Load_GL_version_2_0 returns true *only* if both Load_GL_version_1_5 succeeded *and* all functions on level 2.0 succeeded.

You are absolutely correct.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

Lord Satan
to dmitry boyarintsev: The binding treats OpenGL versions in the same way as any other extension. Only new…
Only new version function are loaded on demand. This makes the binding very *flexible*. Because some obsolete functions might be removed in future OpenGL versions.

OpenGL 3.x also deprecates many OpenGL 1.1 functions (for example immediate mode). OpenGL 1.1 is not loaded (as there is no need even on windows) so how does the 'flexibility' help us there? I also fail to see how loading of OpenGL 1.5 for example helps, if only two of 1.5s functions are deprecated. The bindings have to be changed nonetheless. The bindings where not created with flexibility in mind. It looks more like somebody just ported the Delphi bindings without really knowing what he is doing. No offense meant here just an observation.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email

dmitry boyarintsev
to Lord Satan
OpenGL 3.x also deprecates many OpenGL 1.1 functions (for example immediate mode). OpenGL 1.1 is not loaded (as there is no need even on windows) so how does the 'flexibility' help us there?

Binding flexibility is required, if application is to be distributed. There's no way to say, what kind of OpenGL drivers is installed on the next machine.

for example, an application uses some 2.0 features (that're available in earlier gl versions as some extensions)
The application will run fine with OpenGL 2.0 drives installed, but if there's older drivers it will probably fail.

The most robust code is the following:

if not Load_SomeFunc_asCore and
   not Load_SomeFunc_asExtension then begin
  writeln('Please, update OpenGL drivers');
  Halt;
end;

I know, it's easy, to say: "My application requirement is GL 2.0 or higher", but, personally, i prefer to care about the user, rather making him/her to install latests drivers.

thanks,
dmitry

Reply by email

Lord Satan
to dmitry boyarintsev
Binding flexibility is required, if application is to be distributed. There's no way to say, what kind of OpenGL drivers is installed on the next machine.

First of all this is no answer to my question. I was speaking about 3.x and deprecated 1.1 features. Second, as long as you don't use features the target machine does not support there is no problem with exposing all OpenGL functions. This is how it is done in C/C++ on non Windows OSes since forever.

Show quoted text 7 lines
The most robust code is the following: if not Load_SomeFunc_asCore and not Load_SomeFunc_asExtension then begin writeln('Please, update OpenGL drivers'); Halt; end;

The 'normal' way of doing this is by checking the reported OpenGL version and query the extension string for your wanted functionality (glGet functions). Your way may expose functions whose entry points are defined in the driver but not advertised in the extension string (ATI did this alot to give developers some time to play with the extensions which they thought were not really ready for the general usage). Of couse it is ok to use these extensions just not recommended for published software.

I know, it's easy, to say: "My application requirement is GL 2.0 or higher", but, personally, i prefer to care about the user, rather making him/her to install latests drivers.

It is nice that there are some OpenGL developers who only need the basics. No problem with that. But if you are doing anything remotely advanced then 2.0 is an acceptable requirement (keyword: programmable pipeline). IMHO it is better to tell the user that his driver (and most likely his hardware) are not good enough for the job than to give him some sh***y experience. It is frustating for the user to see 1.000.000+ polygon scenes with per-fragment lighting and soft shadows in your screenshots and if he fires up the application he gets 15 triangles on a black background and does not know why. But I think we are slowly moving OT here. If you want to discuss general OpenGL development with me, you can send me a private mail.

I don't really have any problems with the bindings in general. It is just that they force you to do some things that are not needed on non Windows platforms. I can live with that, but you can try as hard as you like, I won't believe you that there are other reasons for the state of the bindings than that they are 'just' a Delphi port. The only real problem I have is that I don't get all functions up to version x.x if I load_gl_version_x_x. But I hope my patch will be accepted to remedy this problem.

S.

A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?

Reply by email