gl_webgl_wasm.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. // Copyright 2018 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 js && wasm
  5. // +build js,wasm
  6. package gl
  7. import (
  8. "encoding/binary"
  9. "fmt"
  10. "math"
  11. "reflect"
  12. "runtime"
  13. "strconv"
  14. "syscall/js"
  15. "unsafe"
  16. )
  17. var ContextWatcher contextWatcher
  18. type contextWatcher struct{}
  19. func (contextWatcher) OnMakeCurrent(context interface{}) {
  20. // context must be a WebGLRenderingContext js.Value.
  21. c = context.(js.Value)
  22. }
  23. func (contextWatcher) OnDetach() {
  24. c = js.Null()
  25. }
  26. func sliceToByteSlice(s interface{}) []byte {
  27. switch s := s.(type) {
  28. case []int8:
  29. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  30. return *(*[]byte)(unsafe.Pointer(h))
  31. case []int16:
  32. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  33. h.Len *= 2
  34. h.Cap *= 2
  35. return *(*[]byte)(unsafe.Pointer(h))
  36. case []int32:
  37. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  38. h.Len *= 4
  39. h.Cap *= 4
  40. return *(*[]byte)(unsafe.Pointer(h))
  41. case []int64:
  42. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  43. h.Len *= 8
  44. h.Cap *= 8
  45. return *(*[]byte)(unsafe.Pointer(h))
  46. case []uint8:
  47. return s
  48. case []uint16:
  49. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  50. h.Len *= 2
  51. h.Cap *= 2
  52. return *(*[]byte)(unsafe.Pointer(h))
  53. case []uint32:
  54. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  55. h.Len *= 4
  56. h.Cap *= 4
  57. return *(*[]byte)(unsafe.Pointer(h))
  58. case []uint64:
  59. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  60. h.Len *= 8
  61. h.Cap *= 8
  62. return *(*[]byte)(unsafe.Pointer(h))
  63. case []float32:
  64. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  65. h.Len *= 4
  66. h.Cap *= 4
  67. return *(*[]byte)(unsafe.Pointer(h))
  68. case []float64:
  69. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  70. h.Len *= 8
  71. h.Cap *= 8
  72. return *(*[]byte)(unsafe.Pointer(h))
  73. default:
  74. panic(fmt.Sprintf("jsutil: unexpected value at sliceToBytesSlice: %T", s))
  75. }
  76. }
  77. func SliceToTypedArray(s interface{}) js.Value {
  78. if s == nil {
  79. return js.Null()
  80. }
  81. switch s := s.(type) {
  82. case []int8:
  83. a := js.Global().Get("Uint8Array").New(len(s))
  84. js.CopyBytesToJS(a, sliceToByteSlice(s))
  85. runtime.KeepAlive(s)
  86. buf := a.Get("buffer")
  87. return js.Global().Get("Int8Array").New(buf, a.Get("byteOffset"), a.Get("byteLength"))
  88. case []int16:
  89. a := js.Global().Get("Uint8Array").New(len(s) * 2)
  90. js.CopyBytesToJS(a, sliceToByteSlice(s))
  91. runtime.KeepAlive(s)
  92. buf := a.Get("buffer")
  93. return js.Global().Get("Int16Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/2)
  94. case []int32:
  95. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  96. js.CopyBytesToJS(a, sliceToByteSlice(s))
  97. runtime.KeepAlive(s)
  98. buf := a.Get("buffer")
  99. return js.Global().Get("Int32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4)
  100. case []uint8:
  101. a := js.Global().Get("Uint8Array").New(len(s))
  102. js.CopyBytesToJS(a, s)
  103. runtime.KeepAlive(s)
  104. return a
  105. case []uint16:
  106. a := js.Global().Get("Uint8Array").New(len(s) * 2)
  107. js.CopyBytesToJS(a, sliceToByteSlice(s))
  108. runtime.KeepAlive(s)
  109. buf := a.Get("buffer")
  110. return js.Global().Get("Uint16Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/2)
  111. case []uint32:
  112. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  113. js.CopyBytesToJS(a, sliceToByteSlice(s))
  114. runtime.KeepAlive(s)
  115. buf := a.Get("buffer")
  116. return js.Global().Get("Uint32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4)
  117. case []float32:
  118. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  119. js.CopyBytesToJS(a, sliceToByteSlice(s))
  120. runtime.KeepAlive(s)
  121. buf := a.Get("buffer")
  122. return js.Global().Get("Float32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4)
  123. case []float64:
  124. a := js.Global().Get("Uint8Array").New(len(s) * 8)
  125. js.CopyBytesToJS(a, sliceToByteSlice(s))
  126. runtime.KeepAlive(s)
  127. buf := a.Get("buffer")
  128. return js.Global().Get("Float64Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/8)
  129. default:
  130. panic(fmt.Sprintf("jsutil: unexpected value at SliceToTypedArray: %T", s))
  131. }
  132. }
  133. // c is the current WebGL context, or nil if there is no current context.
  134. var c js.Value
  135. func ActiveTexture(texture Enum) {
  136. c.Call("activeTexture", int(texture))
  137. }
  138. func AttachShader(p Program, s Shader) {
  139. c.Call("attachShader", p.Value, s.Value)
  140. }
  141. func BindAttribLocation(p Program, a Attrib, name string) {
  142. c.Call("bindAttribLocation", p.Value, a.Value, name)
  143. }
  144. func BindBuffer(target Enum, b Buffer) {
  145. c.Call("bindBuffer", int(target), b.Value)
  146. }
  147. func BindFramebuffer(target Enum, fb Framebuffer) {
  148. c.Call("bindFramebuffer", int(target), fb.Value)
  149. }
  150. func BindRenderbuffer(target Enum, rb Renderbuffer) {
  151. c.Call("bindRenderbuffer", int(target), rb.Value)
  152. }
  153. func BindTexture(target Enum, t Texture) {
  154. c.Call("bindTexture", int(target), t.Value)
  155. }
  156. func BlendColor(red, green, blue, alpha float32) {
  157. c.Call("blendColor", red, green, blue, alpha)
  158. }
  159. func BlendEquation(mode Enum) {
  160. c.Call("blendEquation", int(mode))
  161. }
  162. func BlendEquationSeparate(modeRGB, modeAlpha Enum) {
  163. c.Call("blendEquationSeparate", int(modeRGB), int(modeAlpha))
  164. }
  165. func BlendFunc(sfactor, dfactor Enum) {
  166. c.Call("blendFunc", int(sfactor), int(dfactor))
  167. }
  168. func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) {
  169. c.Call("blendFuncSeparate", int(sfactorRGB), int(dfactorRGB), int(sfactorAlpha), int(dfactorAlpha))
  170. }
  171. func BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask, filter Enum) {
  172. println("BlitFramebuffer: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  173. c.Call("blitFramebuffer", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, int(mask), int(filter))
  174. }
  175. func BufferData(target Enum, data interface{}, usage Enum) {
  176. c.Call("bufferData", int(target), SliceToTypedArray(data), int(usage))
  177. }
  178. func BufferInit(target Enum, size int, usage Enum) {
  179. c.Call("bufferData", int(target), size, int(usage))
  180. }
  181. func BufferSubData(target Enum, offset int, data interface{}) {
  182. c.Call("bufferSubData", int(target), offset, SliceToTypedArray(data))
  183. }
  184. func CheckFramebufferStatus(target Enum) Enum {
  185. return Enum(c.Call("checkFramebufferStatus", int(target)).Int())
  186. }
  187. func Clear(mask Enum) {
  188. c.Call("clear", int(mask))
  189. }
  190. func ClearColor(red, green, blue, alpha float32) {
  191. c.Call("clearColor", red, green, blue, alpha)
  192. }
  193. func ClearDepthf(d float32) {
  194. c.Call("clearDepth", d)
  195. }
  196. func ClearStencil(s int) {
  197. c.Call("clearStencil", s)
  198. }
  199. func ColorMask(red, green, blue, alpha bool) {
  200. c.Call("colorMask", red, green, blue, alpha)
  201. }
  202. func CompileShader(s Shader) {
  203. c.Call("compileShader", s.Value)
  204. }
  205. func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data interface{}) {
  206. c.Call("compressedTexImage2D", int(target), level, int(internalformat), width, height, border, SliceToTypedArray(data))
  207. }
  208. func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data interface{}) {
  209. c.Call("compressedTexSubImage2D", int(target), level, xoffset, yoffset, width, height, int(format), SliceToTypedArray(data))
  210. }
  211. func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) {
  212. c.Call("copyTexImage2D", int(target), level, int(internalformat), x, y, width, height, border)
  213. }
  214. func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) {
  215. c.Call("copyTexSubImage2D", int(target), level, xoffset, yoffset, x, y, width, height)
  216. }
  217. func CreateBuffer() Buffer {
  218. return Buffer{Value: c.Call("createBuffer")}
  219. }
  220. func CreateFramebuffer() Framebuffer {
  221. return Framebuffer{Value: c.Call("createFramebuffer")}
  222. }
  223. func CreateProgram() Program {
  224. return Program{Value: c.Call("createProgram")}
  225. }
  226. func CreateRenderbuffer() Renderbuffer {
  227. return Renderbuffer{Value: c.Call("createRenderbuffer")}
  228. }
  229. func CreateShader(ty Enum) Shader {
  230. return Shader{Value: c.Call("createShader", int(ty))}
  231. }
  232. func CreateTexture() Texture {
  233. return Texture{Value: c.Call("createTexture")}
  234. }
  235. func CullFace(mode Enum) {
  236. c.Call("cullFace", int(mode))
  237. }
  238. func DeleteBuffer(v Buffer) {
  239. c.Call("deleteBuffer", v.Value)
  240. }
  241. func DeleteFramebuffer(v Framebuffer) {
  242. c.Call("deleteFramebuffer", v.Value)
  243. }
  244. func DeleteProgram(p Program) {
  245. c.Call("deleteProgram", p.Value)
  246. }
  247. func DeleteRenderbuffer(v Renderbuffer) {
  248. c.Call("deleteRenderbuffer", v.Value)
  249. }
  250. func DeleteShader(s Shader) {
  251. c.Call("deleteShader", s.Value)
  252. }
  253. func DeleteTexture(v Texture) {
  254. c.Call("deleteTexture", v.Value)
  255. }
  256. func DepthFunc(fn Enum) {
  257. c.Call("depthFunc", int(fn))
  258. }
  259. func DepthMask(flag bool) {
  260. c.Call("depthMask", flag)
  261. }
  262. func DepthRangef(n, f float32) {
  263. c.Call("depthRange", n, f)
  264. }
  265. func DetachShader(p Program, s Shader) {
  266. c.Call("detachShader", p.Value, s.Value)
  267. }
  268. func Disable(cap Enum) {
  269. c.Call("disable", int(cap))
  270. }
  271. func DisableVertexAttribArray(a Attrib) {
  272. c.Call("disableVertexAttribArray", a.Value)
  273. }
  274. func DrawArrays(mode Enum, first, count int) {
  275. c.Call("drawArrays", int(mode), first, count)
  276. }
  277. func DrawElements(mode Enum, count int, ty Enum, offset int) {
  278. c.Call("drawElements", int(mode), count, int(ty), offset)
  279. }
  280. func Enable(cap Enum) {
  281. c.Call("enable", int(cap))
  282. }
  283. func EnableVertexAttribArray(a Attrib) {
  284. c.Call("enableVertexAttribArray", a.Value)
  285. }
  286. func Finish() {
  287. c.Call("finish")
  288. }
  289. func Flush() {
  290. c.Call("flush")
  291. }
  292. func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) {
  293. c.Call("framebufferRenderbuffer", int(target), int(attachment), int(rbTarget), rb.Value)
  294. }
  295. func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
  296. c.Call("framebufferTexture2D", int(target), int(attachment), int(texTarget), t.Value, level)
  297. }
  298. func FrontFace(mode Enum) {
  299. c.Call("frontFace", int(mode))
  300. }
  301. func GenerateMipmap(target Enum) {
  302. c.Call("generateMipmap", int(target))
  303. }
  304. func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) {
  305. ai := c.Call("getActiveAttrib", p.Value, index)
  306. return ai.Get("name").String(), ai.Get("size").Int(), Enum(ai.Get("type").Int())
  307. }
  308. func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) {
  309. ai := c.Call("getActiveUniform", p.Value, index)
  310. return ai.Get("name").String(), ai.Get("size").Int(), Enum(ai.Get("type").Int())
  311. }
  312. func GetAttachedShaders(p Program) []Shader {
  313. objs := c.Call("getAttachedShaders", p.Value)
  314. shaders := make([]Shader, objs.Length())
  315. for i := 0; i < objs.Length(); i++ {
  316. shaders[i] = Shader{Value: objs.Index(i)}
  317. }
  318. return shaders
  319. }
  320. func GetAttribLocation(p Program, name string) Attrib {
  321. return Attrib{Value: c.Call("getAttribLocation", p.Value, name).Int()}
  322. }
  323. func GetBooleanv(dst []bool, pname Enum) {
  324. println("GetBooleanv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  325. result := c.Call("getParameter", int(pname))
  326. length := result.Length()
  327. for i := 0; i < length; i++ {
  328. dst[i] = result.Index(i).Bool()
  329. }
  330. }
  331. func GetFloatv(dst []float32, pname Enum) {
  332. println("GetFloatv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  333. result := c.Call("getParameter", int(pname))
  334. length := result.Length()
  335. for i := 0; i < length; i++ {
  336. dst[i] = float32(result.Index(i).Float())
  337. }
  338. }
  339. func GetIntegerv(pname Enum, data []int32) {
  340. result := c.Call("getParameter", int(pname))
  341. length := result.Length()
  342. for i := 0; i < length; i++ {
  343. data[i] = int32(result.Index(i).Int())
  344. }
  345. }
  346. func GetInteger(pname Enum) int {
  347. return c.Call("getParameter", int(pname)).Int()
  348. }
  349. func GetBufferParameteri(target, pname Enum) int {
  350. return c.Call("getBufferParameter", int(target), int(pname)).Int()
  351. }
  352. func GetError() Enum {
  353. err := c.Call("getError")
  354. var r int
  355. switch err.Type() {
  356. case js.TypeString:
  357. r, _ = strconv.Atoi(err.String())
  358. case js.TypeNumber:
  359. r = err.Int()
  360. default:
  361. r = 0
  362. }
  363. return Enum(r)
  364. }
  365. func GetBoundFramebuffer() Framebuffer {
  366. return Framebuffer{Value: c.Call("getParameter", FRAMEBUFFER_BINDING)}
  367. }
  368. func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
  369. return c.Call("getFramebufferAttachmentParameter", int(target), int(attachment), int(pname)).Int()
  370. }
  371. func GetProgrami(p Program, pname Enum) int {
  372. switch pname {
  373. case DELETE_STATUS, LINK_STATUS, VALIDATE_STATUS:
  374. if c.Call("getProgramParameter", p.Value, int(pname)).Bool() {
  375. return TRUE
  376. }
  377. return FALSE
  378. default:
  379. return c.Call("getProgramParameter", p.Value, int(pname)).Int()
  380. }
  381. }
  382. func GetProgramInfoLog(p Program) string {
  383. return c.Call("getProgramInfoLog", p.Value).String()
  384. }
  385. func GetRenderbufferParameteri(target, pname Enum) int {
  386. return c.Call("getRenderbufferParameter", int(target), int(pname)).Int()
  387. }
  388. func GetShaderi(s Shader, pname Enum) int {
  389. switch pname {
  390. case DELETE_STATUS, COMPILE_STATUS:
  391. if c.Call("getShaderParameter", s.Value, int(pname)).Bool() {
  392. return TRUE
  393. }
  394. return FALSE
  395. default:
  396. return c.Call("getShaderParameter", s.Value, int(pname)).Int()
  397. }
  398. }
  399. func GetShaderInfoLog(s Shader) string {
  400. return c.Call("getShaderInfoLog", s.Value).String()
  401. }
  402. func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeMin, rangeMax, precision int) {
  403. println("GetShaderPrecisionFormat: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  404. format := c.Call("getShaderPrecisionFormat", int(shadertype), int(precisiontype))
  405. rangeMin = format.Get("rangeMin").Int()
  406. rangeMax = format.Get("rangeMax").Int()
  407. precision = format.Get("precision").Int()
  408. return
  409. }
  410. func GetShaderSource(s Shader) string {
  411. return c.Call("getShaderSource", s.Value).String()
  412. }
  413. func GetString(pname Enum) string {
  414. return c.Call("getParameter", int(pname)).String()
  415. }
  416. func GetTexParameterfv(dst []float32, target, pname Enum) {
  417. dst[0] = float32(c.Call("getTexParameter", int(target), int(pname)).Float())
  418. }
  419. func GetTexParameteriv(dst []int32, target, pname Enum) {
  420. dst[0] = int32(c.Call("getTexParameter", int(target), int(pname)).Int())
  421. }
  422. func GetUniformfv(dst []float32, src Uniform, p Program) {
  423. println("GetUniformfv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  424. result := c.Call("getUniform")
  425. length := result.Length()
  426. for i := 0; i < length; i++ {
  427. dst[i] = float32(result.Index(i).Float())
  428. }
  429. }
  430. func GetUniformiv(dst []int32, src Uniform, p Program) {
  431. println("GetUniformiv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  432. result := c.Call("getUniform")
  433. length := result.Length()
  434. for i := 0; i < length; i++ {
  435. dst[i] = int32(result.Index(i).Int())
  436. }
  437. }
  438. func GetUniformLocation(p Program, name string) Uniform {
  439. return Uniform{Value: c.Call("getUniformLocation", p.Value, name)}
  440. }
  441. func GetVertexAttribf(src Attrib, pname Enum) float32 {
  442. return float32(c.Call("getVertexAttrib", src.Value, int(pname)).Float())
  443. }
  444. func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) {
  445. result := c.Call("getVertexAttrib", src.Value, int(pname))
  446. length := result.Length()
  447. for i := 0; i < length; i++ {
  448. dst[i] = float32(result.Index(i).Float())
  449. }
  450. }
  451. func GetVertexAttribi(src Attrib, pname Enum) int32 {
  452. return int32(c.Call("getVertexAttrib", src.Value, int(pname)).Int())
  453. }
  454. func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) {
  455. result := c.Call("getVertexAttrib", src.Value, int(pname))
  456. length := result.Length()
  457. for i := 0; i < length; i++ {
  458. dst[i] = int32(result.Index(i).Int())
  459. }
  460. }
  461. func Hint(target, mode Enum) {
  462. c.Call("hint", int(target), int(mode))
  463. }
  464. func IsBuffer(b Buffer) bool {
  465. return c.Call("isBuffer", b.Value).Bool()
  466. }
  467. func IsEnabled(cap Enum) bool {
  468. return c.Call("isEnabled", int(cap)).Bool()
  469. }
  470. func IsFramebuffer(fb Framebuffer) bool {
  471. return c.Call("isFramebuffer", fb.Value).Bool()
  472. }
  473. func IsProgram(p Program) bool {
  474. return c.Call("isProgram", p.Value).Bool()
  475. }
  476. func IsRenderbuffer(rb Renderbuffer) bool {
  477. return c.Call("isRenderbuffer", rb.Value).Bool()
  478. }
  479. func IsShader(s Shader) bool {
  480. return c.Call("isShader", s.Value).Bool()
  481. }
  482. func IsTexture(t Texture) bool {
  483. return c.Call("isTexture", t.Value).Bool()
  484. }
  485. func LineWidth(width float32) {
  486. c.Call("lineWidth", width)
  487. }
  488. func LinkProgram(p Program) {
  489. c.Call("linkProgram", p.Value)
  490. }
  491. func ObjectLabel(o Object, label string) {
  492. // not available in WebGL
  493. }
  494. func PixelStorei(pname Enum, param int32) {
  495. c.Call("pixelStorei", int(pname), param)
  496. }
  497. func PolygonOffset(factor, units float32) {
  498. c.Call("polygonOffset", factor, units)
  499. }
  500. func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) {
  501. println("ReadPixels: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  502. if ty == Enum(UNSIGNED_BYTE) {
  503. c.Call("readPixels", x, y, width, height, int(format), int(ty), dst)
  504. } else {
  505. tmpDst := make([]float32, len(dst)/4)
  506. c.Call("readPixels", x, y, width, height, int(format), int(ty), tmpDst)
  507. for i, f := range tmpDst {
  508. binary.LittleEndian.PutUint32(dst[i*4:], math.Float32bits(f))
  509. }
  510. }
  511. }
  512. func ReleaseShaderCompiler() {
  513. // do nothing
  514. }
  515. func RenderbufferStorage(target, internalFormat Enum, width, height int) {
  516. c.Call("renderbufferStorage", int(target), int(internalFormat), width, height)
  517. }
  518. func SampleCoverage(value float32, invert bool) {
  519. c.Call("sampleCoverage", value, invert)
  520. }
  521. func Scissor(x, y, width, height int32) {
  522. c.Call("scissor", x, y, width, height)
  523. }
  524. func ShaderSource(s Shader, src string) {
  525. c.Call("shaderSource", s.Value, src)
  526. }
  527. func StencilFunc(fn Enum, ref int, mask uint32) {
  528. c.Call("stencilFunc", int(fn), ref, mask)
  529. }
  530. func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) {
  531. c.Call("stencilFuncSeparate", int(face), int(fn), ref, mask)
  532. }
  533. func StencilMask(mask uint32) {
  534. c.Call("stencilMask", mask)
  535. }
  536. func StencilMaskSeparate(face Enum, mask uint32) {
  537. c.Call("stencilMaskSeparate", int(face), mask)
  538. }
  539. func StencilOp(fail, zfail, zpass Enum) {
  540. c.Call("stencilOp", int(fail), int(zfail), int(zpass))
  541. }
  542. func StencilOpSeparate(face, sfail, dpfail, dppass Enum) {
  543. c.Call("stencilOpSeparate", int(face), int(sfail), int(dpfail), int(dppass))
  544. }
  545. func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data interface{}) {
  546. c.Call("texImage2D", int(target), level, int(format), width, height, 0, int(format), int(ty), SliceToTypedArray(data))
  547. }
  548. func TexImage2DMultisample(target Enum, samples int, internalformat Enum, width, height int, fixedsamplelocations bool) {
  549. println("TexImage2DMultisample: not available on WebGL.")
  550. }
  551. func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data interface{}) {
  552. c.Call("texSubImage2D", int(target), level, x, y, width, height, format, int(ty), SliceToTypedArray(data))
  553. }
  554. func TexParameterf(target, pname Enum, param float32) {
  555. c.Call("texParameterf", int(target), int(pname), param)
  556. }
  557. func TexParameterfv(target, pname Enum, params []float32) {
  558. println("TexParameterfv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  559. for _, param := range params {
  560. c.Call("texParameterf", int(target), int(pname), SliceToTypedArray(param))
  561. }
  562. }
  563. func TexParameteri(target, pname Enum, param int) {
  564. c.Call("texParameteri", int(target), int(pname), param)
  565. }
  566. func TexParameteriv(target, pname Enum, params []int32) {
  567. println("TexParameteriv: not yet tested (TODO: remove this after it's confirmed to work. Your feedback is welcome.)")
  568. for _, param := range params {
  569. c.Call("texParameteri", int(target), int(pname), SliceToTypedArray(param))
  570. }
  571. }
  572. func Uniform1f(dst Uniform, v float32) {
  573. c.Call("uniform1f", dst.Value, v)
  574. }
  575. func Uniform1fv(dst Uniform, src []float32) {
  576. c.Call("uniform1fv", dst.Value, SliceToTypedArray(src))
  577. }
  578. func Uniform1i(dst Uniform, v int) {
  579. c.Call("uniform1i", dst.Value, v)
  580. }
  581. func Uniform1iv(dst Uniform, src []int32) {
  582. c.Call("uniform1iv", dst.Value, SliceToTypedArray(src))
  583. }
  584. func Uniform2f(dst Uniform, v0, v1 float32) {
  585. c.Call("uniform2f", dst.Value, v0, v1)
  586. }
  587. func Uniform2fv(dst Uniform, src []float32) {
  588. c.Call("uniform2fv", dst.Value, SliceToTypedArray(src))
  589. }
  590. func Uniform2i(dst Uniform, v0, v1 int) {
  591. c.Call("uniform2i", dst.Value, v0, v1)
  592. }
  593. func Uniform2iv(dst Uniform, src []int32) {
  594. c.Call("uniform2iv", dst.Value, SliceToTypedArray(src))
  595. }
  596. func Uniform3f(dst Uniform, v0, v1, v2 float32) {
  597. c.Call("uniform3f", dst.Value, v0, v1, v2)
  598. }
  599. func Uniform3fv(dst Uniform, src []float32) {
  600. c.Call("uniform3fv", dst.Value, SliceToTypedArray(src))
  601. }
  602. func Uniform3i(dst Uniform, v0, v1, v2 int32) {
  603. c.Call("uniform3i", dst.Value, v0, v1, v2)
  604. }
  605. func Uniform3iv(dst Uniform, src []int32) {
  606. c.Call("uniform3iv", dst.Value, SliceToTypedArray(src))
  607. }
  608. func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
  609. c.Call("uniform4f", dst.Value, v0, v1, v2, v3)
  610. }
  611. func Uniform4fv(dst Uniform, src []float32) {
  612. c.Call("uniform4fv", dst.Value, SliceToTypedArray(src))
  613. }
  614. func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) {
  615. c.Call("uniform4i", dst.Value, v0, v1, v2, v3)
  616. }
  617. func Uniform4iv(dst Uniform, src []int32) {
  618. c.Call("uniform4iv", dst.Value, SliceToTypedArray(src))
  619. }
  620. func UniformMatrix2fv(dst Uniform, src []float32) {
  621. c.Call("uniformMatrix2fv", dst.Value, false, SliceToTypedArray(src))
  622. }
  623. func UniformMatrix3fv(dst Uniform, src []float32) {
  624. c.Call("uniformMatrix3fv", dst.Value, false, SliceToTypedArray(src))
  625. }
  626. func UniformMatrix4fv(dst Uniform, src []float32) {
  627. c.Call("uniformMatrix4fv", dst.Value, false, SliceToTypedArray(src))
  628. }
  629. func UseProgram(p Program) {
  630. // Workaround for js.Value zero value.
  631. if p.Value.Equal(js.Value{}) {
  632. p.Value = js.Null()
  633. }
  634. c.Call("useProgram", p.Value)
  635. }
  636. func ValidateProgram(p Program) {
  637. c.Call("validateProgram", p.Value)
  638. }
  639. func VertexAttrib1f(dst Attrib, x float32) {
  640. c.Call("vertexAttrib1f", dst.Value, x)
  641. }
  642. func VertexAttrib1fv(dst Attrib, src []float32) {
  643. c.Call("vertexAttrib1fv", dst.Value, SliceToTypedArray(src))
  644. }
  645. func VertexAttrib2f(dst Attrib, x, y float32) {
  646. c.Call("vertexAttrib2f", dst.Value, x, y)
  647. }
  648. func VertexAttrib2fv(dst Attrib, src []float32) {
  649. c.Call("vertexAttrib2fv", dst.Value, SliceToTypedArray(src))
  650. }
  651. func VertexAttrib3f(dst Attrib, x, y, z float32) {
  652. c.Call("vertexAttrib3f", dst.Value, x, y, z)
  653. }
  654. func VertexAttrib3fv(dst Attrib, src []float32) {
  655. c.Call("vertexAttrib3fv", dst.Value, SliceToTypedArray(src))
  656. }
  657. func VertexAttrib4f(dst Attrib, x, y, z, w float32) {
  658. c.Call("vertexAttrib4f", dst.Value, x, y, z, w)
  659. }
  660. func VertexAttrib4fv(dst Attrib, src []float32) {
  661. c.Call("vertexAttrib4fv", dst.Value, SliceToTypedArray(src))
  662. }
  663. func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
  664. c.Call("vertexAttribPointer", dst.Value, size, int(ty), normalized, stride, offset)
  665. }
  666. func Viewport(x, y, width, height int) {
  667. c.Call("viewport", x, y, width, height)
  668. }