Sign in Join

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

Mailing lists / fpc-pascal / 2013-02

dglOpenGL <-> GL, GLu, GLExt

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Juha Manninen

There is an OpenGL unit named dglOpenGL, maintained by www.delphigl.com, and used by many projects.

I want to use the units provided by FPC instead, namely GL, GLu and GLext. Mostly everything can be found from those units, except for one function:

  InitOpenGL;

It finds OpenGL functions from shared libs and maps them to function pointers.

Q: how am I supposed to initialize OpenGL when using units provided by FPC?

I am also using the TOpenGLControl component provided by LCL, for cross-platform OpenGL context.
I understand it basically takes care of the drawing window for OpenGL. The OpenGL initialization must be done before that. (?)

In fact the dglOpenGL unit is cross-platform, too, but I would like to use the built-in units as much as possible.

Juha

Marco van de Voort
to Juha Manninen

In our previous episode, Juha Manninen said:

Show quoted text 9 lines
There is an OpenGL unit named dglOpenGL, maintained by www.delphigl.com, and used by many projects. I want to use the units provided by FPC instead, namely GL, GLu and GLext. Mostly everything can be found from those units, except for one function: InitOpenGL; It finds OpenGL functions from shared libs and maps them to function pointers. Q: how am I supposed to initialize OpenGL when using units provided by FPC?

The unit does has as disadvantage that the filename can't be changed (or at least that first try can't be avoided).

After that, you iirc need to do load<something with glversion> from unit glext to load the extensions for later versions.

I only used basic functionality from FPC opengl, (I mostly use dglopengl), but, like dglopengl's readextension, you need to probably call those only after you created an appropriately versioned context. At least for opengl versions

Show quoted text 6 lines
=3 I am also using the TOpenGLControl component provided by LCL, for cross-platform OpenGL context. I understand it basically takes care of the drawing window for OpenGL. The OpenGL initialization must be done before that. (?)

Importing functions is not opengl initialization. The reason is the dynamic loading of DLLs, which requires extra action.

And even when dynamic, any form of initialization can be done in the unit startup code, but it is often hard to parameterize then. (which defeats the purpose of making it dynamic in the first place)

In fact the dglOpenGL unit is cross-platform, too, but I would like to use the built-in units as much as possible.

Most of my opengl code is Delphi in origin, but based on original demoes from Ales that were afaik ported from FPC to Delphi :_)

Now parts work with FPC again (though with dglopengl).

Juha Manninen
to Marco van de Voort
Marco van de Voort wrote 7 lines
> Q: how am I supposed to initialize OpenGL when using units provided by FPC? The unit does has as disadvantage that the filename can't be changed (or at least that first try can't be avoided). After that, you iirc need to do load<something with glversion> from unit glext to load the extensions for later versions.

Thanks Marco.

I didn't quite understand what is load<something with glversion>.

My experiments advance slowly. The original DeleD code validate OpenGL by checking if
@glActiveTextureARB, @glClientActiveTextureARB and @glMultiTexCoord2fARB are assigned.

With dglopengl it stops working when I replace
  H_RC := wglCreateContext(H_DC);
with the cross-platform OpenGLContext:
  fOpenGLControl1:=TOpenGLControl.Create(Self);
and replace
  wglMakeCurrent(H_DC, H_RC);
with
  OpenGLControl1.MakeCurrent;

When using GLExt (provided by FPC), the test still fails but then I can remove it and the code does not crash later.
So, maybe it is better to use GL and GLExt.
If I put the same test in the OpenGlControl demo in Lazarus, it does not fail! I don't see what makes the difference.

Cross-platform OpenGL still does not work though. Deled 3-D uses form inheritance and all forms needing OpenGL drawing window inherit from TOGLForm. I copy below the Create method where I had to comment out most code to make it compile.
I create fOpenGLControl1 the same way than in the Lazarus example, but I don't know what to put into the OnPaint and OnResize event handlers. Now the code does not crash but obviously does not draw anything either.

I guess I must study the topic more. I will commit my code to the DeleD SVN branch although it is broken. Maybe someone could have a ,
Juha

----------------------------

constructor TOGLForm.Create(AOwner: TComponent);
//var PixelFormat: Integer;
           // our windows pixel format
//    PFD: PixelFormatDescriptor;
           // describes the pixel format
begin
    inherited;
    Initialize;
    Set8087CW($133f);    // disable fpu exceptions when doing OpenGL rendering
    //ZeroMemory(@PFD, SizeOf(PFD));
           // describe our Pixel Format Descriptor
    //with PFD do begin
    //    nSize := SizeOf(PFD);
    //    nVersion := 1;
    //    dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER or 0;
    //    iPixelType := PFD_TYPE_RGBA;
    //    cColorBits := 16;
    //    cDepthBits := 16;
    //end;
    // now set pixel format + initialize rendering context
    //H_DC := Canvas.Handle;
    //PixelFormat := ChoosePixelFormat(H_DC, @PFD);
           // choose a pixel format based on our description
    //if PixelFormat = 0 then begin
    //    KillWindow;
    //    MessageBox(0, 'Unable to choose pixel format', 'Error',
MB_OK or MB_ICONERROR);
    //    Exit;
    //end;
    //if not SetPixelFormat(H_DC, PixelFormat, @PFD) then begin
           // attach the pixel format to the window
    //    KillWindow;
    //    MessageBox(0, 'Unable to set pixel format', 'Error', MB_OK
