graphic.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 graphic
  5. import (
  6. "github.com/g3n/engine/core"
  7. "github.com/g3n/engine/geometry"
  8. "github.com/g3n/engine/gls"
  9. "github.com/g3n/engine/material"
  10. "github.com/g3n/engine/math32"
  11. )
  12. // Graphic is a Node which has a visible representation in the scene.
  13. // It has an associated geometry and one or more materials.
  14. // It is the base type used by other graphics such as lines, line_strip,
  15. // points and meshes.
  16. type Graphic struct {
  17. core.Node // Embedded Node
  18. igeom geometry.IGeometry // Associated IGeometry
  19. materials []GraphicMaterial // Materials
  20. mode uint32 // OpenGL primitive
  21. renderable bool // Renderable flag
  22. cullable bool // Cullable flag
  23. renderOrder int // Render order
  24. mvm math32.Matrix4 // Cached ModelView matrix
  25. mvpm math32.Matrix4 // Cached ModelViewProjection matrix
  26. }
  27. // GraphicMaterial specifies the material to be used for
  28. // a subset of vertices from the Graphic geometry
  29. // A Graphic object has at least one GraphicMaterial.
  30. type GraphicMaterial struct {
  31. imat material.IMaterial // Associated material
  32. start int // Index of first element in the geometry
  33. count int // Number of elements
  34. igraphic IGraphic // Graphic which contains this GraphicMaterial
  35. }
  36. // IGraphic is the interface for all Graphic objects.
  37. type IGraphic interface {
  38. core.INode
  39. GetGraphic() *Graphic
  40. GetGeometry() *geometry.Geometry
  41. Renderable() bool
  42. SetRenderable(bool)
  43. Cullable() bool
  44. SetCullable(bool)
  45. RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo)
  46. }
  47. // NewGraphic creates and returns a pointer to a new graphic object with
  48. // the specified geometry and OpenGL primitive.
  49. // The created graphic object, though, has not materials.
  50. func NewGraphic(igeom geometry.IGeometry, mode uint32) *Graphic {
  51. gr := new(Graphic)
  52. return gr.Init(igeom, mode)
  53. }
  54. // Init initializes a Graphic type embedded in another type
  55. // with the specified geometry and OpenGL mode.
  56. func (gr *Graphic) Init(igeom geometry.IGeometry, mode uint32) *Graphic {
  57. gr.Node.Init()
  58. gr.igeom = igeom
  59. gr.mode = mode
  60. gr.materials = make([]GraphicMaterial, 0)
  61. gr.renderable = true
  62. gr.cullable = true
  63. return gr
  64. }
  65. // GetGraphic satisfies the IGraphic interface and
  66. // returns pointer to the base Graphic.
  67. func (gr *Graphic) GetGraphic() *Graphic {
  68. return gr
  69. }
  70. // GetGeometry satisfies the IGraphic interface and returns
  71. // a pointer to the geometry associated with this graphic.
  72. func (gr *Graphic) GetGeometry() *geometry.Geometry {
  73. return gr.igeom.GetGeometry() // TODO return igeom
  74. }
  75. // Dispose overrides the embedded Node Dispose method.
  76. func (gr *Graphic) Dispose() {
  77. gr.igeom.Dispose()
  78. for i := 0; i < len(gr.materials); i++ {
  79. gr.materials[i].imat.Dispose()
  80. }
  81. }
  82. // SetRenderable satisfies the IGraphic interface and
  83. // sets the renderable state of this Graphic (default = true).
  84. func (gr *Graphic) SetRenderable(state bool) {
  85. gr.renderable = state
  86. }
  87. // Renderable satisfies the IGraphic interface and
  88. // returns the renderable state of this graphic.
  89. func (gr *Graphic) Renderable() bool {
  90. return gr.renderable
  91. }
  92. // SetCullable satisfies the IGraphic interface and
  93. // sets the cullable state of this Graphic (default = true).
  94. func (gr *Graphic) SetCullable(state bool) {
  95. gr.cullable = state
  96. }
  97. // Cullable satisfies the IGraphic interface and
  98. // returns the cullable state of this graphic.
  99. func (gr *Graphic) Cullable() bool {
  100. return gr.cullable
  101. }
  102. // SetRenderOrder sets the render order of the object.
  103. // All objects have renderOrder of 0 by default.
  104. // To render before renderOrder 0 set a lower renderOrder e.g. -1.
  105. // To render after renderOrder 0 set a higher renderOrder e.g. 1
  106. func (gr *Graphic) SetRenderOrder(order int) {
  107. gr.renderOrder = order
  108. }
  109. // RenderOrder returns the render order of the object.
  110. func (gr *Graphic) RenderOrder() int {
  111. return gr.renderOrder
  112. }
  113. // AddMaterial adds a material for the specified subset of vertices.
  114. // If the material applies to all vertices, start and count must be 0.
  115. func (gr *Graphic) AddMaterial(igr IGraphic, imat material.IMaterial, start, count int) {
  116. gmat := GraphicMaterial{
  117. imat: imat,
  118. start: start,
  119. count: count,
  120. igraphic: igr,
  121. }
  122. gr.materials = append(gr.materials, gmat)
  123. }
  124. // AddGroupMaterial adds a material for the specified geometry group.
  125. func (gr *Graphic) AddGroupMaterial(igr IGraphic, imat material.IMaterial, gindex int) {
  126. geom := gr.igeom.GetGeometry()
  127. if gindex < 0 || gindex >= geom.GroupCount() {
  128. panic("Invalid group index")
  129. }
  130. group := geom.GroupAt(gindex)
  131. gr.AddMaterial(igr, imat, group.Start, group.Count)
  132. }
  133. // Materials returns slice with this graphic materials.
  134. func (gr *Graphic) Materials() []GraphicMaterial {
  135. return gr.materials
  136. }
  137. // GetMaterial returns the material associated with the specified vertex position.
  138. func (gr *Graphic) GetMaterial(vpos int) material.IMaterial {
  139. for _, gmat := range gr.materials {
  140. // Case for unimaterial
  141. if gmat.count == 0 {
  142. return gmat.imat
  143. }
  144. if gmat.start >= vpos && gmat.start+gmat.count <= vpos {
  145. return gmat.imat
  146. }
  147. }
  148. return nil
  149. }
  150. // CalculateMatrices calculates the model view and model view projection matrices.
  151. func (gr *Graphic) CalculateMatrices(gs *gls.GLS, rinfo *core.RenderInfo) {
  152. // Calculate model view and model view projection matrices
  153. mw := gr.MatrixWorld()
  154. gr.mvm.MultiplyMatrices(&rinfo.ViewMatrix, &mw)
  155. gr.mvpm.MultiplyMatrices(&rinfo.ProjMatrix, &gr.mvm)
  156. }
  157. // ModelViewMatrix returns the last cached model view matrix for this graphic.
  158. func (gr *Graphic) ModelViewMatrix() *math32.Matrix4 {
  159. return &gr.mvm
  160. }
  161. // ModelViewProjectionMatrix returns the last cached model view projection matrix for this graphic.
  162. func (gr *Graphic) ModelViewProjectionMatrix() *math32.Matrix4 {
  163. return &gr.mvpm
  164. }
  165. // GetMaterial returns the material associated with the GraphicMaterial.
  166. func (grmat *GraphicMaterial) GetMaterial() material.IMaterial {
  167. return grmat.imat
  168. }
  169. // GetGraphic returns the graphic associated with the GraphicMaterial.
  170. func (grmat *GraphicMaterial) GetGraphic() IGraphic {
  171. return grmat.igraphic
  172. }
  173. // Render is called by the renderer to render this graphic material.
  174. func (grmat *GraphicMaterial) Render(gs *gls.GLS, rinfo *core.RenderInfo) {
  175. // Setup the associated material (set states and transfer material uniforms and textures)
  176. grmat.imat.RenderSetup(gs)
  177. // Setup the associated geometry (set VAO and transfer VBOS)
  178. gr := grmat.igraphic.GetGraphic()
  179. gr.igeom.RenderSetup(gs)
  180. // Setup current graphic (transfer matrices)
  181. grmat.igraphic.RenderSetup(gs, rinfo)
  182. // Get the number of vertices for the current material
  183. count := grmat.count
  184. geom := gr.igeom.GetGeometry()
  185. indices := geom.Indices()
  186. // Indexed geometry
  187. if indices.Size() > 0 {
  188. if count == 0 {
  189. count = indices.Size()
  190. }
  191. gs.DrawElements(gr.mode, int32(count), gls.UNSIGNED_INT, 4*uint32(grmat.start))
  192. // Non indexed geometry
  193. } else {
  194. if count == 0 {
  195. count = geom.Items()
  196. }
  197. gs.DrawArrays(gr.mode, int32(grmat.start), int32(count))
  198. }
  199. }