- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
- Am I calling fwglGetProcAddress correctly (should I use C_LOC instead)?
- 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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe there is a typo: glGenVertexArrays (Mind the "s"). Does this help?
Robert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, there's your answer.... I don't think it's sufficient for just the hardware to support the function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, BLOCK is new in the 2015 (15.0) compiler. It is a Fortran 2008 feature.
I will check out the compiler error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The compiler error RO found in #8 has been fixed for a release later this year.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page