| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // Copyright 2016 The G3N Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package graphic
- import (
- "github.com/g3n/engine/core"
- "github.com/g3n/engine/geometry"
- "github.com/g3n/engine/gls"
- "github.com/g3n/engine/material"
- "github.com/g3n/engine/math32"
- "github.com/g3n/engine/texture"
- )
- // Skybox is the Graphic that represents a skybox.
- type Skybox struct {
- Graphic // embedded graphic object
- uniMVm gls.Uniform // model view matrix uniform location cache
- uniMVPm gls.Uniform // model view projection matrix uniform cache
- uniNm gls.Uniform // normal matrix uniform cache
- }
- // SkyboxData contains the data necessary to locate the textures for a Skybox in a concise manner.
- type SkyboxData struct {
- DirAndPrefix string
- Extension string
- Suffixes [6]string
- }
- // NewSkybox creates and returns a pointer to a Skybox with the specified textures.
- func NewSkybox(data SkyboxData) (*Skybox, error) {
- skybox := new(Skybox)
- geom := geometry.NewCube(1)
- skybox.Graphic.Init(skybox, geom, gls.TRIANGLES)
- skybox.Graphic.SetCullable(false)
- for i := 0; i < 6; i++ {
- tex, err := texture.NewTexture2DFromImage(data.DirAndPrefix + data.Suffixes[i] + "." + data.Extension)
- if err != nil {
- return nil, err
- }
- matFace := material.NewStandard(math32.NewColor("white"))
- matFace.AddTexture(tex)
- matFace.SetSide(material.SideBack)
- matFace.SetUseLights(material.UseLightNone)
- matFace.SetEmissiveColor(&math32.Color{1, 1, 1})
- // Disable writes to the depth buffer (call glDepthMask(GL_FALSE)).
- // This will cause every other object to draw over the skybox, making it always appear behind everything else.
- // It doesn't matter how small/big the skybox is as long as it's visible by the camera (within near/far planes).
- matFace.SetDepthMask(false)
- skybox.AddGroupMaterial(skybox, matFace, i)
- }
- // Creates uniforms
- skybox.uniMVm.Init("ModelViewMatrix")
- skybox.uniMVPm.Init("MVP")
- skybox.uniNm.Init("NormalMatrix")
- // The skybox should always be rendered last among the opaque objects
- skybox.SetRenderOrder(100)
- return skybox, nil
- }
- // RenderSetup is called by the engine before drawing the skybox geometry
- // It is responsible to updating the current shader uniforms with
- // the model matrices.
- func (skybox *Skybox) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo) {
- mvm := *skybox.ModelViewMatrix()
- // Clear translation
- mvm[12] = 0
- mvm[13] = 0
- mvm[14] = 0
- // mvm.ExtractRotation(&rinfo.ViewMatrix) // TODO <- ExtractRotation does not work as expected?
- // Transfer mvp uniform
- location := skybox.uniMVm.Location(gs)
- gs.UniformMatrix4fv(location, 1, false, &mvm[0])
- // Calculates model view projection matrix and updates uniform
- var mvpm math32.Matrix4
- mvpm.MultiplyMatrices(&rinfo.ProjMatrix, &mvm)
- location = skybox.uniMVPm.Location(gs)
- gs.UniformMatrix4fv(location, 1, false, &mvpm[0])
- // Calculates normal matrix and updates uniform
- var nm math32.Matrix3
- nm.GetNormalMatrix(&mvm)
- location = skybox.uniNm.Location(gs)
- gs.UniformMatrix3fv(location, 1, false, &nm[0])
- }
|