gls.go 11 KB

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