Merge pull request #3 from thegtproject/shader-examples
added shader examples
This commit is contained in:
commit
67b4a8f84d
|
@ -0,0 +1,2 @@
|
|||
*.exe
|
||||
.vscode
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 thegtproject
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,20 @@
|
|||
# Examples for Pixel's new custom fragment shader support
|
||||
|
||||
A few examples on how to implement custom shaders in Pixel. Please note I am not good with graphics, so hopefully someone more talented than I come up with better demos soon :)
|
||||
|
||||
|
||||
## fast radial blurring effect
|
||||
|
||||
![](/fastblur.gif)
|
||||
|
||||
## long exposure-ish effect
|
||||
|
||||
![](/exposure.gif)
|
||||
|
||||
## grayscale (from wiki tutorial)
|
||||
|
||||
![](/grayscale.png)
|
||||
|
||||
## wavy (from wiki tutorial)
|
||||
|
||||
![](/wavy.gif)
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -0,0 +1,25 @@
|
|||
#version 330 core
|
||||
|
||||
// Keep in mind, I have very little idea what I'm doing when it comes
|
||||
// to these shaders, so take what you see here with a grain of salt.
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Pixel default uniforms
|
||||
uniform vec4 uTexBounds;
|
||||
uniform sampler2D uTexture;
|
||||
uniform sampler2D uBackBuffer;
|
||||
|
||||
// Our custom uniforms
|
||||
uniform float uAmount;
|
||||
|
||||
void main() {
|
||||
// It is often very useful to normalize the fragment coordinate. Usually
|
||||
// represented as "uv" we do so here:
|
||||
vec2 uv = gl_FragCoord.xy / uTexBounds.zw;
|
||||
fragColor = texture(uTexture, uv);
|
||||
|
||||
// uAmount is programmed to be adjustable with the left and right keys
|
||||
// inside of Pixel
|
||||
fragColor *= texture(uBackBuffer, uv).a * uAmount;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
#version 330 core
|
||||
|
||||
// base shader code from https://www.shadertoy.com/view/XssSDs
|
||||
|
||||
in vec2 vTexCoords;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
// Pixel default uniforms
|
||||
uniform vec4 uTexBounds;
|
||||
uniform sampler2D uTexture;
|
||||
|
||||
// Our custom uniforms
|
||||
uniform float uTime;
|
||||
uniform vec4 uMouse;
|
||||
|
||||
vec2 Circle(float Start, float Points, float Point)
|
||||
{
|
||||
float Rad = (3.141592 * 2.0 * (1.0 / Points)) * (Point + Start);
|
||||
return vec2(sin(Rad), cos(Rad));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// It is often very useful to normalize the fragment coordinate. Usually
|
||||
// represented as "uv" we do so here:
|
||||
//
|
||||
// Normalize the fragments's position, this is the location we use to sample
|
||||
// our two textures/buffers. Note: Pixel passes resolution info through
|
||||
// uTexBounds.zw (x, y)
|
||||
vec2 uv = gl_FragCoord.xy / uTexBounds.zw;
|
||||
|
||||
|
||||
vec2 PixelOffset = 1.0 / uTexBounds.zw;
|
||||
float Start = 4.0 / 14.0;
|
||||
vec2 Scale = 0.66 * 4.0 * 2.0 * PixelOffset.xy;
|
||||
|
||||
vec3 N0 = texture(uTexture, uv + Circle(Start, 14.0, 0.0) * Scale).rgb;
|
||||
vec3 N1 = texture(uTexture, uv + Circle(Start, 14.0, 1.0) * Scale).rgb;
|
||||
vec3 N2 = texture(uTexture, uv + Circle(Start, 14.0, 2.0) * Scale).rgb;
|
||||
vec3 N3 = texture(uTexture, uv + Circle(Start, 14.0, 3.0) * Scale).rgb;
|
||||
vec3 N4 = texture(uTexture, uv + Circle(Start, 14.0, 4.0) * Scale).rgb;
|
||||
vec3 N5 = texture(uTexture, uv + Circle(Start, 14.0, 5.0) * Scale).rgb;
|
||||
vec3 N6 = texture(uTexture, uv + Circle(Start, 14.0, 6.0) * Scale).rgb;
|
||||
vec3 N7 = texture(uTexture, uv + Circle(Start, 14.0, 7.0) * Scale).rgb;
|
||||
vec3 N8 = texture(uTexture, uv + Circle(Start, 14.0, 8.0) * Scale).rgb;
|
||||
vec3 N9 = texture(uTexture, uv + Circle(Start, 14.0, 9.0) * Scale).rgb;
|
||||
vec3 N10 = texture(uTexture, uv + Circle(Start, 14.0, 10.0) * Scale).rgb;
|
||||
vec3 N11 = texture(uTexture, uv + Circle(Start, 14.0, 11.0) * Scale).rgb;
|
||||
vec3 N12 = texture(uTexture, uv + Circle(Start, 14.0, 12.0) * Scale).rgb;
|
||||
vec3 N13 = texture(uTexture, uv + Circle(Start, 14.0, 13.0) * Scale).rgb;
|
||||
vec3 N14 = texture(uTexture, uv).rgb;
|
||||
|
||||
float W = 1.0 / 15.0;
|
||||
|
||||
vec3 color = vec3(0,0,0);
|
||||
|
||||
color.rgb =
|
||||
(N0 * W) +
|
||||
(N1 * W) +
|
||||
(N2 * W) +
|
||||
(N3 * W) +
|
||||
(N4 * W) +
|
||||
(N5 * W) +
|
||||
(N6 * W) +
|
||||
(N7 * W) +
|
||||
(N8 * W) +
|
||||
(N9 * W) +
|
||||
(N10 * W) +
|
||||
(N11 * W) +
|
||||
(N12 * W) +
|
||||
(N13 * W) +
|
||||
(N14 * W);
|
||||
|
||||
// curTexColor is the value of the current fragment color
|
||||
// from Pixel's (the library) input texture.
|
||||
vec4 curTexColor = texture(uTexture, uv);
|
||||
|
||||
float xvalue = 0.0;
|
||||
|
||||
// Left mouse button is currently pressed
|
||||
if (uMouse[2] == 1.0) xvalue = uMouse[0] / uTexBounds.z;
|
||||
|
||||
if(uv.x < xvalue)
|
||||
{
|
||||
color.rgb = curTexColor.rgb;
|
||||
}
|
||||
|
||||
// Draw a black verticle line between our two halves
|
||||
// to distinguish unblurred and blurred
|
||||
if(abs(uv.x - xvalue) < 0.0015)
|
||||
color = vec3(0.0);
|
||||
|
||||
fragColor = vec4(color.rgb, 1.0);
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 248 KiB |
|
@ -0,0 +1,170 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/faiface/pixel"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
)
|
||||
|
||||
// Pixel Shader utility functions
|
||||
|
||||
// EasyBindUniforms does all the work for you, just pass in a
|
||||
// valid array adhering to format: String, Variable, ...
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// var uTimeVar float32
|
||||
// var uMouseVar mgl32.Vec4
|
||||
//
|
||||
// EasyBindUniforms(win.GetCanvas(),
|
||||
// "uTime", &uTimeVar,
|
||||
// "uMouse", &uMouseVar,
|
||||
// )
|
||||
//
|
||||
func EasyBindUniforms(c *pixelgl.Canvas, unifs ...interface{}) {
|
||||
if len(unifs)%2 != 0 {
|
||||
panic("needs to be divisable by 2")
|
||||
}
|
||||
for i := 0; i < len(unifs); i += 2 {
|
||||
|
||||
c.SetUniform(unifs[i+0].(string), unifs[i+1])
|
||||
}
|
||||
}
|
||||
|
||||
// CenterWindow will... center the window
|
||||
func CenterWindow(win *pixelgl.Window) {
|
||||
x, y := pixelgl.PrimaryMonitor().Size()
|
||||
width, height := win.Bounds().Size().XY()
|
||||
win.SetPos(
|
||||
pixel.V(
|
||||
x/2-width/2,
|
||||
y/2-height/2,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// LoadFileToString loads the contents of a file into a string
|
||||
func LoadFileToString(filename string) (string, error) {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 126 KiB |
|
@ -0,0 +1,176 @@
|
|||
package main
|
||||
|
||||
//
|
||||
// This example will show you how to port a shader you find from shadertoy.com
|
||||
// to Pixel. See ../assets/shaders/fastblur.frag.glsl for more details and comments
|
||||
//
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/faiface/pixel"
|
||||
"github.com/faiface/pixel/imdraw"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
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/fastblur.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
|
||||
|
||||
// It is common to provide a vec4 for a "mouse" uniform where
|
||||
// uMouse[0] = X, uMouse[1] = Y, uMouse[2] = left mouse button,
|
||||
// and uMouse[3] = right mouse button.
|
||||
var uMouseVar mgl32.Vec4
|
||||
|
||||
// We will update these uniforms often, so use pointer
|
||||
EasyBindUniforms(win.Canvas(),
|
||||
"uTime", &uTimeVar,
|
||||
"uMouse", &uMouseVar,
|
||||
)
|
||||
|
||||
// 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())
|
||||
|
||||
uMouseVar[0] = float32(win.MousePosition().X)
|
||||
uMouseVar[1] = float32(win.MousePosition().Y)
|
||||
|
||||
if win.Pressed(pixelgl.MouseButton1) {
|
||||
uMouseVar[2] = 1.0
|
||||
} else {
|
||||
uMouseVar[2] = 0.0
|
||||
}
|
||||
if win.Pressed(pixelgl.MouseButton2) {
|
||||
uMouseVar[3] = 1.0
|
||||
} else {
|
||||
uMouseVar[3] = 0.0
|
||||
}
|
||||
|
||||
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{52, 172, 224, 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
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/faiface/pixel"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
)
|
||||
|
||||
// Pixel Shader utility functions
|
||||
|
||||
// EasyBindUniforms does all the work for you, just pass in a
|
||||
// valid array adhering to format: String, Variable, ...
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// var uTimeVar float32
|
||||
// var uMouseVar mgl32.Vec4
|
||||
//
|
||||
// EasyBindUniforms(win.GetCanvas(),
|
||||
// "uTime", &uTimeVar,
|
||||
// "uMouse", &uMouseVar,
|
||||
// )
|
||||
//
|
||||
func EasyBindUniforms(c *pixelgl.Canvas, unifs ...interface{}) {
|
||||
if len(unifs)%2 != 0 {
|
||||
panic("needs to be divisable by 2")
|
||||
}
|
||||
for i := 0; i < len(unifs); i += 2 {
|
||||
|
||||
c.SetUniform(unifs[i+0].(string), unifs[i+1])
|
||||
}
|
||||
}
|
||||
|
||||
// CenterWindow will... center the window
|
||||
func CenterWindow(win *pixelgl.Window) {
|
||||
x, y := pixelgl.PrimaryMonitor().Size()
|
||||
width, height := win.Bounds().Size().XY()
|
||||
win.SetPos(
|
||||
pixel.V(
|
||||
x/2-width/2,
|
||||
y/2-height/2,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// LoadFileToString loads the contents of a file into a string
|
||||
func LoadFileToString(filename string) (string, error) {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image/png"
|
||||
"os"
|
||||
|
||||
"github.com/faiface/pixel"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
)
|
||||
|
||||
var gopherimg *pixel.Sprite
|
||||
|
||||
func gameloop(win *pixelgl.Window) {
|
||||
win.Canvas().SetFragmentShader(fragmentShader)
|
||||
|
||||
for !win.Closed() {
|
||||
win.Clear(pixel.RGB(0, 0, 0))
|
||||
gopherimg.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
|
||||
win.Update()
|
||||
}
|
||||
}
|
||||
|
||||
func run() {
|
||||
cfg := pixelgl.WindowConfig{
|
||||
Title: "Pixel Rocks!",
|
||||
Bounds: pixel.R(0, 0, 325, 348),
|
||||
VSync: true,
|
||||
}
|
||||
win, err := pixelgl.NewWindow(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f, err := os.Open("../assets/images/thegopherproject.png")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
img, err := png.Decode(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pd := pixel.PictureDataFromImage(img)
|
||||
gopherimg = pixel.NewSprite(pd, pd.Bounds())
|
||||
|
||||
gameloop(win)
|
||||
}
|
||||
|
||||
func main() {
|
||||
pixelgl.Run(run)
|
||||
}
|
||||
|
||||
var fragmentShader = `
|
||||
#version 330 core
|
||||
|
||||
in vec2 vTexCoords;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform vec4 uTexBounds;
|
||||
uniform sampler2D uTexture;
|
||||
|
||||
void main() {
|
||||
// Get our current screen coordinate
|
||||
vec2 t = (vTexCoords - uTexBounds.xy) / uTexBounds.zw;
|
||||
|
||||
// Sum our 3 color channels
|
||||
float sum = texture(uTexture, t).r;
|
||||
sum += texture(uTexture, t).g;
|
||||
sum += texture(uTexture, t).b;
|
||||
|
||||
// Divide by 3, and set the output to the result
|
||||
vec4 color = vec4( sum/3, sum/3, sum/3, 1.0);
|
||||
fragColor = color;
|
||||
}
|
||||
`
|
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
|
@ -0,0 +1,92 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"image/png"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/thegtproject/pixel/imdraw"
|
||||
|
||||
"github.com/faiface/pixel"
|
||||
"github.com/faiface/pixel/pixelgl"
|
||||
)
|
||||
|
||||
var gopherimg *pixel.Sprite
|
||||
var imd *imdraw.IMDraw
|
||||
|
||||
var uTime, uSpeed float32
|
||||
|
||||
func gameloop(win *pixelgl.Window) {
|
||||
win.Canvas().SetUniform("uTime", &uTime)
|
||||
win.Canvas().SetUniform("uSpeed", &uSpeed)
|
||||
uSpeed = 5.0
|
||||
win.Canvas().SetFragmentShader(fragmentShader)
|
||||
|
||||
start := time.Now()
|
||||
for !win.Closed() {
|
||||
win.Clear(pixel.RGB(0, 0, 0))
|
||||
gopherimg.Draw(win, pixel.IM.Moved(win.Bounds().Center()))
|
||||
uTime = float32(time.Since(start).Seconds())
|
||||
if win.Pressed(pixelgl.KeyRight) {
|
||||
uSpeed += 0.1
|
||||
}
|
||||
if win.Pressed(pixelgl.KeyLeft) {
|
||||
uSpeed -= 0.1
|
||||
}
|
||||
win.Update()
|
||||
}
|
||||
}
|
||||
|
||||
func run() {
|
||||
cfg := pixelgl.WindowConfig{
|
||||
Title: "Pixel Rocks!",
|
||||
Bounds: pixel.R(0, 0, 325, 348),
|
||||
VSync: true,
|
||||
}
|
||||
win, err := pixelgl.NewWindow(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f, err := os.Open("../assets/images/thegopherproject.png")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
img, err := png.Decode(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pd := pixel.PictureDataFromImage(img)
|
||||
gopherimg = pixel.NewSprite(pd, pd.Bounds())
|
||||
|
||||
gameloop(win)
|
||||
}
|
||||
|
||||
func main() {
|
||||
pixelgl.Run(run)
|
||||
}
|
||||
|
||||
var fragmentShader = `
|
||||
#version 330 core
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec4 uTexBounds;
|
||||
|
||||
// custom uniforms
|
||||
uniform float uSpeed;
|
||||
uniform float uTime;
|
||||
|
||||
void main() {
|
||||
vec2 t = gl_FragCoord.xy / uTexBounds.zw;
|
||||
vec3 influence = texture(uTexture, t).rgb;
|
||||
|
||||
if (influence.r + influence.g + influence.b > 0.3) {
|
||||
t.y += cos(t.x * 40.0 + (uTime * uSpeed))*0.005;
|
||||
t.x += cos(t.y * 40.0 + (uTime * uSpeed))*0.01;
|
||||
}
|
||||
|
||||
vec3 col = texture(uTexture, t).rgb;
|
||||
fragColor = vec4(col * vec3(0.6, 0.6, 1.2),1.0);
|
||||
}
|
||||
`
|
Loading…
Reference in New Issue