Daniel Salvadori 7 лет назад
Родитель
Сommit
30e9d48dda
5 измененных файлов с 100 добавлено и 92 удалено
  1. 58 0
      gls/shaderdefines.go
  2. 23 48
      material/material.go
  3. 10 10
      material/physical.go
  4. 1 1
      renderer/renderer.go
  5. 8 33
      renderer/shaman.go

+ 58 - 0
gls/shaderdefines.go

@@ -0,0 +1,58 @@
+// 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 gls
+
+// ShaderDefines is a store of shader defines ("#define <key> <value>").
+type ShaderDefines map[string]string
+
+// NewShaderDefines creates and returns a pointer to a ShaderDefines object.
+func NewShaderDefines() *ShaderDefines {
+
+	sd := ShaderDefines(make(map[string]string))
+	return &sd
+}
+
+// Set sets a shader define with the specified value.
+func (sd *ShaderDefines) Set(name, value string) {
+
+	(*sd)[name] = value
+}
+
+// Unset removes the specified name from the shader defines.
+func (sd *ShaderDefines) Unset(name string) {
+
+	delete(*sd, name)
+}
+
+// Add adds to this ShaderDefines all the key-value pairs in the specified ShaderDefines.
+func (sd *ShaderDefines) Add(other *ShaderDefines) {
+
+	for k, v := range map[string]string(*other){
+		(*sd)[k] = v
+	}
+}
+
+// Equals compares two ShaderDefines and return true if they contain the same key-value pairs.
+func (sd *ShaderDefines) Equals(other *ShaderDefines) bool {
+
+	if sd == nil && other == nil {
+		return true
+	}
+	if sd != nil && other != nil {
+		if len(*sd) != len(*other) {
+			return false
+		}
+		for k := range map[string]string(*sd) {
+			v1, ok1 := (*sd)[k]
+			v2, ok2 := (*other)[k]
+			if v1 != v2 || ok1 != ok2 {
+				return false
+			}
+		}
+		return true
+	}
+	// One is nil and the other is not nil
+	return false
+}

+ 23 - 48
material/material.go

