171 lines
4.2 KiB
Go
171 lines
4.2 KiB
Go
package main
|
|
|
|
//
|
|
// This example is my (thegtproject) own creation... I am not a designer- you've been warned.
|
|
// This is an attempt at performing a sort of "long-exposure" post effect.
|
|
// See ../assets/shaders/fastblur.frag.glsl for more details and comments
|
|
//
|
|
|
|
import (
|
|
"fmt"
|
|
"image/color"
|
|
"math"
|
|
"time"
|
|
|
|
"github.com/faiface/pixel"
|
|
"github.com/faiface/pixel/imdraw"
|
|
"github.com/faiface/pixel/pixelgl"
|
|
)
|
|
|
|
var (
|
|
g = 0.1
|
|
r1 = 180.0
|
|
r2 = 90.0
|
|
m1 = 32.0
|
|
m2 = 8.0
|
|
a1v = 0.0
|
|
a2v = 0.0
|
|
a1, a2 = a1a2DefaultValues()
|
|
)
|
|
|
|
func run() {
|
|
win, err := pixelgl.NewWindow(pixelgl.WindowConfig{
|
|
Bounds: pixel.R(0, 0, 600, 310),
|
|
VSync: true,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
CenterWindow(win)
|
|
win.SetSmooth(true)
|
|
modelMatrix := pixel.IM.ScaledXY(pixel.ZV, pixel.V(1, -1)).Moved(pixel.V(300, 300))
|
|
viewMatrix := pixel.IM.Moved(win.Bounds().Center())
|
|
|
|
// I am putting all shader example initializing stuff here for
|
|
// easier reference to those learning to use this functionality
|
|
fragSource, err := LoadFileToString("../assets/shaders/exposure.frag.glsl")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Here we setup our uniforms. Think of uniforms as global variables
|
|
// we can use inside of our fragment shader source code.
|
|
var uTimeVar float32
|
|
|
|
// We'll change this variable around with the arrow keys
|
|
var uAmountVar float32 = 0.2
|
|
|
|
// We will update these uniforms often, so use pointer
|
|
EasyBindUniforms(win.Canvas(),
|
|
"uTime", &uTimeVar,
|
|
"uAmount", &uAmountVar,
|
|
)
|
|
|
|
// Since we are making a post effect, we want to apply the shader
|
|
// to the entire final render. We will use an intermediate canvas
|
|
// to complete the draw frame and then draw the canvas to the window's
|
|
// canvas for shader processing. Otherwise, our shader would only be
|
|
// running on active vertex positions, in this case, only the line
|
|
// and circle draws generated by IMDraw.
|
|
intermediatecanvas := pixelgl.NewCanvas(win.Bounds())
|
|
intermediatecanvas.SetMatrix(modelMatrix)
|
|
|
|
wc := win.Canvas()
|
|
wc.SetFragmentShader(fragSource)
|
|
|
|
sqrPos := win.Bounds().Moved(pixel.V(-300, -10))
|
|
start := time.Now()
|
|
for !win.Closed() {
|
|
// Update our uniform variables
|
|
uTimeVar = float32(time.Since(start).Seconds())
|
|
|
|
switch {
|
|
case win.Pressed(pixelgl.KeyLeft):
|
|
uAmountVar -= 0.001
|
|
win.SetTitle(fmt.Sprint(uAmountVar))
|
|
case win.Pressed(pixelgl.KeyRight):
|
|
uAmountVar += 0.001
|
|
win.SetTitle(fmt.Sprint(uAmountVar))
|
|
}
|
|
|
|
win.SetClosed(win.JustPressed(pixelgl.KeyEscape) || win.JustPressed(pixelgl.KeyQ))
|
|
if win.JustPressed(pixelgl.KeySpace) {
|
|
a1, a2 = a1a2DefaultValues()
|
|
}
|
|
|
|
a, b := update()
|
|
|
|
imd := imdraw.New(nil)
|
|
|
|
// Clearing the background color with a filled rectangle so that
|
|
// opengl will include the entire space in shader processing instead
|
|
// of just where the shape objects are drawn.
|
|
imd.Color = color.NRGBA{44, 44, 84, 255}
|
|
imd.Push(sqrPos.Min, sqrPos.Max)
|
|
imd.Rectangle(0)
|
|
|
|
imd.Color = color.NRGBA{64, 64, 122, 255}
|
|
imd.Push(pixel.ZV, a, b)
|
|
imd.Line(3)
|
|
|
|
imd.Color = color.NRGBA{51, 217, 178, 255}
|
|
imd.Push(a)
|
|
imd.Circle(m1/2, 0)
|
|
|
|
imd.Color = color.NRGBA{255, 0, 0, 255}
|
|
imd.Push(b)
|
|
imd.Circle(m2/2, 0)
|
|
|
|
imd.Draw(intermediatecanvas)
|
|
intermediatecanvas.Draw(win, viewMatrix)
|
|
win.Update()
|
|
}
|
|
}
|
|
|
|
func update() (pixel.Vec, pixel.Vec) {
|
|
a1a := a1aCalculation()
|
|
a2a := a2aCalculation()
|
|
|
|
a1v += a1a
|
|
a2v += a2a
|
|
|
|
a1 += a1v
|
|
a2 += a2v
|
|
|
|
a1v *= 0.9996
|
|
a2v *= 0.9996
|
|
|
|
a := pixel.V(r1*math.Sin(a1), r1*math.Cos(a1))
|
|
b := pixel.V(a.X+r2*math.Sin(a2), a.Y+r2*math.Cos(a2))
|
|
|
|
return a, b
|
|
}
|
|
|
|
func main() {
|
|
pixelgl.Run(run)
|
|
}
|
|
|
|
func a1a2DefaultValues() (float64, float64) {
|
|
return math.Pi / 2, math.Pi / 3
|
|
}
|
|
|
|
func a1aCalculation() float64 {
|
|
num1 := -g * (2*m1 + m2) * math.Sin(a1)
|
|
num2 := -m2 * g * math.Sin(a1-2*a2)
|
|
num3 := -2 * math.Sin(a1-a2) * m2
|
|
num4 := a2v*a2v*r2 + a1v*a1v*r1*math.Cos(a1-a2)
|
|
den := r1 * (2*m1 + m2 - m2*math.Cos(2*a1-2*a2))
|
|
|
|
return (num1 + num2 + num3*num4) / den
|
|
}
|
|
|
|
func a2aCalculation() float64 {
|
|
num1 := 2 * math.Sin(a1-a2)
|
|
num2 := (a1v * a1v * r1 * (m1 + m2))
|
|
num3 := g * (m1 + m2) * math.Cos(a1)
|
|
num4 := a2v * a2v * r2 * m2 * math.Cos(a1-a2)
|
|
den := r2 * (2*m1 + m2 - m2*math.Cos(2*a2-2*a2))
|
|
|
|
return (num1 * (num2 + num3 + num4)) / den
|
|
}
|