111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
|
package material
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"os"
|
||
|
|
||
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/asset"
|
||
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/shader"
|
||
|
"git.tek.govt.hu/dowerx/opengl-deferred/types/texture"
|
||
|
"github.com/go-gl/gl/v4.6-core/gl"
|
||
|
"gopkg.in/yaml.v3"
|
||
|
)
|
||
|
|
||
|
type MaterialDefiniton struct {
|
||
|
Shader string `yaml:"shader"`
|
||
|
Textures []struct {
|
||
|
Slot uint32 `yaml:"slot"`
|
||
|
Texture string `yaml:"texture"`
|
||
|
} `yaml:"textures"`
|
||
|
Values []struct {
|
||
|
Type string `yaml:"type"`
|
||
|
Name string `yaml:"name"`
|
||
|
Value interface{} `yaml:"value"`
|
||
|
} `yaml:"values"`
|
||
|
}
|
||
|
|
||
|
type Material struct {
|
||
|
Shader *shader.Shader
|
||
|
ShaderName string
|
||
|
Textures []struct {
|
||
|
Slot uint32
|
||
|
Texture *texture.Texture
|
||
|
TextureName string
|
||
|
}
|
||
|
Values []Value
|
||
|
}
|
||
|
|
||
|
func (m Material) Delete() {}
|
||
|
|
||
|
func (m *Material) Apply() {
|
||
|
m.Shader.Use()
|
||
|
|
||
|
for _, t := range m.Textures {
|
||
|
t.Texture.Bind(gl.TEXTURE0 + t.Slot)
|
||
|
}
|
||
|
|
||
|
for _, v := range m.Values {
|
||
|
v.Apply(m.Shader)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Load(path string, assets map[string]asset.Asset) (Material, error) {
|
||
|
var definition MaterialDefiniton
|
||
|
var material Material
|
||
|
|
||
|
data, err := os.ReadFile(path)
|
||
|
if err != nil {
|
||
|
return material, err
|
||
|
}
|
||
|
|
||
|
if err = yaml.Unmarshal(data, &definition); err != nil {
|
||
|
return material, err
|
||
|
}
|
||
|
|
||
|
material.ShaderName = definition.Shader
|
||
|
for _, t := range definition.Textures {
|
||
|
material.Textures = append(material.Textures, struct {
|
||
|
Slot uint32
|
||
|
Texture *texture.Texture
|
||
|
TextureName string
|
||
|
}{Slot: t.Slot, TextureName: t.Texture})
|
||
|
}
|
||
|
|
||
|
for _, vdef := range definition.Values {
|
||
|
var value Value
|
||
|
|
||
|
switch vdef.Type {
|
||
|
case "int":
|
||
|
intval, ok := vdef.Value.(int32)
|
||
|
if !ok {
|
||
|
return material, err
|
||
|
}
|
||
|
value = IntValue{Name: vdef.Name, Value: intval}
|
||
|
default:
|
||
|
return material, errors.New("Unknown value: " + vdef.Type)
|
||
|
}
|
||
|
|
||
|
material.Values = append(material.Values, value)
|
||
|
}
|
||
|
|
||
|
return material, err
|
||
|
}
|
||
|
|
||
|
func (m *Material) AttachAssets(assets map[string]asset.Asset) error {
|
||
|
tmpShader, ok := assets[m.ShaderName].(shader.Shader)
|
||
|
if !ok {
|
||
|
return errors.New("Failed to attach shader to material: " + m.ShaderName)
|
||
|
}
|
||
|
m.Shader = &tmpShader
|
||
|
|
||
|
for i, t := range m.Textures {
|
||
|
tmpTexture, ok := assets[t.TextureName].(texture.Texture)
|
||
|
if !ok {
|
||
|
return errors.New("Failed to attach texture to material: " + t.TextureName)
|
||
|
}
|
||
|
m.Textures[i].Texture = &tmpTexture
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|