mesh.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. // Mesh is a Graphic with uniforms for the model, view, projection, and normal matrices.
  13. type Mesh struct {
  14. Graphic // Embedded graphic
  15. uniMm gls.Uniform // Model matrix uniform location cache
  16. uniMVm gls.Uniform // Model view matrix uniform location cache
  17. uniMVPm gls.Uniform // Model view projection matrix uniform cache
  18. uniNm gls.Uniform // Normal matrix uniform cache
  19. }
  20. // NewMesh creates and returns a pointer to a mesh with the specified geometry and material.
  21. // If the mesh has multi materials, the material specified here must be nil and the
  22. // individual materials must be add using "AddMaterial" or AddGroupMaterial".
  23. func NewMesh(igeom geometry.IGeometry, imat material.IMaterial) *Mesh {
  24. m := new(Mesh)
  25. m.Init(igeom, imat)
  26. return m
  27. }
  28. // Init initializes the Mesh and its uniforms.
  29. func (m *Mesh) Init(igeom geometry.IGeometry, imat material.IMaterial) {
  30. m.Graphic.Init(m, igeom, gls.TRIANGLES)
  31. // Initialize uniforms
  32. m.uniMm.Init("ModelMatrix")
  33. m.uniMVm.Init("ModelViewMatrix")
  34. m.uniMVPm.Init("MVP")
  35. m.uniNm.Init("NormalMatrix")
  36. // Adds single material if not nil
  37. if imat != nil {
  38. m.AddMaterial(imat, 0, 0)
  39. }
  40. }
  41. // SetMaterial clears all materials and adds the specified material for all vertices.
  42. func (m *Mesh) SetMaterial(imat material.IMaterial) {
  43. m.Graphic.ClearMaterials()
  44. m.Graphic.AddMaterial(m, imat, 0, 0)
  45. }
  46. // AddMaterial adds a material for the specified subset of vertices.
  47. func (m *Mesh) AddMaterial(imat material.IMaterial, start, count int) {
  48. m.Graphic.AddMaterial(m, imat, start, count)
  49. }
  50. // AddGroupMaterial adds a material for the specified geometry group.
  51. func (m *Mesh) AddGroupMaterial(imat material.IMaterial, gindex int) {
  52. m.Graphic.AddGroupMaterial(m, imat, gindex)
  53. }
  54. // Clone clones the mesh and satisfies the INode interface.
  55. func (m *Mesh) Clone() core.INode {
  56. clone := new(Mesh)
  57. clone.Graphic = *m.Graphic.Clone().(*Graphic)
  58. clone.SetIGraphic(clone)
  59. // Initialize uniforms
  60. clone.uniMm.Init("ModelMatrix")
  61. clone.uniMVm.Init("ModelViewMatrix")
  62. clone.uniMVPm.Init("MVP")
  63. clone.uniNm.Init("NormalMatrix")
  64. return clone
  65. }
  66. // RenderSetup is called by the engine before drawing the mesh geometry
  67. // It is responsible to updating the current shader uniforms with
  68. // the model matrices.
  69. func (m *Mesh) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
  70. // Transfer uniform for model matrix
  71. mm := m.ModelMatrix()
  72. location := m.uniMm.Location(gs)
  73. gs.UniformMatrix4fv(location, 1, false, &mm[0])
  74. // Transfer uniform for model view matrix
  75. mvm := m.ModelViewMatrix()
  76. location = m.uniMVm.Location(gs)
  77. gs.UniformMatrix4fv(location, 1, false, &mvm[0])
  78. // Transfer uniform for model view projection matrix
  79. mvpm := m.ModelViewProjectionMatrix()
  80. location = m.uniMVPm.Location(gs)
  81. gs.UniformMatrix4fv(location, 1, false, &mvpm[0])
  82. // Calculates normal matrix and transfer uniform
  83. var nm math32.Matrix3
  84. nm.GetNormalMatrix(mvm)
  85. location = m.uniNm.Location(gs)
  86. gs.UniformMatrix3fv(location, 1, false, &nm[0])
  87. }