@@ -57,28 +57,28 @@ type IMaterial interface {
 // Base Material
 //
 type Material struct {
-	refcount         int                  // Current number of references
-	shader           string               // Shader name
-	shaderUnique     bool                 // shader has only one instance (does not depend on lights or textures)
-	uselights        UseLights            // consider lights for shader selection
-	sidevis          Side                 // sides visible
-	transparent      bool                 // whether at all transparent
-	wireframe        bool                 // show as wirefrme
-	depthMask        bool                 // Enable writing into the depth buffer
-	depthTest        bool                 // Enable depth buffer test
-	depthFunc        uint32               // Active depth test function
-	blending         Blending             // blending mode
-	blendRGB         uint32               // separate blend equation for RGB
-	blendAlpha       uint32               // separate blend equation for Alpha
-	blendSrcRGB      uint32               // separate blend func source RGB
-	blendDstRGB      uint32               // separate blend func dest RGB
-	blendSrcAlpha    uint32               // separate blend func source Alpha
-	blendDstAlpha    uint32               // separate blend func dest Alpha
-	lineWidth        float32              // line width for lines and mesh wireframe
-	polyOffsetFactor float32              // polygon offset factor
-	polyOffsetUnits  float32              // polygon offset units
-	defines          map[string]string    // shader defines
-	textures         []*texture.Texture2D // List of textures
+	refcount         int                    // Current number of references
+	shader           string                 // Shader name
+	shaderUnique     bool                   // shader has only one instance (does not depend on lights or textures)
+	uselights        UseLights              // consider lights for shader selection
+	sidevis          Side                   // sides visible
+	transparent      bool                   // whether at all transparent
+	wireframe        bool                   // show as wirefrme
+	depthMask        bool                   // Enable writing into the depth buffer
+	depthTest        bool                   // Enable depth buffer test
+	depthFunc        uint32                 // Active depth test function
+	blending         Blending               // blending mode
+	blendRGB         uint32                 // separate blend equation for RGB
+	blendAlpha       uint32                 // separate blend equation for Alpha
+	blendSrcRGB      uint32                 // separate blend func source RGB
+	blendDstRGB      uint32                 // separate blend func dest RGB
+	blendSrcAlpha    uint32                 // separate blend func source Alpha
+	blendDstAlpha    uint32                 // separate blend func dest Alpha
+	lineWidth        float32                // line width for lines and mesh wireframe
+	polyOffsetFactor float32                // polygon offset factor
+	polyOffsetUnits  float32                // polygon offset units
+	ShaderDefines    gls.ShaderDefines      // shader defines
+	textures         []*texture.Texture2D   // List of textures
 }
 
 // NewMaterial returns a pointer to a new material
@@ -103,6 +103,7 @@ func (mat *Material) Init() *Material {
 	mat.polyOffsetFactor = 0
 	mat.polyOffsetUnits = 0
 	mat.textures = make([]*texture.Texture2D, 0)
+	mat.ShaderDefines = *gls.NewShaderDefines()
 
 	return mat
 }
@@ -233,32 +234,6 @@ func (mat *Material) SetPolygonOffset(factor, units float32) {
 	mat.polyOffsetUnits = units
 }
 
-// SetShaderDefine defines a name with the specified value which are
-// passed to this material shader.
-func (mat *Material) SetShaderDefine(name, value string) {
-
-	if mat.defines == nil {
-		mat.defines = make(map[string]string)
-	}
-	mat.defines[name] = value
-}
-
-// UnsetShaderDefines removes the specified name from the defines which
-// are passed to this material shader.
-func (mat *Material) UnsetShaderDefine(name string) {
-
-	if mat.defines == nil {
-		return
-	}
-	delete(mat.defines, name)
-}
-
-// ShaderDefines returns this material map of shader defines.
-func (mat *Material) ShaderDefines() map[string]string {
-
-	return mat.defines
-}
-
 func (mat *Material) RenderSetup(gs *gls.GLS) {
 
 	// Sets triangle side view mode

+ 10 - 10
material/physical.go

@@ -93,10 +93,10 @@ func (m *Physical) SetBaseColorMap(tex *texture.Texture2D) *Physical {
 	m.baseColorTex = tex
 	if m.baseColorTex != nil {
 		m.baseColorTex.SetUniformNames("uBaseColorSampler", "uBaseColorTexParams")
-		m.SetShaderDefine("HAS_BASECOLORMAP", "")
+		m.ShaderDefines.Set("HAS_BASECOLORMAP", "")
 		m.AddTexture(m.baseColorTex)
 	} else {
-		m.UnsetShaderDefine("HAS_BASECOLORMAP")
+		m.ShaderDefines.Unset("HAS_BASECOLORMAP")
 		m.RemoveTexture(m.baseColorTex)
 	}
 	return m
@@ -109,10 +109,10 @@ func (m *Physical) SetMetallicRoughnessMap(tex *texture.Texture2D) *Physical {
 	m.metallicRoughnessTex = tex
 	if m.metallicRoughnessTex != nil {
 		m.metallicRoughnessTex.SetUniformNames("uMetallicRoughnessSampler", "uMetallicRoughnessTexParams")
-		m.SetShaderDefine("HAS_METALROUGHNESSMAP", "")
+		m.ShaderDefines.Set("HAS_METALROUGHNESSMAP", "")
 		m.AddTexture(m.metallicRoughnessTex)
 	} else {
-		m.UnsetShaderDefine("HAS_METALROUGHNESSMAP")
+		m.ShaderDefines.Unset("HAS_METALROUGHNESSMAP")
 		m.RemoveTexture(m.metallicRoughnessTex)
 	}
 	return m
@@ -126,10 +126,10 @@ func (m *Physical) SetNormalMap(tex *texture.Texture2D) *Physical {
 	m.normalTex = tex
 	if m.normalTex != nil {
 		m.normalTex.SetUniformNames("uNormalSampler", "uNormalTexParams")
-		m.SetShaderDefine("HAS_NORMALMAP", "")
+		m.ShaderDefines.Set("HAS_NORMALMAP", "")
 		m.AddTexture(m.normalTex)
 	} else {
-		m.UnsetShaderDefine("HAS_NORMALMAP")
+		m.ShaderDefines.Unset("HAS_NORMALMAP")
 		m.RemoveTexture(m.normalTex)
 	}
 	return m
@@ -142,10 +142,10 @@ func (m *Physical) SetOcclusionMap(tex *texture.Texture2D) *Physical {
 	m.occlusionTex = tex
 	if m.occlusionTex != nil {
 		m.occlusionTex.SetUniformNames("uOcclusionSampler", "uOcclusionTexParams")
-		m.SetShaderDefine("HAS_OCCLUSIONMAP", "")
+		m.ShaderDefines.Set("HAS_OCCLUSIONMAP", "")
 		m.AddTexture(m.occlusionTex)
 	} else {
-		m.UnsetShaderDefine("HAS_OCCLUSIONMAP")
+		m.ShaderDefines.Unset("HAS_OCCLUSIONMAP")
 		m.RemoveTexture(m.occlusionTex)
 	}
 	return m
@@ -158,10 +158,10 @@ func (m *Physical) SetEmissiveMap(tex *texture.Texture2D) *Physical {
 	m.emissiveTex = tex
 	if m.emissiveTex != nil {
 		m.emissiveTex.SetUniformNames("uEmissiveSampler", "uEmissiveTexParams")
-		m.SetShaderDefine("HAS_EMISSIVEMAP", "")
+		m.ShaderDefines.Set("HAS_EMISSIVEMAP", "")
 		m.AddTexture(m.emissiveTex)
 	} else {
-		m.UnsetShaderDefine("HAS_EMISSIVEMAP")
+		m.ShaderDefines.Unset("HAS_EMISSIVEMAP")
 		m.RemoveTexture(m.emissiveTex)
 	}
 	return m

+ 1 - 1
renderer/renderer.go

@@ -364,7 +364,7 @@ func (r *Renderer) renderScene(iscene core.INode, icam camera.ICamera) error {
 			r.specs.ShaderUnique = mat.ShaderUnique()
 			r.specs.UseLights = mat.UseLights()
 			r.specs.MatTexturesMax = mat.TextureCount()
-			r.specs.Defines = mat.ShaderDefines()
+			r.specs.Defines = mat.ShaderDefines
 			_, err = r.shaman.SetProgram(&r.specs)
 			if err != nil {
 				return

+ 8 - 33
renderer/shaman.go

@@ -34,7 +34,7 @@ type ShaderSpecs struct {
 	PointLightsMax   int                // Current Number of point lights
 	SpotLightsMax    int                // Current Number of spot lights
 	MatTexturesMax   int                // Current Number of material textures
-	Defines          map[string]string  // Additional shader defines
+	Defines          gls.ShaderDefines  // Additional shader defines
 }
 
 // ProgSpecs represents a compiled shader program along with its specs
@@ -139,13 +139,13 @@ func (sm *Shaman) SetProgram(s *ShaderSpecs) (bool, error) {
 	}
 
 	// If current shader specs are the same as the specified specs, nothing to do.
-	if sm.specs.compare(&specs) {
+	if sm.specs.equals(&specs) {
 		return false, nil
 	}
 
 	// Search for compiled program with the specified specs
 	for _, pinfo := range sm.programs {
-		if pinfo.specs.compare(&specs) {
+		if pinfo.specs.equals(&specs) {
 			sm.gs.UseProgram(pinfo.program)
 			sm.specs = specs
 			return true, nil
@@ -291,15 +291,13 @@ func (ss *ShaderSpecs) copy(other *ShaderSpecs) {
 
 	*ss = *other
 	if other.Defines != nil {
-		ss.Defines = make(map[string]string)
-		for k, v := range other.Defines {
-			ss.Defines[k] = v
-		}
+		ss.Defines = *gls.NewShaderDefines()
+		ss.Defines.Add(&other.Defines)
 	}
 }
 
-// Compare compares two shaders specifications structures
-func (ss *ShaderSpecs) compare(other *ShaderSpecs) bool {
+// equals compares two ShaderSpecs and returns true if they are effectively equal.
+func (ss *ShaderSpecs) equals(other *ShaderSpecs) bool {
 
 	if ss.Name != other.Name {
 		return false
@@ -312,31 +310,8 @@ func (ss *ShaderSpecs) compare(other *ShaderSpecs) bool {
 		ss.PointLightsMax == other.PointLightsMax &&
 		ss.SpotLightsMax == other.SpotLightsMax &&
 		ss.MatTexturesMax == other.MatTexturesMax &&
-		ss.compareDefines(other) {
-		return true
-	}
-	return false
-}
-
-// compareDefines compares two shaders specification define maps.
-func (ss *ShaderSpecs) compareDefines(other *ShaderSpecs) bool {
-
-	if ss.Defines == nil && other.Defines == nil {
-		return true
-	}
-	if ss.Defines != nil && other.Defines != nil {
-		if len(ss.Defines) != len(other.Defines) {
-			return false
-		}
-		for k := range ss.Defines {
-			v1, ok1 := ss.Defines[k]
-			v2, ok2 := other.Defines[k]
-			if v1 != v2 || ok1 != ok2 {
-				return false
-			}
-		}
+		ss.Defines.Equals(&other.Defines) {
 		return true
 	}
-	// One is nil and the other is not nil
 	return false
 }