template.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. package main
  2. import (
  3. "bytes"
  4. "go/format"
  5. "os"
  6. "text/template"
  7. )
  8. type GLHeader struct {
  9. Defines []GLDefine
  10. Funcs []GLFunc
  11. }
  12. type GLDefine struct {
  13. Name string
  14. Value string
  15. }
  16. type GLFunc struct {
  17. Ptype string // type of function pointer (ex: PFNCULLFACEPROC)
  18. Spacer string // spacer string for formatting
  19. Pname string // pointer name (ex: pglCullFace)
  20. Rtype string // return type (ex: void)
  21. Fname string // name of function (ex: glCullFace)
  22. FnameGo string // name of function without the "gl" prefix
  23. CParams string // list of comma C parameter types and names ex:"GLenum mode, GLint x"
  24. Args string // list of comma separated argument names ex:"x, y, z"
  25. GoParams string // list of comma separated Go parameters ex:"x float32, y float32"
  26. Params []GLParam // array of function parameters
  27. }
  28. type GLParam struct {
  29. Qualif string // optional parameter qualifier (ex: const)
  30. CType string // parameter C type
  31. Arg string // parameter name without pointer operator
  32. Name string // parameter name with possible pointer operator
  33. }
  34. // genFile generates file from the specified template
  35. func genFile(templText string, td *GLHeader, fout string, gosrc bool) error {
  36. // Parses the template
  37. tmpl := template.New("tmpl")
  38. tmpl, err := tmpl.Parse(templText)
  39. if err != nil {
  40. return err
  41. }
  42. // Expands template to buffer
  43. var buf bytes.Buffer
  44. err = tmpl.Execute(&buf, &td)
  45. if err != nil {
  46. return err
  47. }
  48. text := buf.Bytes()
  49. // Creates output file
  50. f, err := os.Create(fout)
  51. if err != nil {
  52. return nil
  53. }
  54. // If requested, formats generated text as Go source
  55. if gosrc {
  56. src, err := format.Source(text)
  57. if err != nil {
  58. return err
  59. }
  60. text = src
  61. }
  62. // Writes source to output file
  63. _, err = f.Write(text)
  64. if err != nil {
  65. return err
  66. }
  67. return f.Close()
  68. }
  69. //
  70. // Template for glapi C file
  71. //
  72. const templGLAPIC = `
  73. // This file was generated automatically by "glapi2go" and contains functions to
  74. // open the platform's OpenGL dll/shared library and to load all OpenGL function
  75. // pointers for an specified OpenGL version described by the header file "glcorearb.h",
  76. // from "https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h".
  77. //
  78. // As Go cgo cannot call directly to C pointers it also creates C function wrappers
  79. // for all loaded OpenGL pointers.
  80. // The code was heavily based on "https://github.com/skaslev/gl3w"
  81. #include <stdlib.h>
  82. #include <stdio.h>
  83. #include "glapi.h"
  84. //
  85. // OpenGL function loader for Windows
  86. //
  87. #ifdef _WIN32
  88. #define WIN32_LEAN_AND_MEAN 1
  89. #include <windows.h>
  90. #undef near
  91. #undef far
  92. static HMODULE libgl;
  93. // open_libgl opens the OpenGL dll for Windows
  94. static int open_libgl(void) {
  95. libgl = LoadLibraryA("opengl32.dll");
  96. if (libgl == NULL) {
  97. return -1;
  98. }
  99. return 0;
  100. }
  101. // close_libgl closes the OpenGL dll object for Windows
  102. static void close_libgl(void) {
  103. FreeLibrary(libgl);
  104. }
  105. // get_proc gets the pointer for an OpenGL function for Windows
  106. static void* get_proc(const char *proc) {
  107. void* res;
  108. res = (void*)wglGetProcAddress(proc);
  109. if (!res) {
  110. res = (void*)GetProcAddress(libgl, proc);
  111. }
  112. return res;
  113. }
  114. //
  115. // OpenGL function loader for Mac OS
  116. //
  117. #elif defined(__APPLE__) || defined(__APPLE_CC__)
  118. #include <Carbon/Carbon.h>
  119. CFBundleRef bundle;
  120. CFURLRef bundleURL;
  121. // open_libgl opens the OpenGL shared object for OSX
  122. static void open_libgl(void) {
  123. bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
  124. CFSTR("/System/Library/Frameworks/OpenGL.framework"),
  125. kCFURLPOSIXPathStyle, true);
  126. bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);
  127. assert(bundle != NULL);
  128. }
  129. // close_libgl closes the OpenGL shared object object for OSX
  130. static void close_libgl(void) {
  131. CFRelease(bundle);
  132. CFRelease(bundleURL);
  133. }
  134. // get_proc gets the pointer for an OpenGL function for OSX
  135. static void* get_proc(const char *proc) {
  136. void* res;
  137. CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc,
  138. kCFStringEncodingASCII);
  139. *(void **)(&res) = CFBundleGetFunctionPointerForName(bundle, procname);
  140. CFRelease(procname);
  141. return res;
  142. }
  143. //
  144. // OpenGL function loader for Linux, Unix*
  145. //
  146. #else
  147. #include <dlfcn.h>
  148. #include <GL/glx.h>
  149. static void *libgl;
  150. static PFNGLXGETPROCADDRESSPROC glx_get_proc_address;
  151. // open_libgl opens the OpenGL shared object for Linux/Freebsd
  152. static int open_libgl(void) {
  153. libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
  154. if (libgl == NULL) {
  155. return -1;
  156. }
  157. *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
  158. if (glx_get_proc_address == NULL) {
  159. return -1;
  160. }
  161. return 0;
  162. }
  163. // close_libgl closes the OpenGL shared object for Linux/Freebsd
  164. static void close_libgl(void) {
  165. dlclose(libgl);
  166. }
  167. // get_proc gets the pointer for an OpenGL function for Linux/Freebsd
  168. static void* get_proc(const char *proc) {
  169. void* res;
  170. res = glx_get_proc_address((const GLubyte *)proc);
  171. if (!res) {
  172. *(void **)(&res) = dlsym(libgl, proc);
  173. }
  174. return res;
  175. }
  176. #endif
  177. // Internal global flag to check error from OpenGL functions
  178. static int checkError = 1;
  179. // Declaration of internal function for loading OpenGL function pointers
  180. static void load_procs();
  181. //
  182. // glapiLoad() tries to load functions addresses from the OpenGL library
  183. //
  184. int glapiLoad(void) {
  185. int res = open_libgl();
  186. if (res != 0) {
  187. return res;
  188. }
  189. load_procs();
  190. close_libgl();
  191. return 0;
  192. }
  193. //
  194. // glapiCheckError sets the state of the internal flag which determines
  195. // if error checking must be done for OpenGL calls
  196. //
  197. void glapiCheckError(int check) {
  198. checkError = check;
  199. }
  200. // Internal function to abort process when error
  201. static void panic(GLenum err, const char* fname) {
  202. printf("\nGLAPI Error: %d calling: %s\n", err, fname);
  203. exit(1);
  204. }
  205. //
  206. // Definitions of function pointers variables
  207. //
  208. {{- range .Funcs}}
  209. static {{.Ptype}} {{.Spacer}} {{.Pname}};
  210. {{- end}}
  211. //
  212. // load_procs loads all gl functions addresses into the pointers
  213. //
  214. static void load_procs() {
  215. {{range .Funcs}}
  216. {{- .Pname}} = ({{.Ptype}})get_proc("{{.Fname}}");
  217. {{end}}
  218. }
  219. //
  220. // Definitions of C wrapper functions for all OpenGL loaded pointers
  221. // which call the pointer and optionally cals glGetError() to check
  222. // for OpenGL errors.
  223. //
  224. {{range .Funcs}}
  225. {{.Rtype}} {{.Fname}} ({{.CParams}}) {
  226. {{if ne .Rtype "void"}}
  227. {{- .Rtype}} res = {{.Pname}}({{.Args}});
  228. {{else}}
  229. {{- .Pname}}({{.Args}});
  230. {{end -}}
  231. if (checkError) {
  232. GLenum err = pglGetError();
  233. if (err != GL_NO_ERROR) {
  234. panic(err, "{{.Fname}}");
  235. }
  236. }
  237. {{if ne .Rtype "void" -}}
  238. return res;
  239. {{- end}}
  240. }
  241. {{end}}
  242. `
  243. //
  244. // Template for glapi.h file
  245. //
  246. const templGLAPIH = `
  247. // This file was generated automatically by "glapi2go" and contains declarations
  248. // of public functions from "glapli.c".
  249. #ifndef _glapi_h_
  250. #define _glapi_h_
  251. #include "glcorearb.h"
  252. // Loads the OpenGL function pointers
  253. int glapiLoad(void);
  254. // Set the internal flag to enable/disable OpenGL error checking
  255. void glapiCheckError(int check);
  256. #endif
  257. `
  258. //
  259. // Template for glparam.h file
  260. //
  261. const templGLPARAMH = `
  262. #ifndef _glparam_h_
  263. #define _glparam_h_
  264. #include "glcorearb.h"
  265. //
  266. // Definition of structures for passing parameters to queued OpenGL functions
  267. //
  268. {{range .Funcs}}
  269. typedef struct {
  270. {{- range .Params}}
  271. {{.CType}} {{.Name -}};
  272. {{- end}}
  273. } Param{{.Fname}};
  274. {{end}}
  275. #endif
  276. `
  277. //
  278. // Template for consts.go file
  279. //
  280. const templCONSTS = `
  281. // This file was generated automatically by "glapi2go" and contains all
  282. // OpenGL constants specified by "#define GL_*" directives contained in
  283. // "glcorearb.h" for an specific OpenGL version converted to Go constants.
  284. package gls
  285. const (
  286. {{range .Defines}}
  287. {{.Name}} = {{.Value -}}
  288. {{end}}
  289. )
  290. `