tofu

Making something with OpenGL in Go
Log | Files | Refs

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:
Mcmd/sample/fragment.glsl | 5+++--
Mcmd/sample/main.go | 21+++++++++++++++++----
Mshader.go | 12++++++++++++
Mtexture.go | 39+++++++++++++++++++++++++--------------
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) }