Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
16 Views

fwglGetProcAddress (OpenGL + Windows + Intel Fortran)

I am trying to use OpenGL functions that are not directly supported by Windows, which only supports GL functions up to OpenGL 1.1. Supposedly the  the wglGetProcAddress function allows access to functions supported by the graphics hardware from following versions of OpenGL.

Here's what I'm trying to do....

 
      hWnd = CreateOpenGLWindow( ... )
      hDC  = GetDC(hWnd)
      hRC  = fwglCreateContext(hDC)
      hret = fwglMakeCurrent(hDC, hRC)
      anam = 'glGenVertexArray'C
      f    = fwglGetProcAddress(LOC(anam))

 

When I run this code I get f = zero, which indicates (I think) that function is not supported. I've tried this with various functions with similar results. This particular one is an OpenGL 3.0 function, and my graphics card is a relatively modern AMD Radeon which claims to support up to OpenGL 4.1. so it should be available. Questions:

  1.  Am I calling fwglGetProcAddress correctly (should I use C_LOC instead)?
  2.  If I did get a function address back from this call to fwglGetProcAddress - how would I then call that function?   It would still need some sort of C++ interface in order to call it from Fortran, correct?

Basic system info: I'm using Intel(R) Visual Fortran Composer XE 2013 and Microsoft Visual Studio* 2010, on Windows 7.

 

Thanks

 

 

 

0 Kudos
10 Replies
Highlighted
16 Views

You're calling the function

You're calling the function correctly - C_LOC would not work because the argument is INTEGER(GLvoid), not C_PTR. Other than that, I have no clue whether this ought to work. I did find http://stackoverflow.com/questions/21769427/wglgetprocaddress-returns-null which seems relevant and possibly helpful.

Yes, you will need an interface. I suggest you look at the DLL\DynamicLoad sample provided by Intel Visual Fortran for an example of how to do this.

Retired 12/31/2016
0 Kudos
Highlighted
New Contributor II
16 Views

Maybe there is a typo:

Maybe there is a typo: glGenVertexArrays (Mind the "s"). Does this help?

Robert

 

0 Kudos
Highlighted
Valued Contributor III
16 Views

Case and spelling needs to

Case and spelling needs to match you could also call GetLastError. if null is returned.

0 Kudos
Highlighted
Beginner
16 Views

Quote:Robert van Amerongen

Robert van Amerongen wrote:

Maybe there is a typo: glGenVertexArrays (Mind the "s"). Does this help?

Robert

 

No, good catch but that doesn't help.  I also made sure I've got a current display context:

 

hWnd  = CreateOpenGLWindow(        "foo", &
            0, 0, 1024, 700, color, buffer, WindowProc) 
hDC   = GetDC(hWnd) 
hRC   = fwglCreateContext(hDC) 
hret  = fwglMakeCurrent(hDC, hRC) 
icurr = fwglGetCurrentContext()
anam  = 'glGenVertexArrays'C
ifunc = fwglGetProcAddress(LOC(anam)) 
PRINT *, 'current context: ', icurr, ' procedure handle: ', ifunc

this prints:

 current context:        65536  procedure handle:            0

I will check the GetError return next...

0 Kudos
Highlighted
Beginner
16 Views

anam = 'glGenVertexArrays'C

anam = 'glGenVertexArrays'C
ifunc = fwglGetProcAddress(LOC(anam)) 
ierr = GetLastError()
PRINT ('(A10, Z)'), 'Error is ', ierr

this prints:

 

 Error is           7F

 

which translates to "ERROR_PROC_NOT_FOUND"

according to the MS system error code webpage.

 

 

 

0 Kudos
Highlighted
16 Views

Well, there's your answer....

Well, there's your answer.... I don't think it's sufficient for just the hardware to support the function.

Retired 12/31/2016
0 Kudos
Highlighted
Valued Contributor II
16 Views

There wasn't enough context

There wasn't enough context for me to easily make a full compilable example, so I started with Rings.f90 from the Samples directory. I made the following changes:

! Set up the OpenGL context
!
hDC = GetDC(hWnd)
hRC = fwglCreateContext(hDC)
hret = fwglMakeCurrent(hDC, hRC)
! Test stuff here:
BLOCK
    character(80) anam
    integer(HANDLE) f
    character(80) msg
    integer iret
    interface
       function wglGetProcAddress(name) bind(C,name='wglGetProcAddress')
          use ISO_C_BINDING, only: C_CHAR
          import
          implicit none
          integer(HANDLE) :: wglGetProcAddress
!DEC$ ATTRIBUTES STDCALL :: wglGetProcAddress
          character(kind=C_CHAR), intent(in) :: name(*)
       end function wglGetProcAddress
    end interface
      anam = 'glGenVertexArrays'C
      !f    = fwglGetProcAddress(LOC(anam))
      f    = wglGetProcAddress(anam)
      write(msg,'(i0,a)') f,achar(0)
      iret = MessageBox(NULL,msg,NULL,0)
END BLOCK
bret = ShowWindow(hWND, SW_SHOW)
bret = UpdateWindow(hWnd)
call Init

With the result:

fortcom: Fatal: There has been an internal compiler error (C0000005).
compilation aborted for Rings.f90 (code 1)

Even though this seemed unpromising, I tried instead:

! Set up the OpenGL context
!
hDC = GetDC(hWnd)
hRC = fwglCreateContext(hDC)
hret = fwglMakeCurrent(hDC, hRC)
! Test stuff here:
BLOCK
    character(80) anam
    integer(HANDLE) f
    character(80) msg
    integer iret
!    interface
!       function wglGetProcAddress(name) bind(C,name='wglGetProcAddress')
!          use ISO_C_BINDING, only: C_CHAR
!          import
!          implicit none
!          integer(HANDLE) :: wglGetProcAddress
!!DEC$ ATTRIBUTES STDCALL :: wglGetProcAddress
!          character(kind=C_CHAR), intent(in) :: name(*)
!       end function wglGetProcAddress
!    end interface
      anam = 'glGenVertexArrays'C
      f    = fwglGetProcAddress(LOC(anam))
      !f    = wglGetProcAddress(anam)
      write(msg,'(i0,a)') f,achar(0)
      iret = MessageBox(NULL,msg,NULL,0)
END BLOCK
bret = ShowWindow(hWND, SW_SHOW)
bret = UpdateWindow(hWnd)
call Init

And now build.bat ran without error and the resulting Rings.exe said "1808564752" in its MessageBox. So I think the first thing I would try is to modify Rings.f90 the same way and see if it works OK on your computer. If so the point of failure may lie in setting up the OpenGL context (which is really hard to do properly) and not in the wglGetProcAddress call.

 

0 Kudos
Highlighted
Beginner
16 Views

Thanks for posting working

Thanks for posting working code.  I hate to admit it but the error was nothing to do with OpenGL -

 

! CHARACTER :: anam ='glCreateProgram'C

CHARACTER(80):: anam ='glCreateProgram'C

 

I forgot to put a string length for the procedure name, so it was looking for a procedure called "g".

 

Incidentally, the "BLOCK" construct doesn't compile on my IVF (Composer XE 2013) - is that a recently implemented feature?

thanks again!

0 Kudos
Highlighted
16 Views

Yes, BLOCK is new in the 2015

Yes, BLOCK is new in the 2015 (15.0) compiler. It is a Fortran 2008 feature.

I will check out the compiler error.

Retired 12/31/2016
0 Kudos
Highlighted
16 Views

The compiler error RO found

The compiler error RO found in #8 has been fixed for a release later this year.

Retired 12/31/2016
0 Kudos