template.go 7.0 KB

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