template.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. static HMODULE libgl;
  91. // open_libgl opens the OpenGL dll for Windows
  92. static void open_libgl(void) {
  93. libgl = LoadLibraryA("opengl32.dll");
  94. }
  95. // close_libgl closes the OpenGL dll object for Windows
  96. static void close_libgl(void) {
  97. FreeLibrary(libgl);
  98. }
  99. // get_proc gets the pointer for an OpenGL function for Windows
  100. static void* get_proc(const char *proc) {
  101. void* res;
  102. res = (void*)wglGetProcAddress(proc);
  103. if (!res) {
  104. res = (void*)GetProcAddress(libgl, proc);
  105. }
  106. return res;
  107. }
  108. //
  109. // OpenGL function loader for Mac OS
  110. //
  111. #elif defined(__APPLE__) || defined(__APPLE_CC__)
  112. #include <Carbon/Carbon.h>
  113. CFBundleRef bundle;
  114. CFURLRef bundleURL;
  115. // open_libgl opens the OpenGL shared object for OSX
  116. static void open_libgl(void) {
  117. bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
  118. CFSTR("/System/Library/Frameworks/OpenGL.framework"),
  119. kCFURLPOSIXPathStyle, true);
  120. bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);
  121. assert(bundle != NULL);
  122. }
  123. // close_libgl closes the OpenGL shared object object for OSX
  124. static void close_libgl(void) {
  125. CFRelease(bundle);
  126. CFRelease(bundleURL);
  127. }
  128. // get_proc gets the pointer for an OpenGL function for OSX
  129. static void* get_proc(const char *proc) {
  130. void* res;
  131. CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc,
  132. kCFStringEncodingASCII);
  133. *(void **)(&res) = CFBundleGetFunctionPointerForName(bundle, procname);
  134. CFRelease(procname);
  135. return res;
  136. }
  137. //
  138. // OpenGL function loader for Linux, Unix*
  139. //
  140. #else
  141. #include <dlfcn.h>
  142. #include <GL/glx.h>
  143. static void *libgl;
  144. static PFNGLXGETPROCADDRESSPROC glx_get_proc_address;
  145. // open_libgl opens the OpenGL shared object for Linux/Freebsd
  146. static int open_libgl(void) {
  147. libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
  148. if (libgl == NULL) {
  149. return -1;
  150. }
  151. *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
  152. if (glx_get_proc_address == NULL) {
  153. return -1;
  154. }
  155. return 0;
  156. }
  157. // close_libgl closes the OpenGL shared object for Linux/Freebsd
  158. static void close_libgl(void) {
  159. dlclose(libgl);
  160. }
  161. // get_proc gets the pointer for an OpenGL function for Linux/Freebsd
  162. static void* get_proc(const char *proc) {
  163. void* res;
  164. res = glx_get_proc_address((const GLubyte *)proc);
  165. if (!res) {
  166. *(void **)(&res) = dlsym(libgl, proc);
  167. }
  168. return res;
  169. }
  170. #endif
  171. // Internal global flag to check error from OpenGL functions
  172. static int checkError = 1;
  173. // Declaration of internal function for loading OpenGL function pointers
  174. static void load_procs();
  175. //
  176. // glapiLoad() tries to load functions addresses from the OpenGL library
  177. //
  178. int glapiLoad(void) {
  179. int res = open_libgl();
  180. if (res != 0) {
  181. return res;
  182. }
  183. load_procs();
  184. close_libgl();
  185. return 0;
  186. }
  187. //
  188. // glapiCheckError sets the state of the internal flag which determines
  189. // if error checking must be done for OpenGL calls
  190. //
  191. void glapiCheckError(int check) {
  192. checkError = check;
  193. }
  194. // Internal function to abort process when error
  195. static void panic(GLenum err, const char* fname) {
  196. printf("\nGLAPI Error: %d calling: %s\n", err, fname);
  197. exit(1);
  198. }
  199. //
  200. // Definitions of function pointers variables
  201. //
  202. {{- range .Funcs}}
  203. static {{.Ptype}} {{.Spacer}} {{.Pname}};
  204. {{- end}}
  205. //
  206. // load_procs loads all gl functions addresses into the pointers
  207. //
  208. static void load_procs() {
  209. {{range .Funcs}}
  210. {{- .Pname}} = ({{.Ptype}})get_proc("{{.Fname}}");
  211. {{end}}
  212. }
  213. //
  214. // Definitions of C wrapper functions for all OpenGL loaded pointers
  215. // which call the pointer and optionally cals glGetError() to check
  216. // for OpenGL errors.
  217. //
  218. {{range .Funcs}}
  219. {{.Rtype}} {{.Fname}} ({{.CParams}}) {
  220. {{if ne .Rtype "void"}}
  221. {{- .Rtype}} res = {{.Pname}}({{.Args}});
  222. {{else}}
  223. {{- .Pname}}({{.Args}});
  224. {{end -}}
  225. if (checkError) {
  226. GLenum err = pglGetError();
  227. if (err != GL_NO_ERROR) {
  228. panic(err, "{{.Fname}}");
  229. }
  230. }
  231. {{if ne .Rtype "void" -}}
  232. return res;
  233. {{- end}}
  234. }
  235. {{end}}
  236. `
  237. //
  238. // Template for glapi.h file
  239. //
  240. const templGLAPIH = `
  241. // This file was generated automatically by "glapi2go" and contains declarations
  242. // of public functions from "glapli.c".
  243. #ifndef _glapi_h_
  244. #define _glapi_h_
  245. #include "glcorearb.h"
  246. // Loads the OpenGL function pointers
  247. int glapiLoad(void);
  248. // Set the internal flag to enable/disable OpenGL error checking
  249. void glapiCheckError(int check);
  250. #endif
  251. `
  252. //
  253. // Template for glparam.h file
  254. //
  255. const templGLPARAMH = `
  256. #ifndef _glparam_h_
  257. #define _glparam_h_
  258. #include "glcorearb.h"
  259. //
  260. // Definition of structures for passing parameters to queued OpenGL functions
  261. //
  262. {{range .Funcs}}
  263. typedef struct {
  264. {{- range .Params}}
  265. {{.CType}} {{.Name -}};
  266. {{- end}}
  267. } Param{{.Fname}};
  268. {{end}}
  269. #endif
  270. `
  271. //
  272. // Template for consts.go file
  273. //
  274. const templCONSTS = `
  275. // This file was generated automatically by "glapi2go" and contains all
  276. // OpenGL constants specified by "#define GL_*" directives contained in
  277. // "glcorearb.h" for an specific OpenGL version converted to Go constants.
  278. package gls
  279. const (
  280. {{range .Defines}}
  281. {{.Name}} = {{.Value -}}
  282. {{end}}
  283. )
  284. `