using GLVisualize, GLAbstraction
using FileIO, GeometryTypes, Reactive
window = glscreen()
timesignal = loop(linspace(0f0,1f0,360))
# loadasset is defined in GLVisualize like this:
# loadasset(path_segments...) = FileIO.load(assetpath(path_segments...))
# where assetpath just looks up the file in the asset folder
# You can load these (file types)[https://github.com/JuliaIO/FileIO.jl/blob/master/docs/registry.md]
mesh = loadasset("cat.obj")
# GLAbstraction.const_lift is an alias for Reactive.map, which also works for non
# signal arguments.
# Reactive.map takes a function and signals like the one created via `loop` (or just Signal(x))
# as an argument, applies the function to the signals whenever they update and
# returns a new signal.
rotation_angle = const_lift(*, timesignal, 2f0*pi)
# the cat needs some rotation on the x axis to stand straight
# so we start off with a rotation of 90 degrees
start_rotation = Signal(rotationmatrix_x(deg2rad(90f0)))
rotation = map(rotationmatrix_y, rotation_angle)
final_rotation = map(*, start_rotation, rotation)
# now we visualize the mesh and pass the rotation via the model keyword argument,
# which is short for the modelmatrix, which allows you to transform the visualization
# with any arbitrary transformation matrix
# You can create the most common transformation matrix with `translationmatrix(::Vec3f0)`,
# `rotationmatrix_x`/`y`/`z` (rotation around axis x,y,z), and `scalematrix(::Vec3f0)`
# the visualize function always only takes one argument, plus an optional style
# argument and then visualization dependant many keywords to customize the visualization.
# for all parameters Signals can be used and thus the visualization becomes animated
robj = visualize(mesh, model=final_rotation)
view(robj, window)
renderloop(window)
Simulation
#this is an example by https://github.com/musmo
using GLVisualize, GeometryTypes, Reactive, GLAbstraction, Colors, GLWindow, ModernGL
"""
Simulation function
"""
function solve_particles(pos_vel_s)
dt = 1.0f0
positions, velocity, s = pos_vel_s
for i in eachindex(positions)
velx = 0.0f0
vely = 0.0f0
posi = positions[i]
for j in eachindex(positions)
posj = positions[j]
dx = posj[1] - posi[1]
dy = posj[2] - posi[2]
distsq = dx*dx + dy*dy + 1f0
velx = velx - s[j]*dy/distsq
vely = vely + s[j]*dx/distsq
end
positions[i] = Point2f0(posi[1] + dt*velx, posi[2] + dt*vely)
end
positions, velocity, s
end
"""
Clears the image of the window to `color`
"""
function clear_frame!(window, color=RGB(0.2,0.2,0.2))
glClearColor(red(color), green(color), blue(color), 1)
GLWindow.clear_all!(window)
end
"""
Resets the state of a window
"""
function reset!(window, color=RGB(0.2,0.2,0.2))
clear_frame!(window, color)
empty!(window.renderlist) # removes all viewables that where added with `view`
end
"""
This code should be executed only one time per julia session!!
If you accidantly close the window, you can call this again.
"""
function init(res=(800,600))
# giving the window a transparent background color makes it transparent to
# the previous frame. It's arguable, if that's really how things should be,
# but that's how it currently works ;)
window = glscreen("vortex", resolution=res, background=RGBA(0,0,0,0))
timesignal = Signal(0.0)
speed = Signal(1/30)
# this is equivalent to @async renderloop(window).
# but now you can do other stuff before an image is rendered
# the @async is used to make this non blocking for working in the REPL/Atom
@async while isopen(window)
push!(timesignal, value(timesignal)+0.01)
render_frame(window)
sleep(value(speed))
end
# this registers a callback whenever a keybutton is clicked.
# We use Reactive signals, so every registered callback
# returns a new signal with the returnvalue of that callback. Since we don't
# use that signal, Reactive will try to garbage collect it, which is why we need
# to call preserve on it.
preserve(map(window.inputs[:keyboard_buttons]) do kam
key, action, mods = kam
if key == GLFW.KEY_S
println("saving screenshot")
screenshot(window, path="screenshot.jpg")
end
# make sure that this function doesn't return different types
# for the if branch.
# Reactive would try to convert them otherwise.
nothing
end
)
window, timesignal, speed
end
function main(window, timesignal)
# get the resolution of the window
res = widths(window)
num = 1000
# use Float32 whenever possible to avoid conversions (GLVisualize can
# convert to appropriate type most of the time, though)
x = Float32[(res[1]/2.0) + (res[2]/3.5) * sin(i*2*pi/num) for i=0:num-1]
y = Float32[(res[2]/2.0) + (res[2]/3.5) * cos(i*2*pi/num) for i=0:num-1]
s = (-1 + 2*rand(Float32,num))
# GeometryTypes.Point2f0 -> Point{2, Float32}
start_position = Point2f0[Point2f0(xi,yi) for (xi,yi) in zip(x,y)]
# Everything in GLVisualize gets animated with Reactive signals. So drawing a frame
# and animating some graphic is decoupled.
# for more infos, checkout Reactives documentation:
# https://github.com/JuliaLang/Reactive.jl/blob/master/doc/index.md
# In this case we use foldp to simulate the particles for every time step.
# signature: foldp(function, startvalue, signals...), function will be called
# with f(startvalue, signals...) every time timesignal updates.
position_velocity = foldp(
(v0, t) -> solve_particles(v0),
(start_position, zeros(Float32,num), s),
timesignal
)
# extract the position
position = map(first, position_velocity)
# create a color signal that changes over time
# the color will update whenever timesignal updates
color = map(timesignal) do t
RGBA(1,1,(sin(t)+1.)/2., 0.05)
end
circle = Circle(Point2f0(0), 0.7f0)
# boundingbox is still a very expensive operation, so if you don't need it
# you can simply set it to nothing.
# The signature for all kind of particles is:
# visualize((primitive, positions), keyword_arguments...)
viewable = visualize(
(circle, position),
boundingbox=nothing,
color=color
)
# reset is basically the antagonist of view
reset!(window) # when you reset the window here, you can call main multiple times
# view adds an (animated) viewable to the list of things that you want to see
# in `window`
view(viewable, window, camera=:fixed_pixel)
end
#=
workflow in Julia REPL or you can also just evaluate parts in Atom:
include("simulation.jl")
window, t, speed = init()
main(window, t)
#redefine main/solve_particles
include("simulation.jl") # if you have the changes in the file
main() # call again! If you only changed solve_particles, you don't even have to call main again
push!(speed, 1/20) # this is fully interactive so you can, e.g. change the speed
=#
window, timesignal, speed = init()
main(window, timesignal)
Search
From here you can search these documents. Enter
your search terms below.