www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Win32 + OpenGL bindings

reply "Diggory" <diggsey googlemail.com> writes:
I've been trying to write a win32 app using opengl in D, but none 
of the bindings I've found have been sufficient:

- core.sys.windows.windows:
Missing large parts of wingdi.h, including PFD_* constants, 
ChoosePixelFormat(), SwapBuffers(), wgl*() functions.

- win32.windows:
Apparantly out of date and gives linker errors, although it does 
declare all the functions needed.

- derelict.util.wintypes:
Declares a small number of useful windows functions, many of 
which conflict with those declared in "core.sys.windows.windows" 
(such as PIXELFORMATDESCRIPTOR). However, "SetPixelFormat" is not 
declared.

- derelict.opengl.gl:
Has all of opengl plus wgl* functions needed for windows, but has 
more dependencies than an ideal opengl binding would have.

Why isn't there a simple relationship between C/C++ header files 
and D modules, instead of this weird mix where some things are 
duplicated and others not declared at all?

All of the windows specific functions including wgl* are supposed 
to be in "windows.h", and opengl functions in "gl/gl.h"

It's a shame because I really like the ideas behind D - in fact 
the reason I found it is that I'd come up with a whole bunch of 
ideas I wanted in an ideal language and it turned out D already 
implemented them all...
Apr 19 2013
next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Saturday, 20 April 2013 at 03:26:29 UTC, Diggory wrote:
 I've been trying to write a win32 app using opengl in D, but 
 none of the bindings I've found have been sufficient:

 - core.sys.windows.windows:
 Missing large parts of wingdi.h, including PFD_* constants, 
 ChoosePixelFormat(), SwapBuffers(), wgl*() functions.

 - win32.windows:
 Apparantly out of date and gives linker errors, although it 
 does declare all the functions needed.

 - derelict.util.wintypes:
 Declares a small number of useful windows functions, many of 
 which conflict with those declared in 
 "core.sys.windows.windows" (such as PIXELFORMATDESCRIPTOR). 
 However, "SetPixelFormat" is not declared.

 - derelict.opengl.gl:
 Has all of opengl plus wgl* functions needed for windows, but 
 has more dependencies than an ideal opengl binding would have.

 Why isn't there a simple relationship between C/C++ header 
 files and D modules, instead of this weird mix where some 
 things are duplicated and others not declared at all?

 All of the windows specific functions including wgl* are 
 supposed to be in "windows.h", and opengl functions in "gl/gl.h"

 It's a shame because I really like the ideas behind D - in fact 
 the reason I found it is that I'd come up with a whole bunch of 
 ideas I wanted in an ideal language and it turned out D already 
 implemented them all...
Deimos has some OpenGL bindings for up to 3.1 core here https://github.com/D-Programming-Deimos/OpenGL/tree/master/deimos/gl I also have my own that are up to 4.2 core here https://bitbucket.org/Kapps/shardgraphics/src (gl.d, glfuncs.d, gltypes.d, and possibly glfw.d if you need that), which include loading the function pointers, but there may be some licensing issues because they're parsed from the OpenGL man pages. Also there may be some incorrect functions in mine because of parsing errors.
Apr 20 2013
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Saturday, 20 April 2013 at 03:26:29 UTC, Diggory wrote:
 - win32.windows:
 Apparantly out of date and gives linker errors, although it 
 does declare all the functions needed.
