Quellcode durchsuchen

changing uniform transfers...

leonsal vor 8 Jahren
Ursprung
Commit
796cb8fb30
6 geänderte Dateien mit 134 neuen und 73 gelöschten Zeilen
  1. 6 0
      gls/gls.go
  2. 53 0
      gls/uniform.go
  3. 9 14
      light/ambient.go
  4. 26 21
      light/directional.go
  5. 8 8
      material/point.go
  6. 32 30
      material/standard.go

+ 6 - 0
gls/gls.go

@@ -595,6 +595,12 @@ func (gs *GLS) Uniform3fv(location int32, count int32, v []float32) {
 	gs.stats.Unisets++
 }
 
+func (gs *GLS) Uniform3fvUP(location int32, count int32, v unsafe.Pointer) {
+
+	C.glUniform3fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(v))
+	gs.stats.Unisets++
+}
+
 func (gs *GLS) Uniform4fv(location int32, count int32, v []float32) {
 
 	C.glUniform4fv(C.GLint(location), C.GLsizei(count), (*C.GLfloat)(&v[0]))

+ 53 - 0
gls/uniform.go

@@ -9,6 +9,59 @@ import (
 	"github.com/g3n/engine/math32"
 )
 
+type Uniform2 struct {
+	name      string // base name
+	nameIdx   string // cached indexed name
+	handle    uint32 // program handle
+	location  int32  // last cached location
+	lastIndex int32  // last index
+}
+
+// Init initializes this uniform and sets its name
+func (u *Uniform2) Init(name string) {
+
+	u.name = name
+	u.handle = 0     // invalid program handle
+	u.location = -1  // invalid location
+	u.lastIndex = -1 // invalid index
+}
+
+// Location returns the location of this uniform for
+// the current shader program
+// The returned location can be -1 if not found
+func (u *Uniform2) Location(gs *GLS) int32 {
+
+	handle := gs.prog.Handle()
+	if handle != u.handle {
+		u.location = gs.prog.GetUniformLocation(u.name)
+		u.handle = handle
+		log.Error("Uniform:%s location:%v", u.name, u.location)
+	}
+	return u.location
+}
+
+// LocationIdx returns the location of this indexed uniform for
+// the current shader program
+// The returned location can be -1 if not found
+func (u *Uniform2) LocationIdx(gs *GLS, idx int32) int32 {
+
+	if idx != u.lastIndex {
+		u.nameIdx = fmt.Sprintf("%s[%d]", u.name, idx)
+		u.lastIndex = idx
+		u.handle = 0
+		log.Error("Uniform:%s rebuild nameIdx", u.nameIdx)
+	}
+	handle := gs.prog.Handle()
+	if handle != u.handle {
+		u.location = gs.prog.GetUniformLocation(u.nameIdx)
+		u.handle = handle
+		log.Error("Uniform:%s location:%v", u.nameIdx, u.location)
+	}
+	return u.location
+}
+
+// ----------------------------------------------------------------------
+
 //
 // Type Uniform is the type for all uniforms
 //

+ 9 - 14
light/ambient.go

@@ -11,10 +11,10 @@ import (
 )
 
 type Ambient struct {
-	core.Node               // Embedded node
-	color     math32.Color  // Light color
-	intensity float32       // Light intensity
-	uColor    gls.Uniform3f // Light color uniform (color * intensity)
+	core.Node              // Embedded node
+	color     math32.Color // Light color
+	intensity float32      // Light intensity
+	uni       gls.Uniform2 // Uniform location cache
 }
 
 // NewAmbient returns a pointer to a new ambient color with the specified
@@ -23,11 +23,9 @@ func NewAmbient(color *math32.Color, intensity float32) *Ambient {
 
 	la := new(Ambient)
 	la.Node.Init()
-
 	la.color = *color
 	la.intensity = intensity
-	la.uColor.Init("AmbientLightColor")
-	la.SetColor(color)
+	la.uni.Init("AmbientLightColor")
 	return la
 }
 
@@ -35,9 +33,6 @@ func NewAmbient(color *math32.Color, intensity float32) *Ambient {
 func (la *Ambient) SetColor(color *math32.Color) {
 
 	la.color = *color
-	tmpColor := la.color
-	tmpColor.MultiplyScalar(la.intensity)
-	la.uColor.SetColor(&tmpColor)
 }
 
 // Color returns the current color of this light
@@ -50,9 +45,6 @@ func (la *Ambient) Color() math32.Color {
 func (la *Ambient) SetIntensity(intensity float32) {
 
 	la.intensity = intensity
-	tmpColor := la.color
-	tmpColor.MultiplyScalar(la.intensity)
-	la.uColor.SetColor(&tmpColor)
 }
 
 // Intensity returns the current intensity of this light
@@ -64,5 +56,8 @@ func (la *Ambient) Intensity() float32 {
 // RenderSetup is called by the engine before rendering the scene
 func (la *Ambient) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	la.uColor.TransferIdx(gs, idx)
+	color := la.color
+	color.MultiplyScalar(la.intensity)
+	location := la.uni.Location(gs)
+	gs.Uniform3f(location, color.R, color.G, color.B)
 }

+ 26 - 21
light/directional.go

@@ -5,23 +5,26 @@
 package light
 
 import (
+	"unsafe"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
 )
 
 type Directional struct {
-	core.Node                 // Embedded node
-	color     math32.Color    // Light color
-	intensity float32         // Light intensity
-	uni       *gls.Uniform3fv // uniform with light color and direction
+	core.Node              // Embedded node
+	color     math32.Color // Light color
+	intensity float32      // Light intensity
+	uni       gls.Uniform2 // Uniform location cache
+	udata     struct {     // Combined uniform data in 2 vec3:
+		color    math32.Color   // Light color
+		position math32.Vector3 // Light position
+	}
 }
 
-const (
-	dirColor    = 0 // index of color triplet in uniform
-	dirPosition = 1 // index of position vector in uniform
-	dirUniSize  = 2 // uniform count of 3 float32
-)
+// Number of glsl shader vec3 elements used by uniform data
+const udataVec3 = 2
 
 // NewDirectional creates and returns a pointer of a new directional light
 // the specified color and intensity.
@@ -32,7 +35,7 @@ func NewDirectional(color *math32.Color, intensity float32) *Directional {
 
 	ld.color = *color
 	ld.intensity = intensity
-	ld.uni = gls.NewUniform3fv("DirLight", dirUniSize)
+	ld.uni.Init("DirLight")
 	ld.SetColor(color)
 	return ld
 }
@@ -41,9 +44,8 @@ func NewDirectional(color *math32.Color, intensity float32) *Directional {
 func (ld *Directional) SetColor(color *math32.Color) {
 
 	ld.color = *color
-	tmpColor := ld.color
-	tmpColor.MultiplyScalar(ld.intensity)
-	ld.uni.SetColor(dirColor, &tmpColor)
+	ld.udata.color = ld.color
+	ld.udata.color.MultiplyScalar(ld.intensity)
 }
 
 // Color returns the current color of this light
@@ -56,9 +58,8 @@ func (ld *Directional) Color() math32.Color {
 func (ld *Directional) SetIntensity(intensity float32) {
 
 	ld.intensity = intensity
-	tmpColor := ld.color
-	tmpColor.MultiplyScalar(ld.intensity)
-	ld.uni.SetColor(dirColor, &tmpColor)
+	ld.udata.color = ld.color
+	ld.udata.color.MultiplyScalar(ld.intensity)
 }
 
 // Intensity returns the current intensity of this light
@@ -70,13 +71,17 @@ func (ld *Directional) Intensity() float32 {
 // RenderSetup is called by the engine before rendering the scene
 func (ld *Directional) RenderSetup(gs *gls.GLS, rinfo *core.RenderInfo, idx int) {
 
-	// Calculates and updates light direction uniform in camera coordinates
+	// Calculates light position in camera coordinates and updates uniform
 	var pos math32.Vector3
 	ld.WorldPosition(&pos)
 	pos4 := math32.Vector4{pos.X, pos.Y, pos.Z, 0.0}
 	pos4.ApplyMatrix4(&rinfo.ViewMatrix)
-	ld.uni.SetVector3(dirPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
-
-	// Transfer color and position uniform
-	ld.uni.TransferIdx(gs, idx*dirUniSize)
+	//ld.uni.SetVector3(dirPosition, &math32.Vector3{pos4.X, pos4.Y, pos4.Z})
+	ld.udata.position.X = pos4.X
+	ld.udata.position.Y = pos4.Y
+	ld.udata.position.Z = pos4.Z
+
+	// Transfer uniform data
+	location := ld.uni.LocationIdx(gs, int32(idx))
+	gs.Uniform3fvUP(location, udataVec3, unsafe.Pointer(&ld.udata))
 }

+ 8 - 8
material/point.go

@@ -21,9 +21,9 @@ func NewPoint(color *math32.Color) *Point {
 	pm.Standard.Init("point", color)
 
 	// Sets uniform's initial values
-	pm.uni.SetColor(vEmissive, color)
-	pm.uni.SetPos(pSize, 1.0)
-	pm.uni.SetPos(pRotationZ, 0)
+	pm.udata.emissive = *color
+	pm.udata.psize = 1.0
+	pm.udata.protationZ = 0
 	return pm
 }
 
@@ -31,25 +31,25 @@ func NewPoint(color *math32.Color) *Point {
 // The default is {0,0,0}
 func (pm *Point) SetEmissiveColor(color *math32.Color) {
 
-	pm.uni.SetColor(vEmissive, color)
+	pm.udata.emissive = *color
 }
 
 // SetSize sets the point size
 func (pm *Point) SetSize(size float32) {
 
-	pm.uni.SetPos(pSize, size)
+	pm.udata.psize = size
 }
 
 // SetRotationZ sets the point rotation around the Z axis.
 func (pm *Point) SetRotationZ(rot float32) {
 
-	pm.uni.SetPos(pRotationZ, rot)
+	pm.udata.protationZ = rot
 }
 
 // RenderSetup is called by the engine before drawing the object
 // which uses this material
 func (pm *Point) RenderSetup(gs *gls.GLS) {
 
-	pm.Material.RenderSetup(gs)
-	pm.uni.Transfer(gs)
+	//	pm.Material.RenderSetup(gs)
+	//	pm.uni.Transfer(gs)
 }

+ 32 - 30
material/standard.go

@@ -7,27 +7,29 @@ package material
 import (
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
+	"unsafe"
 )
 
 // Standard material supports the classic lighting model with
 // ambient, diffuse, specular and emissive lights.
 // The lighting calculation is implemented in the vertex shader.
 type Standard struct {
-	Material                 // Embedded material
-	uni      *gls.Uniform3fv // Uniform array of 3 floats with material properties
+	Material              // Embedded material
+	uni      gls.Uniform2 // Uniform location cache
+	udata    struct {     // Combined uniform data in 6 vec3:
+		ambient    math32.Color // Ambient color reflectivity
+		diffuse    math32.Color // Diffuse color reflectivity
+		specular   math32.Color // Specular color reflectivity
+		emissive   math32.Color // Emissive color
+		shininess  float32      // Specular shininess factor
+		opacity    float32      // Opacity
+		psize      float32      // Point size
+		protationZ float32      // Point rotation around Z axis
+	}
 }
 
-const (
-	vAmbient   = 0              // index for Ambient color in uniform array
-	vDiffuse   = 1              // index for Diffuse color in uniform array
-	vSpecular  = 2              // index for Specular color in uniform array
-	vEmissive  = 3              // index for Emissive color in uniform array
-	pShininess = vEmissive * 4  // position for material shininess in uniform array
-	pOpacity   = pShininess + 1 // position for material opacity in uniform array
-	pSize      = pOpacity + 1   // position for material point size
-	pRotationZ = pSize + 1      // position for material point rotation
-	uniSize    = 6              // total count of groups 3 floats in uniform
-)
+// Number of glsl shader vec3 elements used by uniform data
+const udataVec3 = 6
 
 // NewStandard creates and returns a pointer to a new standard material
 func NewStandard(color *math32.Color) *Standard {
@@ -45,66 +47,65 @@ func (ms *Standard) Init(shader string, color *math32.Color) {
 	ms.SetShader(shader)
 
 	// Creates uniforms and set initial values
-	ms.uni = gls.NewUniform3fv("Material", uniSize)
-	ms.uni.SetColor(vAmbient, color)
-	ms.uni.SetColor(vDiffuse, color)
-	ms.uni.Set(vSpecular, 0.5, 0.5, 0.5)
-	ms.uni.Set(vEmissive, 0, 0, 0)
-	ms.uni.SetPos(pShininess, 30.0)
-	ms.uni.SetPos(pOpacity, 1.0)
+	ms.uni.Init("Material")
+	ms.SetColor(color)
+	ms.SetSpecularColor(&math32.Color{0.5, 0.5, 0.5})
+	ms.SetEmissiveColor(&math32.Color{0, 0, 0})
+	ms.SetShininess(30.0)
+	ms.SetOpacity(1.0)
 }
 
 // AmbientColor returns the material ambient color reflectivity.
 func (ms *Standard) AmbientColor() math32.Color {
 
-	return ms.uni.GetColor(vAmbient)
+	return ms.udata.ambient
 }
 
 // SetAmbientColor sets the material ambient color reflectivity.
 // The default is the same as the diffuse color
 func (ms *Standard) SetAmbientColor(color *math32.Color) {
 
-	ms.uni.SetColor(vAmbient, color)
+	ms.udata.ambient = *color
 }
 
 // SetColor sets the material diffuse color and also the
 // material ambient color reflectivity
 func (ms *Standard) SetColor(color *math32.Color) {
 
-	ms.uni.SetColor(vDiffuse, color)
-	ms.uni.SetColor(vAmbient, color)
+	ms.udata.diffuse = *color
+	ms.udata.ambient = *color
 }
 
 // SetEmissiveColor sets the material emissive color
 // The default is {0,0,0}
 func (ms *Standard) SetEmissiveColor(color *math32.Color) {
 
-	ms.uni.SetColor(vEmissive, color)
+	ms.udata.emissive = *color
 }
 
 // EmissiveColor returns the material current emissive color
 func (ms *Standard) EmissiveColor() math32.Color {
 
-	return ms.uni.GetColor(vEmissive)
+	return ms.udata.emissive
 }
 
 // SetSpecularColor sets the material specular color reflectivity.
 // The default is {0.5, 0.5, 0.5}
 func (ms *Standard) SetSpecularColor(color *math32.Color) {
 
-	ms.uni.SetColor(vSpecular, color)
+	ms.udata.specular = *color
 }
 
 // SetShininess sets the specular highlight factor. Default is 30.
 func (ms *Standard) SetShininess(shininess float32) {
 
-	ms.uni.SetPos(pShininess, shininess)
+	ms.udata.shininess = shininess
 }
 
 // SetOpacity sets the material opacity (alpha). Default is 1.0.
 func (ms *Standard) SetOpacity(opacity float32) {
 
-	ms.uni.SetPos(pOpacity, opacity)
+	ms.udata.opacity = opacity
 }
 
 // RenderSetup is called by the engine before drawing the object
@@ -112,5 +113,6 @@ func (ms *Standard) SetOpacity(opacity float32) {
 func (ms *Standard) RenderSetup(gs *gls.GLS) {
 
 	ms.Material.RenderSetup(gs)
-	ms.uni.Transfer(gs)
+	location := ms.uni.Location(gs)
+	gs.Uniform3fvUP(location, udataVec3, unsafe.Pointer(&ms.udata))
 }