or MB_ICONERROR);
    //    Exit;
    //end;
    //H_RC := wglCreateContext(H_DC);
           // get the rendering context handle
    //if H_RC = 0 then begin
    //    KillWindow;
    //    MessageBox(0, 'Unable to create rendering context', 'Error',
MB_OK or MB_ICONERROR);
    //    Exit;
    //end;
    //ActivateRenderingContext(H_DC,H_RC);
    fOpenGLControl1:=TOpenGLControl.Create(Self);
    with fOpenGLControl1 do begin
      Name:='OpenGLControl1';
      Parent:=Self;
      SetBounds(10,90,380,200);
      ;
      ;
    end;
    if not fOpenGLControl1.MakeCurrent then begin
          // initialize the endering context
        KillWindow;
        MessageBox(0, 'Unable to activate rendering context', 'Error',
MB_OK or MB_ICONERROR);
        Exit;
    end;
end;
Sven Barth
to Juha Manninen
Juha Manninen wrote 13 lines
On Sun, Feb 17, 2013 at 11:12 PM, Marco van de Voort wrote: >> Q: how am I supposed to initialize OpenGL when using units provided by FPC? > > The unit does has as disadvantage that the filename > can't be changed (or at least that first try can't be avoided). > > After that, you iirc need to do load<something with glversion> from unit > glext to load the extensions for later versions. Thanks Marco. I didn't quite understand what is load<something with glversion>.

In unit GLext you have functions like Load_GL_version_1_3 which will load all core functions provided in OpenGL 1.3 or
Load_GL_ARB_multitexture which will load all ARB functions related to multitexturing (of course you should only do this if your version supports/needs this). This is necessary, because in different OpenGL versions different APIs were either part of the "core API" or where at least standardized, but still optional in the "ARB API" or where provided by specific vendors only "Ext API". So you need to decide first which OpenGL version you want to support where you might need to test first whether the version is supported at all at your client's computer by creating an approbiate context (Note: I don't know how this can be influenced with TOpenGLControl).

E.g. for current computer graphics you'll most likely want to have support for shaders for which you need to have at least OpenGL 2.0. If you want to have geometry shaders as well you need to use OpenGL 3.0 or newer. With newer versions you also can't use the fixed function pipeline anymore (glBegin() ... glEnd() ) [with the capabilities of shaders this isn't feasible anymore]

Show quoted text 6 lines
My experiments advance slowly. The original DeleD code validate OpenGL by checking if @glActiveTextureARB, @glClientActiveTextureARB and @glMultiTexCoord2fARB are assigned.

The Load_GL_... return a Boolean to tell you whether the functions could be loaded. I just checked the code of e.g. Load_GL_ARB_multitexture and it does even check for you whether the extension is supported.

I create fOpenGLControl1 the same way than in the Lazarus example, but I don't know what to put into the OnPaint and OnResize event handlers. Now the code does not crash but obviously does not draw anything either.

OnResize can be used to recalculate the projection matrix if the Window with the OpenGL control was resized.

OnPaint is the event where you do your rendering (and AFAIK call OpenGLControl.SwapBuffers at the end).

Show quoted text 9 lines
constructor TOGLForm.Create(AOwner: TComponent); //var PixelFormat: Integer; // our windows pixel format // PFD: PixelFormatDescriptor; // describes the pixel format begin inherited; Initialize; Set8087CW($133f); // disable fpu exceptions when doing OpenGL rendering

Note: If you really want to disable FPU exceptions you should use SetExceptionMask (
http://www.freepascal.org/docs-html/rtl/math/setexceptionmask.html ) instead as Set8087CW is supported on x86 only.

Regards,
Sven

Marco van de Voort
to Juha Manninen: Thanks Marco. I didn't quite understand what is load<something with glversion>. My…

In our previous episode, Juha Manninen said:

I didn't quite understand what is load<something with glversion>.

A function loadgl4.1 or loadglext4.1 or so. There was one for each version in glext to preload certain extensions (which afaik you can only load if you have created a proper context)

Show quoted text 15 lines
My experiments advance slowly. The original DeleD code validate OpenGL by checking if @glActiveTextureARB, @glClientActiveTextureARB and @glMultiTexCoord2fARB are assigned. With dglopengl it stops working when I replace H_RC := wglCreateContext(H_DC); with the cross-platform OpenGLContext: fOpenGLControl1:=TOpenGLControl.Create(Self); and replace wglMakeCurrent(H_DC, H_RC); with OpenGLControl1.MakeCurrent; From what I see it is TWSOpenGLControl.CreateHandle that creates the

context. Put a breakpoint on the lopenglcreatecontext function and make sure you hit the breakpoint when you create the topenglcontrol. I don't know what these WS components are good for.

Note also that openglcontrol seems to use its own headers (at least on Windows). I've only used opengl on Windows though (its for work)

Reimar Grabowski
to Sven Barth: In unit GLext you have functions like Load_GL_version_1_3 which will load all core…

On Sat, 23 Feb 2013 15:20:12 +0100
Sven Barth wrote:

Just a little addition:

In unit GLext you have functions like Load_GL_version_1_3 which will load all core functions provided in OpenGL 1.3

and lower. So Load_GL_version_2_0 will call Load_GL_version_1_5 which will call Load_GL_Version_1_4 ... A graphics card/driver supporting one OpenGL version is required to support the lower versions, too.

R.