gl.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build darwin || linux || openbsd || freebsd || windows
  5. // +build darwin linux openbsd freebsd windows
  6. package gl
  7. // TODO(crawshaw): should functions on specific types become methods? E.g.
  8. // func (t Texture) Bind(target Enum)
  9. // this seems natural in Go, but moves us slightly
  10. // further away from the underlying OpenGL spec.
  11. import (
  12. "math"
  13. "unsafe"
  14. )
  15. func (ctx *context) ActiveTexture(texture Enum) {
  16. ctx.enqueue(call{
  17. args: fnargs{
  18. fn: glfnActiveTexture,
  19. a0: texture.c(),
  20. },
  21. })
  22. }
  23. func (ctx *context) AttachShader(p Program, s Shader) {
  24. ctx.enqueue(call{
  25. args: fnargs{
  26. fn: glfnAttachShader,
  27. a0: p.c(),
  28. a1: s.c(),
  29. },
  30. })
  31. }
  32. func (ctx *context) BindBuffer(target Enum, b Buffer) {
  33. ctx.enqueue(call{
  34. args: fnargs{
  35. fn: glfnBindBuffer,
  36. a0: target.c(),
  37. a1: b.c(),
  38. },
  39. })
  40. }
  41. func (ctx *context) BindTexture(target Enum, t Texture) {
  42. ctx.enqueue(call{
  43. args: fnargs{
  44. fn: glfnBindTexture,
  45. a0: target.c(),
  46. a1: t.c(),
  47. },
  48. })
  49. }
  50. func (ctx *context) BindVertexArray(va VertexArray) {
  51. ctx.enqueue(call{
  52. args: fnargs{
  53. fn: glfnBindVertexArray,
  54. a0: va.c(),
  55. },
  56. })
  57. }
  58. func (ctx *context) BlendColor(red, green, blue, alpha float32) {
  59. ctx.enqueue(call{
  60. args: fnargs{
  61. fn: glfnBlendColor,
  62. a0: uintptr(math.Float32bits(red)),
  63. a1: uintptr(math.Float32bits(green)),
  64. a2: uintptr(math.Float32bits(blue)),
  65. a3: uintptr(math.Float32bits(alpha)),
  66. },
  67. })
  68. }
  69. func (ctx *context) BlendFunc(sfactor, dfactor Enum) {
  70. ctx.enqueue(call{
  71. args: fnargs{
  72. fn: glfnBlendFunc,
  73. a0: sfactor.c(),
  74. a1: dfactor.c(),
  75. },
  76. })
  77. }
  78. func (ctx *context) BufferData(target Enum, src []byte, usage Enum) {
  79. parg := unsafe.Pointer(nil)
  80. if len(src) > 0 {
  81. parg = unsafe.Pointer(&src[0])
  82. }
  83. ctx.enqueue(call{
  84. args: fnargs{
  85. fn: glfnBufferData,
  86. a0: target.c(),
  87. a1: uintptr(len(src)),
  88. a2: usage.c(),
  89. },
  90. parg: parg,
  91. blocking: true,
  92. })
  93. }
  94. func (ctx *context) Clear(mask Enum) {
  95. ctx.enqueue(call{
  96. args: fnargs{
  97. fn: glfnClear,
  98. a0: uintptr(mask),
  99. },
  100. })
  101. }
  102. func (ctx *context) ClearColor(red, green, blue, alpha float32) {
  103. ctx.enqueue(call{
  104. args: fnargs{
  105. fn: glfnClearColor,
  106. a0: uintptr(math.Float32bits(red)),
  107. a1: uintptr(math.Float32bits(green)),
  108. a2: uintptr(math.Float32bits(blue)),
  109. a3: uintptr(math.Float32bits(alpha)),
  110. },
  111. })
  112. }
  113. func (ctx *context) CompileShader(s Shader) {
  114. ctx.enqueue(call{
  115. args: fnargs{
  116. fn: glfnCompileShader,
  117. a0: s.c(),
  118. },
  119. })
  120. }
  121. func (ctx *context) CreateBuffer() Buffer {
  122. return Buffer{Value: uint32(ctx.enqueue(call{
  123. args: fnargs{
  124. fn: glfnGenBuffer,
  125. },
  126. blocking: true,
  127. }))}
  128. }
  129. func (ctx *context) CreateProgram() Program {
  130. return Program{
  131. Init: true,
  132. Value: uint32(ctx.enqueue(call{
  133. args: fnargs{
  134. fn: glfnCreateProgram,
  135. },
  136. blocking: true,
  137. },
  138. ))}
  139. }
  140. func (ctx *context) CreateShader(ty Enum) Shader {
  141. return Shader{Value: uint32(ctx.enqueue(call{
  142. args: fnargs{
  143. fn: glfnCreateShader,
  144. a0: uintptr(ty),
  145. },
  146. blocking: true,
  147. }))}
  148. }
  149. func (ctx *context) CreateTexture() Texture {
  150. return Texture{Value: uint32(ctx.enqueue(call{
  151. args: fnargs{
  152. fn: glfnGenTexture,
  153. },
  154. blocking: true,
  155. }))}
  156. }
  157. func (ctx *context) CreateVertexArray() VertexArray {
  158. return VertexArray{Value: uint32(ctx.enqueue(call{
  159. args: fnargs{
  160. fn: glfnGenVertexArray,
  161. },
  162. blocking: true,
  163. }))}
  164. }
  165. func (ctx *context) DeleteBuffer(v Buffer) {
  166. ctx.enqueue(call{
  167. args: fnargs{
  168. fn: glfnDeleteBuffer,
  169. a0: v.c(),
  170. },
  171. })
  172. }
  173. func (ctx *context) DeleteTexture(v Texture) {
  174. ctx.enqueue(call{
  175. args: fnargs{
  176. fn: glfnDeleteTexture,
  177. a0: v.c(),
  178. },
  179. })
  180. }
  181. func (ctx *context) Disable(cap Enum) {
  182. ctx.enqueue(call{
  183. args: fnargs{
  184. fn: glfnDisable,
  185. a0: cap.c(),
  186. },
  187. })
  188. }
  189. func (ctx *context) DrawArrays(mode Enum, first, count int) {
  190. ctx.enqueue(call{
  191. args: fnargs{
  192. fn: glfnDrawArrays,
  193. a0: mode.c(),
  194. a1: uintptr(first),
  195. a2: uintptr(count),
  196. },
  197. })
  198. }
  199. func (ctx *context) Enable(cap Enum) {
  200. ctx.enqueue(call{
  201. args: fnargs{
  202. fn: glfnEnable,
  203. a0: cap.c(),
  204. },
  205. })
  206. }
  207. func (ctx *context) EnableVertexAttribArray(a Attrib) {
  208. ctx.enqueue(call{
  209. args: fnargs{
  210. fn: glfnEnableVertexAttribArray,
  211. a0: a.c(),
  212. },
  213. })
  214. }
  215. func (ctx *context) Flush() {
  216. ctx.enqueue(call{
  217. args: fnargs{
  218. fn: glfnFlush,
  219. },
  220. blocking: true,
  221. })
  222. }
  223. func (ctx *context) GetAttribLocation(p Program, name string) Attrib {
  224. s, free := ctx.cString(name)
  225. defer free()
  226. return Attrib{Value: uint(ctx.enqueue(call{
  227. args: fnargs{
  228. fn: glfnGetAttribLocation,
  229. a0: p.c(),
  230. a1: s,
  231. },
  232. blocking: true,
  233. }))}
  234. }
  235. func (ctx *context) GetError() Enum {
  236. return Enum(ctx.enqueue(call{
  237. args: fnargs{
  238. fn: glfnGetError,
  239. },
  240. blocking: true,
  241. }))
  242. }
  243. func (ctx *context) GetProgrami(p Program, pname Enum) int {
  244. return int(ctx.enqueue(call{
  245. args: fnargs{
  246. fn: glfnGetProgramiv,
  247. a0: p.c(),
  248. a1: pname.c(),
  249. },
  250. blocking: true,
  251. }))
  252. }
  253. func (ctx *context) GetProgramInfoLog(p Program) string {
  254. infoLen := ctx.GetProgrami(p, InfoLogLength)
  255. if infoLen == 0 {
  256. return ""
  257. }
  258. buf := make([]byte, infoLen)
  259. ctx.enqueue(call{
  260. args: fnargs{
  261. fn: glfnGetProgramInfoLog,
  262. a0: p.c(),
  263. a1: uintptr(infoLen),
  264. },
  265. parg: unsafe.Pointer(&buf[0]),
  266. blocking: true,
  267. })
  268. return goString(buf)
  269. }
  270. func (ctx *context) GetShaderi(s Shader, pname Enum) int {
  271. return int(ctx.enqueue(call{
  272. args: fnargs{
  273. fn: glfnGetShaderiv,
  274. a0: s.c(),
  275. a1: pname.c(),
  276. },
  277. blocking: true,
  278. }))
  279. }
  280. func (ctx *context) GetShaderInfoLog(s Shader) string {
  281. infoLen := ctx.GetShaderi(s, InfoLogLength)
  282. if infoLen == 0 {
  283. return ""
  284. }
  285. buf := make([]byte, infoLen)
  286. ctx.enqueue(call{
  287. args: fnargs{
  288. fn: glfnGetShaderInfoLog,
  289. a0: s.c(),
  290. a1: uintptr(infoLen),
  291. },
  292. parg: unsafe.Pointer(&buf[0]),
  293. blocking: true,
  294. })
  295. return goString(buf)
  296. }
  297. func (ctx *context) GetShaderSource(s Shader) string {
  298. sourceLen := ctx.GetShaderi(s, ShaderSourceLength)
  299. if sourceLen == 0 {
  300. return ""
  301. }
  302. buf := make([]byte, sourceLen)
  303. ctx.enqueue(call{
  304. args: fnargs{
  305. fn: glfnGetShaderSource,
  306. a0: s.c(),
  307. a1: uintptr(sourceLen),
  308. },
  309. parg: unsafe.Pointer(&buf[0]),
  310. blocking: true,
  311. })
  312. return goString(buf)
  313. }
  314. func (ctx *context) GetTexParameteriv(dst []int32, target, pname Enum) {
  315. ctx.enqueue(call{
  316. args: fnargs{
  317. fn: glfnGetTexParameteriv,
  318. a0: target.c(),
  319. a1: pname.c(),
  320. },
  321. blocking: true,
  322. })
  323. }
  324. func (ctx *context) GetUniformLocation(p Program, name string) Uniform {
  325. s, free := ctx.cString(name)
  326. defer free()
  327. return Uniform{Value: int32(ctx.enqueue(call{
  328. args: fnargs{
  329. fn: glfnGetUniformLocation,
  330. a0: p.c(),
  331. a1: s,
  332. },
  333. blocking: true,
  334. }))}
  335. }
  336. func (ctx *context) LinkProgram(p Program) {
  337. ctx.enqueue(call{
  338. args: fnargs{
  339. fn: glfnLinkProgram,
  340. a0: p.c(),
  341. },
  342. })
  343. }
  344. func (ctx *context) PixelStorei(pname Enum, param int32) {
  345. ctx.enqueue(call{
  346. args: fnargs{
  347. fn: glfnPixelStorei,
  348. a0: pname.c(),
  349. a1: uintptr(param),
  350. },
  351. })
  352. }
  353. func (ctx *context) ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) {
  354. ctx.enqueue(call{
  355. args: fnargs{
  356. fn: glfnReadPixels,
  357. // TODO(crawshaw): support PIXEL_PACK_BUFFER in GLES3, uses offset.
  358. a0: uintptr(x),
  359. a1: uintptr(y),
  360. a2: uintptr(width),
  361. a3: uintptr(height),
  362. a4: format.c(),
  363. a5: ty.c(),
  364. },
  365. parg: unsafe.Pointer(&dst[0]),
  366. blocking: true,
  367. })
  368. }
  369. func (ctx *context) Scissor(x, y, width, height int32) {
  370. ctx.enqueue(call{
  371. args: fnargs{
  372. fn: glfnScissor,
  373. a0: uintptr(x),
  374. a1: uintptr(y),
  375. a2: uintptr(width),
  376. a3: uintptr(height),
  377. },
  378. })
  379. }
  380. func (ctx *context) ShaderSource(s Shader, src string) {
  381. strp, free := ctx.cStringPtr(src)
  382. defer free()
  383. ctx.enqueue(call{
  384. args: fnargs{
  385. fn: glfnShaderSource,
  386. a0: s.c(),
  387. a1: 1,
  388. a2: strp,
  389. },
  390. blocking: true,
  391. })
  392. }
  393. func (ctx *context) TexImage2D(target Enum, level int, internalFormat int, width, height int, format Enum, ty Enum, data []byte) {
  394. // It is common to pass TexImage2D a nil data, indicating that a
  395. // bound GL buffer is being used as the source. In that case, it
  396. // is not necessary to block.
  397. parg := unsafe.Pointer(nil)
  398. if len(data) > 0 {
  399. parg = unsafe.Pointer(&data[0])
  400. }
  401. ctx.enqueue(call{
  402. args: fnargs{
  403. fn: glfnTexImage2D,
  404. // TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
  405. a0: target.c(),
  406. a1: uintptr(level),
  407. a2: uintptr(internalFormat),
  408. a3: uintptr(width),
  409. a4: uintptr(height),
  410. a5: format.c(),
  411. a6: ty.c(),
  412. },
  413. parg: parg,
  414. blocking: parg != nil,
  415. })
  416. }
  417. func (ctx *context) TexParameteri(target, pname Enum, param int) {
  418. ctx.enqueue(call{
  419. args: fnargs{
  420. fn: glfnTexParameteri,
  421. a0: target.c(),
  422. a1: pname.c(),
  423. a2: uintptr(param),
  424. },
  425. })
  426. }
  427. func (ctx *context) Uniform1f(dst Uniform, v float32) {
  428. ctx.enqueue(call{
  429. args: fnargs{
  430. fn: glfnUniform1f,
  431. a0: dst.c(),
  432. a1: uintptr(math.Float32bits(v)),
  433. },
  434. })
  435. }
  436. func (ctx *context) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
  437. ctx.enqueue(call{
  438. args: fnargs{
  439. fn: glfnUniform4f,
  440. a0: dst.c(),
  441. a1: uintptr(math.Float32bits(v0)),
  442. a2: uintptr(math.Float32bits(v1)),
  443. a3: uintptr(math.Float32bits(v2)),
  444. a4: uintptr(math.Float32bits(v3)),
  445. },
  446. })
  447. }
  448. func (ctx *context) Uniform4fv(dst Uniform, src []float32) {
  449. ctx.enqueue(call{
  450. args: fnargs{
  451. fn: glfnUniform4fv,
  452. a0: dst.c(),
  453. a1: uintptr(len(src) / 4),
  454. },
  455. parg: unsafe.Pointer(&src[0]),
  456. blocking: true,
  457. })
  458. }
  459. func (ctx *context) UseProgram(p Program) {
  460. ctx.enqueue(call{
  461. args: fnargs{
  462. fn: glfnUseProgram,
  463. a0: p.c(),
  464. },
  465. })
  466. }
  467. func (ctx *context) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
  468. ctx.enqueue(call{
  469. args: fnargs{
  470. fn: glfnVertexAttribPointer,
  471. a0: dst.c(),
  472. a1: uintptr(size),
  473. a2: ty.c(),
  474. a3: glBoolean(normalized),
  475. a4: uintptr(stride),
  476. a5: uintptr(offset),
  477. },
  478. })
  479. }
  480. func (ctx *context) Viewport(x, y, width, height int) {
  481. ctx.enqueue(call{
  482. args: fnargs{
  483. fn: glfnViewport,
  484. a0: uintptr(x),
  485. a1: uintptr(y),
  486. a2: uintptr(width),
  487. a3: uintptr(height),
  488. },
  489. })
  490. }