gls.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. // Copyright 2016 The G3N 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. // Package gls allows access to the OpenGL functions.
  5. package gls
  6. import (
  7. "github.com/g3n/engine/util/logger"
  8. "github.com/go-gl/gl/v3.3-core/gl"
  9. "math"
  10. )
  11. // GLS allows access to the OpenGL functions and keeps state to
  12. // minimize functions calling.
  13. // It also keeps some statistics of some OpenGL objects currently allocated
  14. type GLS struct {
  15. // Statistics
  16. Stats struct {
  17. Vaos int // Number of Vertex Array Objects
  18. Vbos int // Number of Vertex Buffer Objects
  19. Textures int // Number of Textures
  20. }
  21. Prog *Program // Current active program
  22. programs map[*Program]bool // Programs cache
  23. checkErrors bool // Check openGL API errors flag
  24. viewportX int32
  25. viewportY int32
  26. viewportWidth int32
  27. viewportHeight int32
  28. lineWidth float32
  29. sideView int
  30. depthFunc uint32
  31. depthMask int
  32. capabilities map[int]int
  33. blendEquation uint32
  34. blendSrc uint32
  35. blendDst uint32
  36. blendEquationRGB uint32
  37. blendEquationAlpha uint32
  38. blendSrcRGB uint32
  39. blendSrcAlpha uint32
  40. blendDstRGB uint32
  41. blendDstAlpha uint32
  42. }
  43. const (
  44. capUndef = 0
  45. capDisabled = 1
  46. capEnabled = 2
  47. )
  48. const (
  49. uintUndef = math.MaxUint32
  50. intFalse = 0
  51. intTrue = 1
  52. )
  53. // Polygon side view.
  54. const (
  55. FrontSide = iota + 1
  56. BackSide
  57. DoubleSide
  58. )
  59. // Package logger
  60. var log = logger.New("GLS", logger.Default)
  61. // New creates and returns a new instance of an GLS object
  62. // which encapsulates the state of an OpenGL context
  63. // This should be called only after an active OpenGL context
  64. // was established, such as by creating a new window.
  65. func New() (*GLS, error) {
  66. gs := new(GLS)
  67. gs.Reset()
  68. // Initialize GL
  69. err := gl.Init()
  70. if err != nil {
  71. return nil, err
  72. }
  73. gs.SetDefaultState()
  74. gs.checkErrors = true
  75. return gs, nil
  76. }
  77. // SetCheckErrors enables/disables checking for errors after the
  78. // call of any OpenGL function. It is enabled by default but
  79. // could be disabled after an application is stable to improve the performance.
  80. func (gs *GLS) SetCheckErrors(enable bool) {
  81. gs.checkErrors = enable
  82. }
  83. // ChecksErrors returns if error checking is enabled or not.
  84. func (gs *GLS) CheckErrors() bool {
  85. return gs.checkErrors
  86. }
  87. // Reset resets the internal state kept of the OpenGL
  88. func (gs *GLS) Reset() {
  89. gs.lineWidth = 0.0
  90. gs.sideView = uintUndef
  91. gs.depthFunc = 0
  92. gs.depthMask = uintUndef
  93. gs.capabilities = make(map[int]int)
  94. gs.programs = make(map[*Program]bool)
  95. gs.Prog = nil
  96. gs.blendEquation = uintUndef
  97. gs.blendSrc = uintUndef
  98. gs.blendDst = uintUndef
  99. gs.blendEquationRGB = 0
  100. gs.blendEquationAlpha = 0
  101. gs.blendSrcRGB = uintUndef
  102. gs.blendSrcAlpha = uintUndef
  103. gs.blendDstRGB = uintUndef
  104. gs.blendDstAlpha = uintUndef
  105. }
  106. func (gs *GLS) SetDefaultState() {
  107. gl.ClearColor(0, 0, 0, 1)
  108. gl.ClearDepth(1)
  109. gl.ClearStencil(0)
  110. gs.Enable(gl.DEPTH_TEST)
  111. gs.DepthFunc(gl.LEQUAL)
  112. gl.FrontFace(gl.CCW)
  113. gl.CullFace(gl.BACK)
  114. gs.Enable(gl.CULL_FACE)
  115. gs.Enable(gl.BLEND)
  116. gs.BlendEquation(gl.FUNC_ADD)
  117. gs.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
  118. gs.Enable(gl.VERTEX_PROGRAM_POINT_SIZE)
  119. gs.Enable(gl.PROGRAM_POINT_SIZE)
  120. gs.Enable(gl.MULTISAMPLE)
  121. }
  122. func (gs *GLS) ActiveTexture(texture uint32) {
  123. gl.ActiveTexture(texture)
  124. gs.checkError("ActiveTexture")
  125. }
  126. func (gs *GLS) BindBuffer(target int, vbo uint32) {
  127. gl.BindBuffer(uint32(target), vbo)
  128. gs.checkError("BindBuffer")
  129. }
  130. func (gs *GLS) BindTexture(target int, tex uint32) {
  131. gl.BindTexture(uint32(target), tex)
  132. gs.checkError("BindTexture")
  133. }
  134. func (gs *GLS) BindVertexArray(vao uint32) {
  135. gl.BindVertexArray(vao)
  136. gs.checkError("BindVertexArray")
  137. }
  138. func (gs *GLS) BlendEquation(mode uint32) {
  139. if gs.blendEquation == mode {
  140. return
  141. }
  142. gl.BlendEquation(mode)
  143. gs.checkError("BlendEquation")
  144. gs.blendEquation = mode
  145. }
  146. func (gs *GLS) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) {
  147. if gs.blendEquationRGB == modeRGB && gs.blendEquationAlpha == modeAlpha {
  148. return
  149. }
  150. gl.BlendEquationSeparate(uint32(modeRGB), uint32(modeAlpha))
  151. gs.checkError("BlendEquationSeparate")
  152. gs.blendEquationRGB = modeRGB
  153. gs.blendEquationAlpha = modeAlpha
  154. }
  155. func (gs *GLS) BlendFunc(sfactor, dfactor uint32) {
  156. if gs.blendSrc == sfactor && gs.blendDst == dfactor {
  157. return
  158. }
  159. gl.BlendFunc(sfactor, dfactor)
  160. gs.checkError("BlendFunc")
  161. gs.blendSrc = sfactor
  162. gs.blendDst = dfactor
  163. }
  164. func (gs *GLS) BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) {
  165. if gs.blendSrcRGB == srcRGB && gs.blendDstRGB == dstRGB &&
  166. gs.blendSrcAlpha == srcAlpha && gs.blendDstAlpha == dstAlpha {
  167. return
  168. }
  169. gl.BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)
  170. gs.checkError("BlendFuncSeparate")
  171. gs.blendSrcRGB = srcRGB
  172. gs.blendDstRGB = dstRGB
  173. gs.blendSrcAlpha = srcAlpha
  174. gs.blendDstAlpha = dstAlpha
  175. }
  176. func (gs *GLS) BufferData(target uint32, size int, data interface{}, usage uint32) {
  177. gl.BufferData(target, size, gl.Ptr(data), usage)
  178. gs.checkError("BufferData")
  179. }
  180. func (gs *GLS) ClearColor(r, g, b, a float32) {
  181. gl.ClearColor(r, g, b, a)
  182. }
  183. func (gs *GLS) Clear(mask int) {
  184. gl.Clear(uint32(mask))
  185. }
  186. func (gs *GLS) DeleteBuffers(vbos ...uint32) {
  187. gl.DeleteBuffers(int32(len(vbos)), &vbos[0])
  188. gs.checkError("DeleteBuffers")
  189. }
  190. func (gs *GLS) DeleteTextures(tex ...uint32) {
  191. gl.DeleteTextures(int32(len(tex)), &tex[0])
  192. gs.checkError("DeleteTextures")
  193. gs.Stats.Textures -= len(tex)
  194. }
  195. func (gs *GLS) DeleteVertexArrays(vaos ...uint32) {
  196. gl.DeleteVertexArrays(int32(len(vaos)), &vaos[0])
  197. gs.checkError("DeleteVertexArrays")
  198. }
  199. func (gs *GLS) DepthFunc(mode uint32) {
  200. if gs.depthFunc == mode {
  201. return
  202. }
  203. gl.DepthFunc(mode)
  204. gs.checkError("DepthFunc")
  205. gs.depthFunc = mode
  206. }
  207. func (gs *GLS) DepthMask(flag bool) {
  208. if gs.depthMask == intTrue && flag {
  209. return
  210. }
  211. if gs.depthMask == intFalse && !flag {
  212. return
  213. }
  214. gl.DepthMask(flag)
  215. gs.checkError("DepthMask")
  216. if flag {
  217. gs.depthMask = intTrue
  218. } else {
  219. gs.depthMask = intFalse
  220. }
  221. }
  222. func (gs *GLS) DrawArrays(mode uint32, first int32, count int32) {
  223. gl.DrawArrays(mode, first, count)
  224. gs.checkError("DrawArrays")
  225. }
  226. func (gs *GLS) DrawElements(mode uint32, count int32, itype uint32, start uint32) {
  227. gl.DrawElements(mode, int32(count), itype, gl.PtrOffset(int(start)))
  228. gs.checkError("DrawElements")
  229. }
  230. func (gs *GLS) Enable(cap int) {
  231. if gs.capabilities[cap] == capEnabled {
  232. return
  233. }
  234. gl.Enable(uint32(cap))
  235. gs.checkError("Enable")
  236. gs.capabilities[cap] = capEnabled
  237. }
  238. func (gs *GLS) EnableVertexAttribArray(index uint32) {
  239. gl.EnableVertexAttribArray(index)
  240. gs.checkError("EnableVertexAttribArray")
  241. }
  242. func (gs *GLS) Disable(cap int) {
  243. if gs.capabilities[cap] == capDisabled {
  244. return
  245. }
  246. gl.Disable(uint32(cap))
  247. gs.checkError("Disable")
  248. gs.capabilities[cap] = capDisabled
  249. }
  250. func (gs *GLS) FrontFace(mode uint32) {
  251. gl.FrontFace(mode)
  252. gs.checkError("FrontFace")
  253. }
  254. func (gs *GLS) GenBuffer() uint32 {
  255. var buf uint32
  256. gl.GenBuffers(1, &buf)
  257. gs.checkError("GenBuffers")
  258. gs.Stats.Vbos++
  259. return buf
  260. }
  261. func (gs *GLS) GenerateMipmap(target uint32) {
  262. gl.GenerateMipmap(target)
  263. gs.checkError("GenerateMipmap")
  264. }
  265. func (gs *GLS) GenTexture() uint32 {
  266. var tex uint32
  267. gl.GenTextures(1, &tex)
  268. gs.checkError("GenTextures")
  269. gs.Stats.Textures++
  270. return tex
  271. }
  272. func (gs *GLS) GenVertexArray() uint32 {
  273. var vao uint32
  274. gl.GenVertexArrays(1, &vao)
  275. gs.checkError("GenVertexArrays")
  276. gs.Stats.Vaos++
  277. return vao
  278. }
  279. func (gs *GLS) GetString(name uint32) string {
  280. cstr := gl.GetString(name)
  281. return gl.GoStr(cstr)
  282. }
  283. func (gs *GLS) GetViewport() (x, y, width, height int32) {
  284. return gs.viewportX, gs.viewportY, gs.viewportWidth, gs.viewportHeight
  285. }
  286. func (gs *GLS) LineWidth(width float32) {
  287. if gs.lineWidth == width {
  288. return
  289. }
  290. gl.LineWidth(width)
  291. gs.checkError("LineWidth")
  292. gs.lineWidth = width
  293. }
  294. func (gs *GLS) SetDepthTest(mode bool) {
  295. if mode {
  296. gs.Enable(gl.DEPTH_TEST)
  297. } else {
  298. gs.Disable(gl.DEPTH_TEST)
  299. }
  300. }
  301. func (gs *GLS) SetSideView(mode int) {
  302. if gs.sideView == mode {
  303. return
  304. }
  305. switch mode {
  306. // Default: show only the front size
  307. case FrontSide:
  308. gs.Enable(gl.CULL_FACE)
  309. gl.FrontFace(gl.CCW)
  310. // Show only the back side
  311. case BackSide:
  312. gs.Enable(gl.CULL_FACE)
  313. gl.FrontFace(gl.CW)
  314. // Show both sides
  315. case DoubleSide:
  316. gs.Disable(gl.CULL_FACE)
  317. default:
  318. panic("SetSideView() invalid mode")
  319. }
  320. gs.sideView = mode
  321. }
  322. func (gs *GLS) TexImage2D(target uint32, level int32, iformat int32, width int32, height int32, border int32, format uint32, itype uint32, data interface{}) {
  323. gl.TexImage2D(uint32(target), int32(level), int32(iformat), int32(width), int32(height), int32(border), uint32(format), uint32(itype), gl.Ptr(data))
  324. gs.checkError("TexImage2D")
  325. }
  326. func (gs *GLS) TexStorage2D(target int, levels int, iformat int, width, height int) {
  327. gl.TexStorage2D(uint32(target), int32(levels), uint32(iformat), int32(width), int32(height))
  328. gs.checkError("TexStorage2D")
  329. }
  330. func (gs *GLS) TexParameteri(target uint32, pname uint32, param int32) {
  331. gl.TexParameteri(target, pname, param)
  332. gs.checkError("TexParameteri")
  333. }
  334. func (gs *GLS) PolygonMode(face, mode int) {
  335. gl.PolygonMode(uint32(face), uint32(mode))
  336. gs.checkError("PolygonMode")
  337. }
  338. func (gs *GLS) PolygonOffset(factor float32, units float32) {
  339. gl.PolygonOffset(factor, units)
  340. gs.checkError("PolygonOffset")
  341. }
  342. func (gs *GLS) Uniform1i(location int32, v0 int32) {
  343. gl.Uniform1i(location, v0)
  344. gs.checkError("Uniform1i")
  345. }
  346. func (gs *GLS) Uniform1f(location int32, v0 float32) {
  347. gl.Uniform1f(location, v0)
  348. gs.checkError("Uniform1f")
  349. }
  350. func (gs *GLS) Uniform2f(location int32, v0, v1 float32) {
  351. gl.Uniform2f(location, v0, v1)
  352. gs.checkError("Uniform2f")
  353. }
  354. func (gs *GLS) Uniform3f(location int32, v0, v1, v2 float32) {
  355. gl.Uniform3f(location, v0, v1, v2)
  356. gs.checkError("Uniform3f")
  357. }
  358. func (gs *GLS) Uniform4f(location int32, v0, v1, v2, v3 float32) {
  359. gl.Uniform4f(location, v0, v1, v2, v3)
  360. gs.checkError("Uniform4f")
  361. }
  362. func (gs *GLS) UniformMatrix3fv(location int32, count int32, transpose bool, v []float32) {
  363. gl.UniformMatrix3fv(location, count, transpose, &v[0])
  364. gs.checkError("UniformMatrix3fv")
  365. }
  366. func (gs *GLS) UniformMatrix4fv(location int32, count int32, transpose bool, v []float32) {
  367. gl.UniformMatrix4fv(location, count, transpose, &v[0])
  368. gs.checkError("UniformMatrix4fv")
  369. }
  370. // Use set this program as the current program.
  371. func (gs *GLS) UseProgram(prog *Program) {
  372. if prog.handle == 0 {
  373. panic("Invalid program")
  374. }
  375. gl.UseProgram(prog.handle)
  376. gs.checkError("UseProgram")
  377. gs.Prog = prog
  378. // Inserts program in cache if not already there.
  379. if !gs.programs[prog] {
  380. gs.programs[prog] = true
  381. log.Debug("New Program activated. Total: %d", len(gs.programs))
  382. }
  383. }
  384. func (gs *GLS) VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset uint32) {
  385. gl.VertexAttribPointer(index, size, xtype, normalized, stride, gl.PtrOffset(int(offset)))
  386. gs.checkError("VertexAttribPointer")
  387. }
  388. func (gs *GLS) Viewport(x, y, width, height int32) {
  389. gl.Viewport(x, y, width, height)
  390. gs.checkError("Viewport")
  391. gs.viewportX = x
  392. gs.viewportY = y
  393. gs.viewportWidth = width
  394. gs.viewportHeight = height
  395. }
  396. // checkError checks the error code of the previously called OpenGL function
  397. func (gls *GLS) checkError(fname string) {
  398. if gls.CheckErrors() {
  399. ecode := gl.GetError()
  400. if ecode != 0 {
  401. log.Fatal("Error:%d calling:%s()", ecode, fname)
  402. }
  403. }
  404. }