Bladeren bron

gui.Panel shader support for optional texture in the same program instance

leonsal 8 jaren geleden
bovenliggende
commit
f1a8ec6556
9 gewijzigde bestanden met toevoegingen van 82 en 88 verwijderingen
  1. 12 0
      gls/uniform.go
  2. 1 0
      gui/chart.go
  3. 12 2
      gui/panel.go
  4. 0 34
      light/spot.go
  5. 17 1
      material/material.go
  6. 1 0
      renderer/renderer.go
  7. 30 21
      renderer/shader/shaderPanel.go
  8. 9 2
      renderer/shaman.go
  9. 0 28
      texture/texture2D.go

+ 12 - 0
gls/uniform.go

@@ -697,6 +697,18 @@ func (uni *Uniform4fv) GetColor4(idx int) math32.Color4 {
 	return math32.Color4{uni.v[pos], uni.v[pos+1], uni.v[pos+2], uni.v[pos+3]}
 }
 
+// SetPos sets the value at the specified position in the uniform array.
+func (uni *Uniform4fv) SetPos(pos int, v float32) {
+
+	uni.v[pos] = v
+}
+
+// GetPos gets the value at the specified position in the uniform array.
+func (uni *Uniform4fv) GetPos(pos int) float32 {
+
+	return uni.v[pos]
+}
+
 // Transfer transfers the current values of this uniform to the current shader program
 func (uni *Uniform4fv) Transfer(gl *GLS) {
 

+ 1 - 0
gui/chart.go

@@ -711,6 +711,7 @@ func (cm *chartMaterial) Init(color *math32.Color) {
 
 	cm.Material.Init()
 	cm.SetShader("shaderChart")
+	cm.SetShaderUnique(true)
 
 	// Creates uniforms and adds to material
 	cm.color = gls.NewUniform3f("MatColor")

+ 12 - 2
gui/panel.go

@@ -87,6 +87,7 @@ const (
 	idxBorderColor  = 4              // index of uniform array for border color
 	idxPaddingColor = 5              // index of uniform array for padding color
 	idxContentColor = 6              // index of uniform array for content color
+	posTextureValid = 7 * 4          // position of uniform array for texture valid
 )
 
 // NewPanel creates and returns a pointer to a new panel with the
@@ -128,6 +129,7 @@ func (p *Panel) Initialize(width, height float32) {
 	// Initialize material
 	p.mat = material.NewMaterial()
 	p.mat.SetShader("shaderPanel")
+	p.mat.SetShaderUnique(true)
 
 	// Initialize graphic
 	p.Graphic = graphic.NewGraphic(geom, gls.TRIANGLES)
@@ -135,7 +137,7 @@ func (p *Panel) Initialize(width, height float32) {
 
 	// Initialize uniforms
 	p.modelMatrixUni.Init("ModelMatrix")
-	p.panUni.Init("Panel", 7)
+	p.panUni.Init("Panel", 8)
 
 	// Set defaults
 	p.panUni.Set(idxBorderColor, 0, 0, 0, 1)
@@ -153,7 +155,7 @@ func (p *Panel) InitializeGraphic(width, height float32, gr *graphic.Graphic) {
 
 	// Initializes uniforms
 	p.modelMatrixUni.Init("ModelMatrix")
-	p.panUni.Init("Panel", 7)
+	p.panUni.Init("Panel", 8)
 
 	// Set defaults
 	p.panUni.Set(idxBorderColor, 0, 0, 0, 1)
@@ -849,6 +851,14 @@ func (p *Panel) resize(width, height float32) {
 // RenderSetup is called by the Engine before drawing the object
 func (p *Panel) RenderSetup(gl *gls.GLS, rinfo *core.RenderInfo) {
 
+	// Sets texture valid flag in uniforms
+	// depending if the material has texture
+	if p.mat.TextureCount() > 0 {
+		p.panUni.SetPos(posTextureValid, 1)
+	} else {
+		p.panUni.SetPos(posTextureValid, 0)
+	}
+
 	// Sets model matrix
 	var mm math32.Matrix4
 	p.SetModelMatrix(gl, &mm)

+ 0 - 34
light/spot.go

@@ -16,14 +16,6 @@ type Spot struct {
 	intensity float32         // Light intensity
 	direction math32.Vector3  // Direction in world coordinates
 	uni       *gls.Uniform3fv // Uniform with spot light properties
-
-	//uColor          gls.Uniform3f // Uniform for light color
-	//uPosition       gls.Uniform3f // Uniform for position in camera coordinates
-	//uDirection      gls.Uniform3f // Uniform for direction in camera coordinates
-	//uAngularDecay   gls.Uniform1f // Uniform for angular attenuation exponent
-	//uCutoffAngle    gls.Uniform1f // Uniform for cutoff angle from 0 to 90 degrees
-	//uLinearDecay    gls.Uniform1f // Uniform for linear distance decay
-	//uQuadraticDecay gls.Uniform1f // Uniform for quadratic distance decay
 }
 
 const (
@@ -54,22 +46,6 @@ func NewSpot(color *math32.Color, intensity float32) *Spot {
 	sl.SetLinearDecay(1.0)
 	sl.SetQuadraticDecay(1.0)
 
-	//	// Creates uniforms
-	//	sp.uColor.Init("SpotLightColor")
-	//	sp.uPosition.Init("SpotLightPosition")
-	//	sp.uDirection.Init("SpotLightDirection")
-	//	sp.uAngularDecay.Init("SpotLightAngularDecay")
-	//	sp.uCutoffAngle.Init("SpotLightCutoffAngle")
-	//	sp.uLinearDecay.Init("SpotLightLinearDecay")
-	//	sp.uQuadraticDecay.Init("SpotQuadraticDecay")
-	//
-	//	// Set initial values
-	//	sp.intensity = intensity
-	//	sp.SetColor(color)
-	//	sp.uAngularDecay.Set(15.0)
-	//	sp.uCutoffAngle.Set(45.0)
-	//	sp.uLinearDecay.Set(1.0)
-	//	sp.uQuadraticDecay.Set(1.0)
 	return sl
 }
 
@@ -166,28 +142,18 @@ func (sl *Spot) QuadraticDecay() float32 {
 // RenderSetup is called by the engine before rendering the scene
 func (sl *Spot) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	//sl.uColor.TransferIdx(gs, idx)
-	//sl.uAngularDecay.TransferIdx(gs, idx)
-	//sl.uCutoffAngle.TransferIdx(gs, idx)
-	//sl.uLinearDecay.TransferIdx(gs, idx)
-	//sl.uQuadraticDecay.TransferIdx(gs, idx)
-
 	// Calculates and updates light position uniform in camera coordinates
 	var pos math32.Vector3
 	sl.WorldPosition(&pos)
 	var pos4 math32.Vector4
 	pos4.SetVector3(&pos, 1.0)
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
-	//sl.uPosition.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	//sl.uPosition.TransferIdx(gs, idx)
 	sl.uni.SetVector3(sPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
 
 	// Calculates and updates light direction uniform in camera coordinates
 	pos4.SetVector3(&sl.direction, 0.0)
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
 	// Normalize here ??
-	//sl.uDirection.SetVector3(&math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-	//sl.uDirection.TransferIdx(gs, idx)
 	sl.uni.SetVector3(sDirection, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
 
 	// Transfer uniform

+ 17 - 1
material/material.go

@@ -57,7 +57,8 @@ type IMaterial interface {
 type Material struct {
 	refcount         int                  // Current number of references
 	shader           string               // Shader name
-	uselights        UseLights            // Use lights bit mask
+	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
 	wireframe        bool                 // show as wirefrme
 	depthMask        bool                 // Enable writing into the depth buffer
@@ -144,6 +145,20 @@ func (mat *Material) Shader() string {
 	return mat.shader
 }
 
+// SetShaderUnique sets indication that this material shader is unique and
+// does not depend on the number of lights in the scene and/or the
+// number of textures in the material.
+func (mat *Material) SetShaderUnique(unique bool) {
+
+	mat.shaderUnique = unique
+}
+
+// ShaderUnique returns this material shader is unique.
+func (mat *Material) ShaderUnique() bool {
+
+	return mat.shaderUnique
+}
+
 // SetUseLights sets the material use lights bit mask specifying which
 // light types will be used when rendering the material
 // By default the material will use all lights
@@ -152,6 +167,7 @@ func (mat *Material) SetUseLights(lights UseLights) {
 	mat.uselights = lights
 }
 
+// UseLights returns the current use lights bitmask
 func (mat *Material) UseLights() UseLights {
 
 	return mat.uselights

+ 1 - 0
renderer/renderer.go

@@ -154,6 +154,7 @@ func (r *Renderer) Render(iscene core.INode, icam camera.ICamera) error {
 
 		// Sets the shader specs for this material and sets shader program
 		r.specs.Name = mat.Shader()
+		r.specs.ShaderUnique = mat.ShaderUnique()
 		r.specs.UseLights = mat.UseLights()
 		r.specs.MatTexturesMax = mat.TextureCount()
 		_, err := r.shaman.SetProgram(&r.specs)

+ 30 - 21
renderer/shader/shaderPanel.go

@@ -45,20 +45,29 @@ void main() {
 const shaderPanelFrag = `
 #version {{.Version}}
 
-{{template "material" .}}
+// Textures uniforms
+uniform sampler2D	MatTexture[1];
+uniform mat3		MatTexinfo[1];
+
+// Macros to access elements inside MatTexinfo uniform
+#define MatTexOffset(a)		MatTexinfo[a][0].xy
+#define MatTexRepeat(a)		MatTexinfo[a][1].xy
+#define MatTexFlipY(a)		bool(MatTexinfo[a][2].x)
+#define MatTexVisible(a)	bool(MatTexinfo[a][2].y)
 
 // Inputs from vertex shader
 in vec2 FragTexcoord;
 
 // Input uniform
-uniform vec4 Panel[7];
-const int bounds		= 0;              // index of uniform array for bounds coordinates
-const int border		= 1;              // index of uniform array for border coordinates
-const int padding		= 2;              // index of uniform array for padding coordinates
-const int content		= 3;              // index of uniform array for content coordinates
-const int borderColor  	= 4;              // index of uniform array for border color
-const int paddingColor 	= 5;              // index of uniform array for padding color
-const int contentColor	= 6;              // index of uniform array for content color
+uniform vec4 Panel[8];
+#define Bounds			Panel[0]		  // panel bounds in texture coordinates
+#define Border			Panel[1]		  // panel border in texture coordinates
+#define Padding			Panel[2]		  // panel padding in texture coordinates
+#define Content			Panel[3]		  // panel content area in texture coordinates
+#define BorderColor		Panel[4]		  // panel border color
+#define PaddingColor	Panel[5]		  // panel padding color
+#define ContentColor	Panel[6]		  // panel content color
+#define TextureValid	bool(Panel[7].x)  // texture valid flag
 
 // Output
 out vec4 FragColor;
@@ -97,24 +106,24 @@ void main() {
     // Bounds[1] - ymin
     // Bounds[2] - xmax
     // Bounds[3] - ymax
-    if (FragTexcoord.x <= Panel[bounds][0] || FragTexcoord.x >= Panel[bounds][2]) {
+    if (FragTexcoord.x <= Bounds[0] || FragTexcoord.x >= Bounds[2]) {
         discard;
     }
-    if (FragTexcoord.y <= Panel[bounds][1] || FragTexcoord.y >= Panel[bounds][3]) {
+    if (FragTexcoord.y <= Bounds[1] || FragTexcoord.y >= Bounds[3]) {
         discard;
     }
 
     // Check if fragment is inside content area
-    if (checkRect(Panel[content])) {
+    if (checkRect(Content)) {
         // If no texture, the color will be the material color.
-        vec4 color = Panel[contentColor];
-        {{ if .MatTexturesMax }}
+        vec4 color = ContentColor;
+		if (TextureValid) {
             // Adjust texture coordinates to fit texture inside the content area
-            vec2 offset = vec2(-Panel[content][0], -Panel[content][1]);
-            vec2 factor = vec2(1/Panel[content][2], 1/Panel[content][3]);
+            vec2 offset = vec2(-Content[0], -Content[1]);
+            vec2 factor = vec2(1/Content[2], 1/Content[3]);
             vec2 texcoord = (FragTexcoord + offset) * factor;
             color = texture(MatTexture[0], texcoord * MatTexRepeat(0) + MatTexOffset(0));
-        {{ end }}
+		}
         if (color.a == 0) {
             discard;
         }
@@ -123,14 +132,14 @@ void main() {
     }
 
     // Checks if fragment is inside paddings area
-    if (checkRect(Panel[padding])) {
-        FragColor = Panel[paddingColor];
+    if (checkRect(Padding)) {
+        FragColor = PaddingColor;
         return;
     }
 
     // Checks if fragment is inside borders area
-    if (checkRect(Panel[border])) {
-        FragColor = Panel[borderColor];
+    if (checkRect(Border)) {
+        FragColor = BorderColor;
         return;
     }
 

+ 9 - 2
renderer/shaman.go

@@ -17,6 +17,7 @@ import (
 type ShaderSpecs struct {
 	Name             string             // Shader name
 	Version          string             // GLSL version
+	ShaderUnique     bool               // indicates if shader is independent of lights and textures
 	UseLights        material.UseLights // Bitmask indicating which lights to consider
 	AmbientLightsMax int                // Current number of ambient lights
 	DirLightsMax     int                // Current Number of directional lights
@@ -222,10 +223,16 @@ func (sm *Shaman) GenProgram(specs *ShaderSpecs) (*gls.Program, error) {
 	return prog, nil
 }
 
+// Compare compares two shaders specifications structures
 func (ss *ShaderSpecs) Compare(other *ShaderSpecs) bool {
 
-	if ss.Name == other.Name &&
-		ss.AmbientLightsMax == other.AmbientLightsMax &&
+	if ss.Name != other.Name {
+		return false
+	}
+	if other.ShaderUnique {
+		return true
+	}
+	if ss.AmbientLightsMax == other.AmbientLightsMax &&
 		ss.DirLightsMax == other.DirLightsMax &&
 		ss.PointLightsMax == other.PointLightsMax &&
 		ss.SpotLightsMax == other.SpotLightsMax &&

+ 0 - 28
texture/texture2D.go

@@ -34,12 +34,6 @@ type Texture2D struct {
 	data         interface{}         // array with texture data
 	uTexture     gls.Uniform1i       // Texture unit uniform
 	uTexinfo     gls.UniformMatrix3f // uniform 3x3 array with texture info
-
-	//uTexture     gls.Uniform1i // Texture unit uniform
-	//uFlipY       gls.Uniform1i // Flip Y coordinate flag uniform
-	//uVisible     gls.Uniform1i // Texture visible uniform
-	//uOffset      gls.Uniform2f // Texture offset uniform
-	//uRepeat      gls.Uniform2f // Texture repeat uniform
 }
 
 const (
@@ -75,15 +69,6 @@ func newTexture2D() *Texture2D {
 	t.uTexinfo.Set(iFlipY, 1)
 	t.uTexinfo.Set(iVisible, 1)
 
-	//t.uFlipY.Init("MatTexFlipY")
-	//t.uVisible.Init("MatTexVisible")
-	//t.uOffset.Init("MatTexOffset")
-	//t.uRepeat.Init("MatTexRepeat")
-	//t.uRepeat.Set(1, 1)
-	//t.uOffset.Set(0, 0)
-	//t.uVisible.Set(1)
-	//t.uFlipY.Set(1)
-
 	return t
 }
 
@@ -238,14 +223,12 @@ func (t *Texture2D) SetRepeat(x, y float32) {
 
 	t.uTexinfo.Set(iRepeatX, x)
 	t.uTexinfo.Set(iRepeatY, y)
-	//t.uRepeat.Set(x, y)
 }
 
 // Repeat returns the current X and Y repeat factors
 func (t *Texture2D) Repeat() (float32, float32) {
 
 	return t.uTexinfo.Get(iRepeatX), t.uTexinfo.Get(iRepeatY)
-	//return t.uRepeat.Get()
 }
 
 // SetOffset sets the offset factor
@@ -253,14 +236,12 @@ func (t *Texture2D) SetOffset(x, y float32) {
 
 	t.uTexinfo.Set(iOffsetX, x)
 	t.uTexinfo.Set(iOffsetY, y)
-	//t.uOffset.Set(x, y)
 }
 
 // Offset returns the current X and Y offset factors
 func (t *Texture2D) Offset() (float32, float32) {
 
 	return t.uTexinfo.Get(iOffsetX), t.uTexinfo.Get(iOffsetY)
-	//return t.uOffset.Get()
 }
 
 // SetFlipY set the state for flipping the Y coordinate
@@ -268,10 +249,8 @@ func (t *Texture2D) SetFlipY(state bool) {
 
 	if state {
 		t.uTexinfo.Set(iFlipY, 1)
-		//t.uFlipY.Set(1)
 	} else {
 		t.uTexinfo.Set(iFlipY, 0)
-		//t.uFlipY.Set(0)
 	}
 }
 
@@ -363,11 +342,4 @@ func (t *Texture2D) RenderSetup(gs *gls.GLS, idx int) {
 	t.uTexture.Set(int32(idx))
 	t.uTexture.TransferIdx(gs, idx)
 	t.uTexinfo.TransferIdx(gs, idx)
-
-	//	t.uTexture.Set(int32(idx))
-	//	t.uTexture.TransferIdx(gs, idx)
-	//	t.uFlipY.TransferIdx(gs, idx)
-	//	t.uVisible.TransferIdx(gs, idx)
-	//	t.uOffset.TransferIdx(gs, idx)
-	//	t.uRepeat.TransferIdx(gs, idx)
 }