template.go 8.3 KB

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