Bladeren bron

gui renderer dev...

leonsal 8 jaren geleden
bovenliggende
commit
00c2098a88
3 gewijzigde bestanden met toevoegingen van 122 en 33 verwijderingen
  1. 37 0
      core/node.go
  2. 8 22
      gui/panel.go
  3. 77 11
      renderer/renderer.go

+ 37 - 0
core/node.go

@@ -32,6 +32,7 @@ type Node struct {
 	matrix      math32.Matrix4    // Transform matrix relative to this node parent.
 	matrixWorld math32.Matrix4    // Transform world matrix
 	visible     bool              // Visible flag
+	changed     bool              // Node position/orientation/scale changed
 	parent      INode             // Parent node
 	children    []INode           // Array with node children
 	userData    interface{}       // Generic user data
@@ -59,6 +60,7 @@ func (n *Node) Init() {
 	n.matrixWorld.Identity()
 	n.children = make([]INode, 0)
 	n.visible = true
+	n.changed = true
 }
 
 // GetNode satisfies the INode interface and returns
@@ -154,6 +156,18 @@ func (n *Node) FindLoaderID(id string) INode {
 	return finder(n, id)
 }
 
+// SetChanged sets this node changed flag
+func (n *Node) SetChanged(changed bool) {
+
+	n.changed = changed
+}
+
+// Changed returns this Node changed flag
+func (n *Node) Changed() bool {
+
+	return n.changed
+}
+
 // SetName set an option name for the node.
 // This name can be used for debugging or other purposes.
 func (n *Node) SetName(name string) {
@@ -171,30 +185,35 @@ func (n *Node) Name() string {
 func (n *Node) SetPosition(x, y, z float32) {
 
 	n.position.Set(x, y, z)
+	n.changed = true
 }
 
 // SetPositionVec sets this node position from the specified vector pointer
 func (n *Node) SetPositionVec(vpos *math32.Vector3) {
 
 	n.position = *vpos
+	n.changed = true
 }
 
 // SetPositionX sets the x coordinate of this node position
 func (n *Node) SetPositionX(x float32) {
 
 	n.position.X = x
+	n.changed = true
 }
 
 // SetPositionY sets the y coordinate of this node position
 func (n *Node) SetPositionY(y float32) {
 
 	n.position.Y = y
+	n.changed = true
 }
 
 // SetPositionZ sets the z coordinate of this node position
 func (n *Node) SetPositionZ(z float32) {
 
 	n.position.Z = z
+	n.changed = true
 }
 
 // Position returns the current node position as a vector
@@ -209,6 +228,7 @@ func (n *Node) SetRotation(x, y, z float32) {
 
 	n.rotation.Set(x, y, z)
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // SetRotationX sets the x rotation angle in radians
@@ -217,6 +237,7 @@ func (n *Node) SetRotationX(x float32) {
 
 	n.rotation.X = x
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // SetRotationY sets the y rotation angle in radians
@@ -225,6 +246,7 @@ func (n *Node) SetRotationY(y float32) {
 
 	n.rotation.Y = y
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // SetRotationZ sets the z rotation angle in radians
@@ -233,6 +255,7 @@ func (n *Node) SetRotationZ(z float32) {
 
 	n.rotation.Z = z
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // AddRotationX adds to the current rotation x coordinate in radians
@@ -241,6 +264,7 @@ func (n *Node) AddRotationX(x float32) {
 
 	n.rotation.X += x
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // AddRotationY adds to the current rotation y coordinate in radians
@@ -249,6 +273,7 @@ func (n *Node) AddRotationY(y float32) {
 
 	n.rotation.Y += y
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // AddRotationZ adds to the current rotation z coordinate in radians
@@ -257,6 +282,7 @@ func (n *Node) AddRotationZ(z float32) {
 
 	n.rotation.Z += z
 	n.quaternion.SetFromEuler(&n.rotation)
+	n.changed = true
 }
 
 // Rotation returns the current rotation
@@ -269,18 +295,21 @@ func (n *Node) Rotation() math32.Vector3 {
 func (n *Node) SetQuaternion(x, y, z, w float32) {
 
 	n.quaternion.Set(x, y, z, w)
+	n.changed = true
 }
 
 // SetQuaternionQuat sets this node quaternion from the specified quaternion pointer
 func (n *Node) SetQuaternionQuat(q *math32.Quaternion) {
 
 	n.quaternion = *q
+	n.changed = true
 }
 
 // QuaternionMult multiplies the quaternion by the specified quaternion
 func (n *Node) QuaternionMult(q *math32.Quaternion) {
 
 	n.quaternion.Multiply(q)
+	n.changed = true
 }
 
 // Quaternion returns the current quaternion
@@ -293,30 +322,35 @@ func (n *Node) Quaternion() math32.Quaternion {
 func (n *Node) SetScale(x, y, z float32) {
 
 	n.scale.Set(x, y, z)
+	n.changed = true
 }
 
 // SetScaleVec sets this node scale from a pointer to a Vector3
 func (n *Node) SetScaleVec(scale *math32.Vector3) {
 
 	n.scale = *scale
+	n.changed = true
 }
 
 // SetScaleX sets the X scale of this node
 func (n *Node) SetScaleX(sx float32) {
 
 	n.scale.X = sx
+	n.changed = true
 }
 
 // SetScaleY sets the Y scale of this node
 func (n *Node) SetScaleY(sy float32) {
 
 	n.scale.Y = sy
+	n.changed = true
 }
 
 // SetScaleZ sets the Z scale of this node
 func (n *Node) SetScaleZ(sz float32) {
 
 	n.scale.Z = sz
+	n.changed = true
 }
 
 // Scale returns the current scale
@@ -329,12 +363,14 @@ func (n *Node) Scale() math32.Vector3 {
 func (n *Node) SetDirection(x, y, z float32) {
 
 	n.direction.Set(x, y, z)
+	n.changed = true
 }
 
 // SetDirection sets this node initial direction vector
 func (n *Node) SetDirectionv(vdir *math32.Vector3) {
 
 	n.direction = *vdir
+	n.changed = true
 }
 
 // Direction returns this node initial direction
@@ -347,6 +383,7 @@ func (n *Node) Direction() math32.Vector3 {
 func (n *Node) SetMatrix(m *math32.Matrix4) {
 
 	n.matrix = *m
+	n.changed = true
 }
 
 // Matrix returns a copy of this node local transformation matrix

+ 8 - 22
gui/panel.go

@@ -74,7 +74,6 @@ type Panel struct {
 	bounded          bool               // panel is bounded by its parent
 	enabled          bool               // enable event processing
 	cursorEnter      bool               // mouse enter dispatched
-	changed          bool               // changed flag
 	layout           ILayout            // current layout for children
 	layoutParams     interface{}        // current layout parameters used by container panel
 	uniMatrix        gls.Uniform        // model matrix uniform location cache
@@ -176,7 +175,6 @@ func (p *Panel) InitializeGraphic(width, height float32, gr *graphic.Graphic) {
 	p.udata.bordersColor = math32.Color4{0, 0, 0, 1}
 	p.bounded = true
 	p.enabled = true
-	p.changed = true
 	p.resize(width, height, true)
 }
 
@@ -233,7 +231,7 @@ func (p *Panel) SetTopChild(ipan IPanel) {
 	found := p.Remove(ipan)
 	if found {
 		p.Add(ipan)
-		p.changed = true
+		p.SetChanged(true)
 	}
 }
 
@@ -243,7 +241,6 @@ func (p *Panel) SetPosition(x, y float32) {
 
 	p.Node.SetPositionX(math32.Round(x))
 	p.Node.SetPositionY(math32.Round(y))
-	p.changed = true
 }
 
 // SetSize sets this panel external width and height in pixels.
@@ -392,14 +389,14 @@ func (p *Panel) Paddings() BorderSizes {
 func (p *Panel) SetBordersColor(color *math32.Color) {
 
 	p.udata.bordersColor = math32.Color4{color.R, color.G, color.B, 1}
-	p.changed = true
+	p.SetChanged(true)
 }
 
 // SetBordersColor4 sets the color and opacity of this panel borders
 func (p *Panel) SetBordersColor4(color *math32.Color4) {
 
 	p.udata.bordersColor = *color
-	p.changed = true
+	p.SetChanged(true)
 }
 
 // BorderColor4 returns current border color
@@ -412,7 +409,7 @@ func (p *Panel) BordersColor4() math32.Color4 {
 func (p *Panel) SetPaddingsColor(color *math32.Color) {
 
 	p.udata.paddingsColor = math32.Color4{color.R, color.G, color.B, 1}
-	p.changed = true
+	p.SetChanged(true)
 }
 
 // SetColor sets the color of the panel paddings and content area
@@ -420,7 +417,7 @@ func (p *Panel) SetColor(color *math32.Color) *Panel {
 
 	p.udata.paddingsColor = math32.Color4{color.R, color.G, color.B, 1}
 	p.udata.contentColor = p.udata.paddingsColor
-	p.changed = true
+	p.SetChanged(true)
 	return p
 }
 
@@ -429,7 +426,7 @@ func (p *Panel) SetColor4(color *math32.Color4) *Panel {
 
 	p.udata.paddingsColor = *color
 	p.udata.contentColor = *color
-	p.changed = true
+	p.SetChanged(true)
 	return p
 }
 
@@ -523,6 +520,7 @@ func (p *Panel) Bounded() bool {
 func (p *Panel) SetBounded(bounded bool) {
 
 	p.bounded = bounded
+	p.SetChanged(true)
 }
 
 // UpdateMatrixWorld overrides the standard core.Node version which is called by
@@ -571,18 +569,6 @@ func (p *Panel) InsideBorders(x, y float32) bool {
 	return true
 }
 
-// SetChanged sets this panel changed flag
-func (p *Panel) SetChanged(changed bool) {
-
-	p.changed = changed
-}
-
-// Changed returns this panel changed flag
-func (p *Panel) Changed() bool {
-
-	return p.changed
-}
-
 // SetEnabled sets the panel enabled state
 // A disabled panel do not process key or mouse events.
 func (p *Panel) SetEnabled(state bool) {
@@ -883,7 +869,7 @@ func (p *Panel) resize(width, height float32, dispatch bool) {
 		float32(p.content.Width) / float32(p.width),
 		float32(p.content.Height) / float32(p.height),
 	}
-	p.changed = true
+	p.SetChanged(true)
 
 	// Update layout and dispatch event
 	if !dispatch {

+ 77 - 11
renderer/renderer.go

@@ -26,6 +26,8 @@ type Renderer struct {
 	grmats      []*graphic.GraphicMaterial // Array of all graphic materials for scene
 	rinfo       core.RenderInfo            // Preallocated Render info
 	specs       ShaderSpecs                // Preallocated Shader specs
+	clearScreen bool                       // Clear screen flag
+	needSwap    bool
 }
 
 func NewRenderer(gs *gls.GLS) *Renderer {
@@ -79,12 +81,19 @@ func (r *Renderer) SetScene(scene core.INode) {
 	r.scene = scene
 }
 
+func (r *Renderer) NeedSwap() bool {
+
+	return r.needSwap
+}
+
 // Render renders the previously set Scene and Gui using the specified camera
 func (r *Renderer) Render(icam camera.ICamera) error {
 
+	r.needSwap = false
+
 	// Renders the 3D scene
 	if r.scene != nil {
-		r.gs.Clear(gls.DEPTH_BUFFER_BIT | gls.STENCIL_BUFFER_BIT | gls.COLOR_BUFFER_BIT)
+		//r.gs.Clear(gls.DEPTH_BUFFER_BIT | gls.STENCIL_BUFFER_BIT | gls.COLOR_BUFFER_BIT)
 		err := r.renderScene(r.scene, icam)
 		if err != nil {
 			return err
@@ -188,6 +197,12 @@ func (r *Renderer) renderScene(iscene core.INode, icam camera.ICamera) error {
 		r.others[i].Render(r.gs)
 	}
 
+	if len(r.grmats) > 0 {
+		r.gs.Clear(gls.DEPTH_BUFFER_BIT | gls.STENCIL_BUFFER_BIT | gls.COLOR_BUFFER_BIT)
+		r.needSwap = true
+		log.Error("Clear screen")
+	}
+
 	// For each *GraphicMaterial
 	for _, grmat := range r.grmats {
 		//log.Debug("grmat:%v", grmat)
@@ -234,28 +249,78 @@ func (r *Renderer) renderGui(icam camera.ICamera) error {
 	icam.ViewMatrix(&r.rinfo.ViewMatrix)
 	icam.ProjMatrix(&r.rinfo.ProjMatrix)
 
-	var buildRenderList func(ipan gui.IPanel)
-	buildRenderList = func(ipan gui.IPanel) {
+	// checkBounded checks if any of this panel children has
+	// changed and it is not bounded
+	var checkBounded func(ipan gui.IPanel) bool
+	checkBounded = func(ipan gui.IPanel) bool {
+		pan := ipan.GetPanel()
+		if !pan.Visible() {
+			return false
+		}
+		if pan.Changed() && !pan.Bounded() {
+			return true
+		}
+		for _, ichild := range pan.Children() {
+			if checkBounded(ichild.(gui.IPanel)) {
+				return true
+			}
+		}
+		return false
+	}
+
+	// checkChildren checks if any of this panel immediate children has changed
+	checkChildren := func(ipan gui.IPanel) bool {
+		pan := ipan.GetPanel()
+		for _, ichild := range pan.Children() {
+			child := ichild.(gui.IPanel).GetPanel()
+			if !child.Visible() || !child.Renderable() {
+				continue
+			}
+			if child.Changed() {
+				return true
+			}
+		}
+		return false
+	}
+
+	var buildRenderList func(ipan gui.IPanel, checkChanged bool)
+	buildRenderList = func(ipan gui.IPanel, checkChanged bool) {
 		pan := ipan.GetPanel()
 		// If panel is not visible, ignore
 		if !pan.Visible() {
 			return
 		}
-		// Get panel graphic materials
-		gr := pan.GetGraphic()
-		materials := gr.Materials()
-		for i := 0; i < len(materials); i++ {
-			r.grmats = append(r.grmats, &materials[i])
+		// If no check or if any of this panel immediate children changed,
+		// inserts this panel if renderable and all its visible/renderable children
+		if !checkChanged || checkChildren(ipan) || checkBounded(ipan) {
+			if pan.Renderable() {
+				materials := pan.GetGraphic().Materials()
+				r.grmats = append(r.grmats, &materials[0])
+			}
+			for _, ichild := range pan.Children() {
+				buildRenderList(ichild.(gui.IPanel), false)
+			}
+			pan.SetChanged(false)
+			return
+		}
+		// If this panel is renderable and changed, inserts this panel
+		if pan.Renderable() && pan.Changed() {
+			materials := pan.GetGraphic().Materials()
+			r.grmats = append(r.grmats, &materials[0])
 		}
-		// Get this panel children
+		// Checks this panel children
 		for _, ichild := range pan.Children() {
-			buildRenderList(ichild.(gui.IPanel))
+			buildRenderList(ichild.(gui.IPanel), true)
 		}
+		pan.SetChanged(false)
 	}
 
 	// Builds list of panel graphic materials to render
 	r.grmats = r.grmats[0:0]
-	buildRenderList(parent)
+	buildRenderList(parent, true)
+	if len(r.grmats) > 0 {
+		log.Error("render list:%v", len(r.grmats))
+	}
 
 	// For each *GraphicMaterial
 	for _, grmat := range r.grmats {
@@ -270,6 +335,7 @@ func (r *Renderer) renderGui(icam camera.ICamera) error {
 		}
 		// Render this graphic material
 		grmat.Render(r.gs, &r.rinfo)
+		r.needSwap = true
 	}
 
 	return nil