commit e273ad0ac66480f6fb58a1ff0fc3cbc917e21025
parent f6639e8a819091d515edf063f94ab061991e280b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 23 Oct 2024 10:03:52 +0900
set textures using uniform name
Diffstat:
4 files changed, 57 insertions(+), 20 deletions(-)
diff --git a/cmd/sample/fragment.glsl b/cmd/sample/fragment.glsl
@@ -1,9 +1,10 @@
#version 330 core
in vec3 vcol;
in vec2 texCoord;
-uniform sampler2D tex;
+uniform sampler2D texture1;
+uniform sampler2D texture2;
out vec4 fcol;
void main() {
- fcol = texture(tex, texCoord);
+ fcol = mix(texture(texture1, texCoord), texture(texture2, texCoord), 0.5);
}
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -85,7 +85,8 @@ func main() {
}
vpath := filepath.Join(filepath.Dir(f), "vertex.glsl")
fpath := filepath.Join(filepath.Dir(f), "fragment.glsl")
- texpath := filepath.Join(filepath.Dir(f), "container.jpg")
+ texpath1 := filepath.Join(filepath.Dir(f), "container.jpg")
+ texpath2 := filepath.Join(filepath.Dir(f), "awesomeface.png")
object.Load()
@@ -94,12 +95,24 @@ func main() {
log.Fatalf("create shader: %v", err)
}
- texture, err := draw.NewTexture(texpath)
+ texture1, err := draw.NewTexture(texpath1)
if err != nil {
- log.Fatalf("create texture: %v")
+ log.Fatalf("create texture: %v", err)
+ }
+ if err := shader.SetTexture(texture1, "texture1"); err != nil {
+ log.Fatalf("set texture: %v", err)
+ }
+
+ texture2, err := draw.NewTexture(texpath2)
+ if err != nil {
+ log.Fatalf("create texture: %v", err)
+ }
+ if err := shader.SetTexture(texture2, "texture2"); err != nil {
+ log.Fatalf("set texture: %v", err)
}
- _ = texture
+ texture1.Bind()
+ texture2.Bind()
shader.Use()
window.SetFramebufferSizeCallback(framebufferSizeCallback)
diff --git a/shader.go b/shader.go
@@ -59,6 +59,7 @@ func linkShaders(vsID, fsID uint32) (shaderID uint32, err error) {
type Shader struct {
id uint32
+ nextTextureId int32
}
// NewShader creates a shader program from a vertex shader source file specified by vpath and
@@ -95,4 +96,15 @@ func (s *Shader) SetFloat32(name string, val float32) error {
}
gl.Uniform1f(l, val)
return nil
+}
+
+func (s *Shader) SetTexture(t *Texture, name string) error {
+ s.Use()
+ l := gl.GetUniformLocation(s.id, gl.Str(name + "\x00"))
+ if l == -1 {
+ return fmt.Errorf("no such uniform: %s", name)
+ }
+ gl.Uniform1i(l, s.nextTextureId)
+ s.nextTextureId++
+ return nil
}
\ No newline at end of file
diff --git a/texture.go b/texture.go
@@ -5,15 +5,32 @@ import (
"image"
idraw "image/draw"
_ "image/jpeg"
+ _ "image/png"
"os"
"github.com/go-gl/gl/v3.3-core/gl"
)
+func loadImage(name string) (image.Image, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, fmt.Errorf("open: %v", err)
+ }
+ defer f.Close()
+ img, _, err := image.Decode(f)
+ if err != nil {
+ return nil, fmt.Errorf("decode image %s: %v", name, err)
+ }
+ return img, nil
+}
+
type Texture struct {
id uint32
+ unit uint32
}
+var nextUnit uint32 = gl.TEXTURE0
+
func NewTexture(name string) (*Texture, error) {
var id uint32
gl.GenTextures(1, &id)
@@ -31,22 +48,16 @@ func NewTexture(name string) (*Texture, error) {
if rgba.Stride != rgba.Rect.Dx()*4 {
return nil, fmt.Errorf("data should be packed dense")
}
- gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
+ gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
+ int32(rgba.Rect.Dx()), int32(rgba.Rect.Dy()), 0,
gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix))
gl.GenerateMipmap(gl.TEXTURE_2D)
- return &Texture{id: id}, nil
+ unit := nextUnit
+ nextUnit++
+ return &Texture{id: id, unit: unit}, nil
}
-
-func loadImage(name string) (image.Image, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, fmt.Errorf("open: %v", err)
- }
- defer f.Close()
- img, _, err := image.Decode(f)
- if err != nil {
- return nil, fmt.Errorf("decode image %s: %v", name, err)
- }
- return img, nil
+func (t *Texture) Bind() {
+ gl.ActiveTexture(t.unit)
+ gl.BindTexture(gl.TEXTURE_2D, t.id)
}