Is this the ChoosePixelFormat error from your other thread? If so - you probably need to link your program with gdi32.lib. You can do this by adding this line to your program (won't work with GDC): pragma(lib, "gdi32"); Or, just add gdi32.lib to the compiler's command line. If it's some other error - are you using the .lib / .def files from the same project? There are some additional import libraries files in the repository's "lib" directory.
Apr 20 2013
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-20 05:26, Diggory wrote:

 - derelict.opengl.gl:
 Has all of opengl plus wgl* functions needed for windows, but has more
 dependencies than an ideal opengl binding would have.
Dependencies, like what? -- /Jacob Carlborg
Apr 20 2013
parent reply "Diggory" <diggsey googlemail.com> writes:
On Saturday, 20 April 2013 at 10:09:37 UTC, Jacob Carlborg wrote:
 On 2013-04-20 05:26, Diggory wrote:

 - derelict.opengl.gl:
 Has all of opengl plus wgl* functions needed for windows, but 
 has more
 dependencies than an ideal opengl binding would have.
Dependencies, like what?
Well the opengl module depends on the util module. The util module declares a load of stuff duplicated by the windows module so importing them both without aliasing is impossible. All I want is to import the raw opengl and win32 functions. I've got my program partially working using the old win32.windows module with an opengl module I got from elsewhere which included "opengl32.lib", but doesn't define glViewport... I would like to use the opengl module from deimos if possible - it doesn't need to be particularly up to date - but I don't know how to get/generate the .lib file for it. Are the .lib files used with D just C/C++ .lib files? If so what are the requirements of them - .lib files from the windows SDK don't seem to be compatible? Do I need to generate them instead from the .d files? Also the program I'm compiling is bringing up a console window when it runs, even though I'm setting the subsystem to "Windows" and using "WinMain" exactly as the documentation describes. Finally I seem to have discovered a bug with "final switch": This correctly does nothing when passed "36" (neither WM_SIZE and WM_DESTROY equal 36): switch (message) { case WM_SIZE: glViewport(0, 0, LOWORD(lParam), HIWORD(lParam)); break; case WM_DESTROY: PostQuitMessage(0); break; default: break; } While this runs the "WM_DESTROY" case statement when passed 36. final switch (message) { case WM_SIZE: glViewport(0, 0, LOWORD(lParam), HIWORD(lParam)); break; case WM_DESTROY: PostQuitMessage(0); break; }
Apr 20 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-20 12:43, Diggory wrote:

 Well the opengl module depends on the util module. The util module
 declares a load of stuff duplicated by the windows module so importing
 them both without aliasing is impossible. All I want is to import the
 raw opengl and win32 functions.
Derelict is raw OpenGL + automatically loading the dynamic libraries. I'm looking at the Dreliect3 source code. I can't see that it publicly import any Windows types/functions from the OpenGL files. If file "main" imports file A which imports file B, that doesn't mean that "main" will have access to file B. As far as I can see, you shouldn't have any conflicts. https://github.com/aldacron/Derelict3
 I've got my program partially working using the old win32.windows module
 with an opengl module I got from elsewhere which included
 "opengl32.lib", but doesn't define glViewport...

 I would like to use the opengl module from deimos if possible - it
 doesn't need to be particularly up to date - but I don't know how to
 get/generate the .lib file for it.

 Are the .lib files used with D just C/C++ .lib files? If so what are the
 requirements of them - .lib files from the windows SDK don't seem to be
 compatible? Do I need to generate them instead from the .d files?
Yes, they are just regular C .lib files. But if you're using DMD 32bit they need to be in the OMF format but the Microsoft linker and SDK uses the COFF format.
 Also the program I'm compiling is bringing up a console window when it
 runs, even though I'm setting the subsystem to "Windows" and using
 "WinMain" exactly as the documentation describes.
You need to add the following flag when compiling : -L/SUBSYSTEM:CONSOLE:4.0 -- /Jacob Carlborg
Apr 21 2013
parent reply "Diggory" <diggsey googlemail.com> writes:
OK, thanks I think I've got the hang of the way linking works now 
- I was confused about how some things didn't seem to require 
libs to work, but now I see it's because those things were 
compiled into "druntime.lib" which was compiled into "phobos.lib".

So is this correct, assuming I'm only talking about non-COFF libs:
- D code can link directly to normal C libs
- .libs generated by DMD are a superset of normal C .libs, they 
can contain normal C functions but DMD also has some way of 
representing more complicated D constructs inside the .lib file 
(but not templates).
- druntime.lib is linked into phobos.lib so only phobos.lib needs 
to be linked and the compiler does this automatically (how does 
this work, is just hard-coded in?)

Is there a compiler independent way to tell the linker to 
automatically link in a specific library from within a .d file? 
(preferable this hint should still exist in the .di file 
generated from that .d file, and be transitive so dependencies 
automatically get linked in just by "import"ing the required 
stuff) If not can I suggest this as a feature?

I've switched to using the "head" revision in the repo and 
building from source which was surprisingly easy (thanks whoever 
set that up!) so now I can just add missing functions to 
windows.d as I need and rebuild and no more linker errors!

Am I correct in thinking there is no specific order in the 
contents of windows.d? I've rearranged mine so that functions are 
ordered by module then header file so I can more easily see if a 
function already exists, and if not where to add it. Would these 
changes be of any use?
Apr 21 2013
next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Sunday, 21 April 2013 at 15:20:28 UTC, Diggory wrote:
 OK, thanks I think I've got the hang of the way linking works 
 now - I was confused about how some things didn't seem to 
 require libs to work, but now I see it's because those things 
 were compiled into "druntime.lib" which was compiled into 
 "phobos.lib".
phobos and druntime linked automatically, though i am unaware of where it goes, so can't tell for sure.
 Is there a compiler independent way to tell the linker to 
 automatically link in a specific library from within a .d file? 
 (preferable this hint should still exist in the .di file 
 generated from that .d file, and be transitive so dependencies 
 automatically get linked in just by "import"ing the required 
 stuff) If not can I suggest this as a feature?
there is pragma for this: pragma(lib, "mylib.lib"); read this. http://dlang.org/pragma.html
 Am I correct in thinking there is no specific order in the 
 contents of windows.d? I've rearranged mine so that functions 
 are ordered by module then header file so I can more easily see 
 if a function already exists, and if not where to add it. Would 
 these changes be of any use?
in D order of imports doesn't important. also i would suggest you read all documents in language reference, how-tos, and sections, they are not so big but it will give answer to most begginers questions. also start reading library reference, you will save much time later.
Apr 22 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-04-21 17:20, Diggory wrote:
 OK, thanks I think I've got the hang of the way linking works now - I
 was confused about how some things didn't seem to require libs to work,
 but now I see it's because those things were compiled into
 "druntime.lib" which was compiled into "phobos.lib".

 So is this correct, assuming I'm only talking about non-COFF libs:
 - D code can link directly to normal C libs
Yes.
 - .libs generated by DMD are a superset of normal C .libs, they can
 contain normal C functions but DMD also has some way of representing
 more complicated D constructs inside the .lib file (but not templates).
Yes and no. DMD produces the same .lib files as any C compiler does. The differences is that D functions uses mangled names this is to support overloaded function (two or more functions with the same name but different argument types), methods and template functions.
 - druntime.lib is linked into phobos.lib so only phobos.lib needs to be
 linked and the compiler does this automatically (how does this work, is
 just hard-coded in?)
Yes, druntime is included in Phobos. The compiler hard codes this (at least on Posix), add the -v flag when compiling and look at the end of the output to see the linker command it uses. There's also the dm.ini (dmd.conf on Posix) that contains a couple of default flags. You'll see that it adds the search path where Phobos is located.
 Is there a compiler independent way to tell the linker to automatically
 link in a specific library from within a .d file? (preferable this hint
 should still exist in the .di file generated from that .d file, and be
 transitive so dependencies automatically get linked in just by
 "import"ing the required stuff) If not can I suggest this as a feature?
Yes, pragma(lib, ...); but it won't work for .di files. http://d.puremagic.com/issues/show_bug.cgi?id=2776
 I've switched to using the "head" revision in the repo and building from
 source which was surprisingly easy (thanks whoever set that up!) so now
 I can just add missing functions to windows.d as I need and rebuild and
 no more linker errors!

 Am I correct in thinking there is no specific order in the contents of
 windows.d? I've rearranged mine so that functions are ordered by module
 then header file so I can more easily see if a function already exists,
 and if not where to add it. Would these changes be of any use?
In general declarations are order independent. When you start with nested functions and static-ifs it become order dependent. -- /Jacob Carlborg
Apr 22 2013
parent reply "Diggory" <diggsey googlemail.com> writes:
 you are doing it wrong. first you will need mingw32-make from 
 mingw default setup, second fix win32 bindings makefile around 
 line 25 so it will looks like this(supported file don't have 
 uuid.di outdated interface file included)
Yeah I realise what I was doing wrong now. It only coincidentally worked because the win32 libraries were linked in by default, although of course the functions implemented in D gave errors. I've switched to just adding missing functions as I need them to "windows.d" and recompiling the druntime.
 Yes, pragma(lib, ...); but it won't work for .di files.

 http://d.puremagic.com/issues/show_bug.cgi?id=2776
OK, I had seen that but earlier in this thread evilrat said it didn't work in GDC so I assumed it was a DMD only feature.
 also i would suggest you read all documents in language 
 reference, how-tos, and sections, they are not so big but it 
 will give answer to most begginers questions. also start 
 reading library reference, you will save much time later.
I have read all the language reference pages, but there is very little on linking and related things. Specifically, there could be a more obvious link to "deimos" so that those bindings can be found as that seems to be the most official place for such things as well as more information on how to build the .d files. (For example, the opengl project gives just a single .d file with no information about how to use it) As it turns out, the opengl project needs a .lib file to import opengl32.dll which can only be generated by getting "coffimplib.exe" (wow finding that was hard!) and running it on the platform sdk import library for opengl. Since wgl*** functions are declared in "windows.h" but are defined in "opengl32.dll" this is technically part of the platform SDK. It should really not be this hard to call a function supposedly built into the operating system. An up to date opengl32 import library should exist in "dmd2/windows/lib/". I realise D is still fairly young so it's unreasonable to expect everything to already exist, but at least enough information should be given to be able to correctly add things that don't.
Apr 22 2013
next sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Monday, 22 April 2013 at 12:54:32 UTC, Diggory wrote:
 ...

 I realise D is still fairly young so it's unreasonable to 
 expect everything to already exist, but at least enough 
 information should be given to be able to correctly add things 
 that don't.
it's not that young, but i agree the whole site is quite outdated, under-maintained and uninformative on some concepts, therefore making lot of people who accidentally found D to quickly abandon learning it, also turning some of them into very haters :( the real problem is that you need to really want to use D, not just "i wish there be cool language with wow features that super easy to learn and use..." oops, some offtopic. btw i really recommend w32api bindings and derelict3(since it's really crossplatform and easy to build and use) for opengl. it also helps to avoid some problems with manual pointer loading when you messed up function signature/name resulting in not loading gl funcs which in result leads to happy debugging time.
Apr 22 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-04-22 14:54, Diggory wrote:

 OK, I had seen that but earlier in this thread evilrat said it didn't
 work in GDC so I assumed it was a DMD only feature.
That's true as well. GDC won't/can't implement it because of how the architecture looks like in GCC. The compiler cannot access the driver. As I understand it the driver chooses the linker flags. -- /Jacob Carlborg
Apr 23 2013
prev sibling parent "evilrat" <evilrat666 gmail.com> writes:
On Saturday, 20 April 2013 at 03:26:29 UTC, Diggory wrote:
 - win32.windows:
 Apparantly out of date and gives linker errors, although it 
 does declare all the functions needed.
you are doing it wrong. first you will need mingw32-make from mingw default setup, second fix win32 bindings makefile around line 25 so it will looks like this(supported file don't have uuid.di outdated interface file included): win32.lib : $(SOURCES) $(DC) $^ -lib -of$ uuid.di $(DFLAGS) use mingw make to compile win32 bindings(they are not bindings actually but a D language translation), you will get dmd ready win32.lib file. setup import search path to win32 bindings path, link with win32.lib, AND(!) add any version identifier from w32api.d(by default makefile assumes you will do "WindowsVista" version, it's mostly safe to still use on XP but i would suggest recompile for production build. now you will get all you missing!!!!
Apr 22 2013