skybox.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. "github.com/g3n/engine/texture"
  12. )
  13. type SkyboxData struct {
  14. DirAndPrefix string
  15. Extension string
  16. Suffixes [6]string
  17. }
  18. type Skybox struct {
  19. Graphic // embedded graphic object
  20. uniMVM gls.Uniform // model view matrix uniform location cache
  21. uniMVPM gls.Uniform // model view projection matrix uniform cache
  22. uniNM gls.Uniform // normal matrix uniform cache
  23. }
  24. // NewSkybox creates and returns a pointer to a skybox with the specified textures
  25. func NewSkybox(data SkyboxData) (*Skybox, error) {
  26. skybox := new(Skybox)
  27. geom := geometry.NewBox(50, 50, 50, 1, 1, 1)
  28. skybox.Graphic.Init(geom, gls.TRIANGLES)
  29. for i := 0; i < 6; i++ {
  30. tex, err := texture.NewTexture2DFromImage(data.DirAndPrefix + data.Suffixes[i] + "." + data.Extension)
  31. if err != nil {
  32. return nil, err
  33. }
  34. matFace := material.NewStandard(math32.NewColor("white"))
  35. matFace.AddTexture(tex)
  36. matFace.SetSide(material.SideBack)
  37. matFace.SetUseLights(material.UseLightAmbient)
  38. skybox.AddGroupMaterial(skybox, matFace, i)
  39. }
  40. // Creates uniforms
  41. skybox.uniMVM.Init("ModelViewMatrix")
  42. skybox.uniMVPM.Init("MVP")
  43. skybox.uniNM.Init("NormalMatrix")
  44. return skybox, nil
  45. }
  46. // RenderSetup is called by the engine before drawing the skybox geometry
  47. // It is responsible to updating the current shader uniforms with
  48. // the model matrices.
  49. func (skybox *Skybox) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
  50. // TODO
  51. // Disable writes to the depth buffer (call glDepthMask(GL_FALSE)).
  52. // This will cause every other object to draw over the skybox, making it always appear "behind" everything else.
  53. // Since writes to the depth buffer are off, it doesn't matter how small the skybox is as long as it's larger than the camera's near clip plane.
  54. var mvm math32.Matrix4
  55. mvm.Copy(&rinfo.ViewMatrix)
  56. // Clear translation
  57. mvm[12] = 0
  58. mvm[13] = 0
  59. mvm[14] = 0
  60. // mvm.ExtractRotation(&rinfo.ViewMatrix) // TODO <- ExtractRotation does not work as expected?
  61. // Transfer mvp uniform
  62. location := skybox.uniMVM.Location(gs)
  63. gs.UniformMatrix4fv(location, 1, false, &mvm[0])
  64. // Calculates model view projection matrix and updates uniform
  65. var mvpm math32.Matrix4
  66. mvpm.MultiplyMatrices(&rinfo.ProjMatrix, &mvm)
  67. location = skybox.uniMVPM.Location(gs)
  68. gs.UniformMatrix4fv(location, 1, false, &mvpm[0])
  69. // Calculates normal matrix and updates uniform
  70. var nm math32.Matrix3
  71. nm.GetNormalMatrix(&mvm)
  72. location = skybox.uniNM.Location(gs)
  73. gs.UniformMatrix3fv(location, 1, false, &nm[0])
  74. }