Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement min/mag texture filtering #76

Merged
merged 3 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions TextureFilters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package giu

// Texture filtering types.
const (
TextureFilterNearest = iota
TextureFilterLinear
TextureFilterNearestMipmapNearest
TextureFilterLinearMipmapNearest
TextureFilterNearestMipmapLinear
TextureFilterLinearMipmapLinear
)
Binary file added examples/texturefiltering/gopher-sprite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/texturefiltering/gopher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions examples/texturefiltering/texturefiltering.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
_ "image/jpeg"
_ "image/png"

g "github.com/AllenDang/giu"
)

var (
spriteTexture *g.Texture
largeTexture *g.Texture
)

func loop() {
g.SingleWindow("load image", g.Layout{
g.Group(g.Layout{
g.Label("15x20 pixel image"),
g.Line(
g.Group(g.Layout{
g.Label("50%"),
g.Image(spriteTexture, 8, 10),
}),
g.Group(g.Layout{
g.Label("100%"),
g.Image(spriteTexture, 15, 20),
}),
g.Group(g.Layout{
g.Label("800%"),
g.Image(spriteTexture, 120, 160),
}),
),
}),
g.Group(g.Layout{
g.Label("215x140 image"),
g.Line(
g.Group(g.Layout{
g.Label("50%"),
g.Image(largeTexture, 215/2, 140/2),
}),
g.Group(g.Layout{
g.Label("100%"),
g.Image(largeTexture, 215, 140),
}),
g.Group(g.Layout{
g.Label("200%"),
g.Image(largeTexture, 215*2, 140*2),
}),
),
}),
g.Line(
g.Button("Minify Filter Nearest", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterNearest)
}),
g.Button("Minify Filter Linear", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterLinear)
}),
/*g.Button("Nearest Mipmap Nearest", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterNearestMipmapNearest)
}),
g.Button("Linear Mipmap Nearest", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterLinearMipmapNearest)
}),
g.Button("Nearest Mipmap Linear", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterNearestMipmapLinear)
}),
g.Button("Linear Mipmap Linear", func() {
g.Context.GetRenderer().SetTextureMinFilter(g.TextureFilterLinearMipmapLinear)
}),*/
),
g.Line(
g.Button("Magnify Filter Nearest", func() {
g.Context.GetRenderer().SetTextureMagFilter(g.TextureFilterNearest)
}),
g.Button("Magnify Filter Linear", func() {
g.Context.GetRenderer().SetTextureMagFilter(g.TextureFilterLinear)
}),
),
})
}

func main() {
wnd := g.NewMasterWindow("Texture Filtering", 800, 600, g.MasterWindowFlagsNotResizable, nil)

spriteImg, _ := g.LoadImage("gopher-sprite.png")
largeImg, _ := g.LoadImage("gopher.png")
go func() {
spriteTexture, _ = g.NewTextureFromRgba(spriteImg)
largeTexture, _ = g.NewTextureFromRgba(largeImg)
}()

wnd.Main(loop)
}
4 changes: 4 additions & 0 deletions imgui/RendererInterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ type Renderer interface {
PreRender(clearColor [4]float32)
// Render draws the provided imgui draw data.
Render(displaySize [2]float32, framebufferSize [2]float32, drawData DrawData)
// Sets the texture minifying filter.
SetTextureMinFilter(min uint) error
// Sets the texture magnifying filter.
SetTextureMagFilter(mag uint) error
// Load image and return the TextureID
LoadImage(image *image.RGBA) (TextureID, error)
// Release image
Expand Down
58 changes: 54 additions & 4 deletions imgui/RendererOpenGL3.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@ type OpenGL3 struct {
vboHandle uint32
elementsHandle uint32

contentScale float32
contentScale float32
textureMinFilter int32
textureMagFilter int32
}

// Texture filtering types.
const (
textureFilterNearest = iota
textureFilterLinear
textureFilterNearestMipmapNearest
textureFilterLinearMipmapNearest
textureFilterNearestMipmapLinear
textureFilterLinearMipmapLinear
)

// NewOpenGL3 attempts to initialize a renderer.
// An OpenGL context has to be established before calling this function.
func NewOpenGL3(io IO, contentScale float32) (*OpenGL3, error) {
Expand All @@ -40,9 +52,11 @@ func NewOpenGL3(io IO, contentScale float32) (*OpenGL3, error) {
}

renderer := &OpenGL3{
imguiIO: io,
glslVersion: "#version 150",
contentScale: contentScale,
imguiIO: io,
glslVersion: "#version 150",
contentScale: contentScale,
textureMinFilter: gl.LINEAR,
textureMagFilter: gl.LINEAR,
}
renderer.createDeviceObjects()
return renderer, nil
Expand Down Expand Up @@ -176,6 +190,8 @@ func (renderer *OpenGL3) Render(displaySize [2]float32, framebufferSize [2]float
gl.Uniform1i(renderer.attribLocationImageType, int32(imageType))

gl.BindTexture(gl.TEXTURE_2D, uint32(cmd.TextureID()))
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, renderer.textureMinFilter) // minification filter
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, renderer.textureMagFilter) // magnification filter
clipRect := cmd.ClipRect()
gl.Scissor(int32(clipRect.X), int32(fbHeight)-int32(clipRect.W), int32(clipRect.Z-clipRect.X), int32(clipRect.W-clipRect.Y))
gl.DrawElements(gl.TRIANGLES, int32(cmd.ElementCount()), uint32(drawType), unsafe.Pointer(indexBufferOffset))
Expand Down Expand Up @@ -384,6 +400,40 @@ func (renderer *OpenGL3) invalidateDeviceObjects() {
}
}

// SetTextureMinFilter sets the minifying function for texture filtering.
func (renderer *OpenGL3) SetTextureMinFilter(min uint) error {
switch min {
case textureFilterNearest:
renderer.textureMinFilter = gl.NEAREST
case textureFilterLinear:
renderer.textureMinFilter = gl.LINEAR
case textureFilterNearestMipmapNearest:
renderer.textureMinFilter = gl.NEAREST_MIPMAP_NEAREST
case textureFilterLinearMipmapNearest:
renderer.textureMinFilter = gl.LINEAR_MIPMAP_NEAREST
case textureFilterNearestMipmapLinear:
renderer.textureMinFilter = gl.NEAREST_MIPMAP_LINEAR
case textureFilterLinearMipmapLinear:
renderer.textureMinFilter = gl.LINEAR_MIPMAP_LINEAR
default:
return fmt.Errorf("invalid minifying filter")
}
return nil
}

// SetTextureMagFilter sets the magnifying function for texture filtering.
func (renderer *OpenGL3) SetTextureMagFilter(mag uint) error {
switch mag {
case textureFilterNearest:
renderer.textureMagFilter = gl.NEAREST
case textureFilterLinear:
renderer.textureMagFilter = gl.LINEAR
default:
return fmt.Errorf("invalid magnifying filter")
}
return nil
}

// Load image and return the TextureID
func (renderer *OpenGL3) LoadImage(image *image.RGBA) (TextureID, error) {
texture, err := renderer.createImageTexture(image)
Expand Down