From ad565b18cf0d526cc90e017fa096422648d60a6e Mon Sep 17 00:00:00 2001 From: "H. Diedrich" Date: Sat, 12 Apr 2014 22:28:20 +0200 Subject: [PATCH 1/3] build for Mac 10.8; make clean; notes in README --- .gitignore | 1 + Makefile | 11 +++++++++++ README.md | 20 +++++++++++++++----- c_src/Makefile | 3 ++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index dbe3e92..11f1186 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ c_src/env.mk ebin examples/*/*.beam priv +.DS_Store diff --git a/Makefile b/Makefile index ed7c196..94c2d41 100644 --- a/Makefile +++ b/Makefile @@ -19,3 +19,14 @@ all: cd c_src && make erlc -o examples/bullet_engine examples/bullet_engine/*.erl cd examples/bullet_engine && ./start.sh + +hello: + erlc -o examples/hello_sdl examples/hello_sdl/*.erl + cd examples/hello_sdl && ./start.sh + +clean: + @rm -f *.swp + @rm -f c_src/env.mk + @rm -rf ebin/ + @rm -f examples/*/*.beam + @echo clean diff --git a/README.md b/README.md index a5fb1da..44c06de 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,29 @@ ESDL2 ===== -SDL2 Erlang NIF. +SDL2 Erlang NIFs + +SDL provides cross-platform low level access to graphics, audio, keyboard, mouseand joystick hardware via OpenGL and Direct3D. This is an Erlang binding. http://www.libsdl.org/ Status ------ Week-end project. Work in progress. - -The following limitations apply: - + + Building + -------- + * Erlang 17.0+ is required - * SDL 2.0.3+ is required + * SDL 2.0.3+ is required (`http://www.libsdl.org/download-2.0.php`) + * SDL\_image is required (`https://www.libsdl.org/projects/SDL_image/`) * No support for UTF-8 strings, only Latin-1 +Tip: configure SDL\_image with --disable-webp for not having to install libwebp. + +Build using `make`. + +Ideas +----- The following ideas need to be investigated: * We may benefit from the reference receive optimization when doing calls diff --git a/c_src/Makefile b/c_src/Makefile index 0887c86..7fa7c94 100644 --- a/c_src/Makefile +++ b/c_src/Makefile @@ -20,7 +20,8 @@ SDL2_LIBS = $(filter-out $(SDL2_LIBS_FILTER_OUT),$(shell sdl2-config --static-li all: env.mk mkdir -p $(PRIV_DIR) - gcc *.c -fPIC -shared -o $(PRIV_DIR)/esdl2.so -I $(ERTS_INCLUDE_DIR) \ + gcc -undefined dynamic_lookup *.c -fPIC -shared \ + -o $(PRIV_DIR)/esdl2.so -I $(ERTS_INCLUDE_DIR) \ `sdl2-config --cflags` $(SDL2_LIBS) -lSDL2_image env.mk: From cdf0a620529bd25978f58fd850f780820ec5c835 Mon Sep 17 00:00:00 2001 From: "H. Diedrich" Date: Mon, 21 Apr 2014 10:39:03 +0200 Subject: [PATCH 2/3] examples rose, dot; make deps; more README; unused version assert --- Makefile | 19 +++++++++++++++- README.md | 31 +++++++++++++++++++++----- examples/dot/dot.erl | 50 ++++++++++++++++++++++++++++++++++++++++++ examples/dot/start.sh | 2 ++ examples/rose/rose.erl | 50 ++++++++++++++++++++++++++++++++++++++++++ examples/rose/start.sh | 2 ++ src/sdl_version.erl | 6 +++++ 7 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 examples/dot/dot.erl create mode 100755 examples/dot/start.sh create mode 100644 examples/rose/rose.erl create mode 100755 examples/rose/start.sh diff --git a/Makefile b/Makefile index 94c2d41..c5f4be0 100644 --- a/Makefile +++ b/Makefile @@ -13,20 +13,37 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. all: + make ebin + make bullet + +ebin: rm -rf ebin/ mkdir -p ebin/ erlc -o ebin/ src/*.erl cd c_src && make + +bullet: ebin erlc -o examples/bullet_engine examples/bullet_engine/*.erl cd examples/bullet_engine && ./start.sh -hello: +hello: ebin erlc -o examples/hello_sdl examples/hello_sdl/*.erl cd examples/hello_sdl && ./start.sh +dot: ebin + erlc -o examples/dot examples/dot/*.erl + cd examples/dot && ./start.sh + +rose: ebin + erlc -o examples/rose examples/rose/*.erl + cd examples/rose && ./start.sh + clean: @rm -f *.swp @rm -f c_src/env.mk + @rm -f priv/esdl2.so @rm -rf ebin/ + @rm -f examples/*/*.dump @rm -f examples/*/*.beam + @rm -f .DS_Store @echo clean diff --git a/README.md b/README.md index 44c06de..0bda87a 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,17 @@ ESDL2 SDL2 Erlang NIFs -SDL provides cross-platform low level access to graphics, audio, keyboard, mouseand joystick hardware via OpenGL and Direct3D. This is an Erlang binding. http://www.libsdl.org/ +SDL provides cross-platform low level access to graphics, audio, keyboard, mouseand joystick hardware via OpenGL and Direct3D. This is an Erlang binding to SDL2. http://www.libsdl.org/ + +Note: 'ESDL' used to be Erlang's graphics kit, using SDL 1, before it was replaced by wxWidgets. This is a different implementation, for a new version of SDL. Status ------ Week-end project. Work in progress. - - Building - -------- + +Building +-------- * Erlang 17.0+ is required * SDL 2.0.3+ is required (`http://www.libsdl.org/download-2.0.php`) @@ -20,7 +22,26 @@ Week-end project. Work in progress. Tip: configure SDL\_image with --disable-webp for not having to install libwebp. -Build using `make`. +Build using make: + + make + +Examples +-------- + +Samples in examples/ + + * Bullet Engine - rains bullets danmaku style + * Hello World - minimal visual: show a graphic + * Rose - minimal animation: draw a pixel line + * Dot - minimal animation: show a circling dot + +Build and run using make from the project root. + + make bullet + make hello + make rose + make dot Ideas ----- diff --git a/examples/dot/dot.erl b/examples/dot/dot.erl new file mode 100644 index 0000000..ca4dea7 --- /dev/null +++ b/examples/dot/dot.erl @@ -0,0 +1,50 @@ +%% Minimal animation example: a single dot looping in circles. +%% Build and run from project root: make dot +%% Feel free to copy and reuse as you wish. + +-module(dot). +-export([run/0]). + +run() -> + spawn_opt(fun init/0, [{scheduler, 0}]). + +init() -> + %% setup sdl, window and renderer + ok = sdl:start([video]), + ok = sdl:stop_on_exit(), + {ok, Window} = sdl_window:create("Dot", 10, 10, 500, 500, []), + {ok, Renderer} = sdl_renderer:create(Window, -1, [accelerated, present_vsync]), + %% start animaton + loop(#{window=>Window, renderer=>Renderer, t=>0}). + +%% animation loop +loop(State) -> + events_loop(), + loop(render(State)). + +%% check for termination +events_loop() -> + case sdl_events:poll() of + false -> ok; + #{type:=quit} -> terminate(); + _ -> events_loop() + end. + +%% render one frame +render(#{renderer:=Renderer, t:=T}=State) -> + %% clear screen + ok = sdl_renderer:set_draw_color(Renderer, 0,0,0,0), + ok = sdl_renderer:clear(Renderer), + %% draw dot + X = erlang:round(250 + 100 * math:sin(T/250) * (math:cos(T/100) + math:cos(T/10))), + Y = erlang:round(250 + 100 * math:sin(T/250) * (math:sin(T/100) + math:sin(T/10))), + ok = sdl_renderer:set_draw_color(Renderer, 255, 255, 255, 255), + ok = sdl_renderer:draw_point(Renderer, #{x=>X, y=>Y}), + %% render + ok = sdl_renderer:present(Renderer), + %% progress timeline + State#{t=>T + 1}. + +terminate() -> + init:stop(), + exit(normal). diff --git a/examples/dot/start.sh b/examples/dot/start.sh new file mode 100755 index 0000000..6f95a39 --- /dev/null +++ b/examples/dot/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +erl +stbt db -pa ../../ebin -eval "dot:run()." diff --git a/examples/rose/rose.erl b/examples/rose/rose.erl new file mode 100644 index 0000000..ba0fca4 --- /dev/null +++ b/examples/rose/rose.erl @@ -0,0 +1,50 @@ +%% Minimal animation example: rose line art. +%% Build and run from project root: make rose +%% Feel free to copy and reuse as you wish. + +-module(rose). +-export([run/0]). + +run() -> + spawn_opt(fun init/0, [{scheduler, 0}]). + +init() -> + %% setup sdl, window and renderer + ok = sdl:start([video]), + ok = sdl:stop_on_exit(), + {ok, Window} = sdl_window:create("Dot", 10, 10, 500, 500, []), + {ok, Renderer} = sdl_renderer:create(Window, -1, [accelerated, present_vsync]), + %% clear screen (once ever in this example) + ok = sdl_renderer:set_draw_color(Renderer, 0,0,0,0), + ok = sdl_renderer:clear(Renderer), + %% start animaton + loop(#{window=>Window, renderer=>Renderer, t=>0}). + +%% animation loop +loop(State) -> + events_loop(), + loop(render(State)). + +%% check for termination +events_loop() -> + case sdl_events:poll() of + false -> ok; + #{type:=quit} -> terminate(); + _ -> events_loop() + end. + +%% render one frame +render(#{renderer:=Renderer, t:=T}=State) -> + %% draw one dot (it is not cleared next frame) + X = erlang:round(250 + 100 * math:sin(T/250) * math:cos(T/100)), + Y = erlang:round(250 + 100 * math:sin(T/250) * math:sin(T/100)), + ok = sdl_renderer:set_draw_color(Renderer, 255, 0, 0, 255), + ok = sdl_renderer:draw_point(Renderer, #{x=>X, y=>Y}), + %% render + ok = sdl_renderer:present(Renderer), + %% progress frame number + State#{t=>T + 1}. + +terminate() -> + init:stop(), + exit(normal). diff --git a/examples/rose/start.sh b/examples/rose/start.sh new file mode 100755 index 0000000..18b346e --- /dev/null +++ b/examples/rose/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +erl +stbt db -pa ../../ebin -eval "rose:run()." diff --git a/src/sdl_version.erl b/src/sdl_version.erl index 488b712..f31e61e 100644 --- a/src/sdl_version.erl +++ b/src/sdl_version.erl @@ -16,6 +16,7 @@ -export([get_version/0]). -export([get_revision/0]). +-export([assert_erlang_version/0]). -spec get_version() -> {byte(), byte(), byte()}. get_version() -> @@ -24,3 +25,8 @@ get_version() -> -spec get_revision() -> string(). get_revision() -> esdl2:get_revision(). + +-spec assert_erlang_version() -> true. +assert_erlang_version() -> + V = list_to_integer(string:substr(erlang:system_info(otp_release),2,2)), + true = V >= 17. From cfcc197fd51259583ee7b6d662236b8bf0437275 Mon Sep 17 00:00:00 2001 From: "H. Diedrich" Date: Sat, 3 May 2014 08:08:45 +0200 Subject: [PATCH 3/3] planets wip --- examples/planets/planets.erl | 79 ++++++++++++++++++++++++++++++++++++ examples/planets/start.sh | 2 + 2 files changed, 81 insertions(+) create mode 100644 examples/planets/planets.erl create mode 100755 examples/planets/start.sh diff --git a/examples/planets/planets.erl b/examples/planets/planets.erl new file mode 100644 index 0000000..33f7328 --- /dev/null +++ b/examples/planets/planets.erl @@ -0,0 +1,79 @@ +%% Minimal animation example: rose line art. +%% Build and run from project root: make rose +%% Feel free to copy and reuse as you wish. + +-module(planets). +-export([run/0]). + +run() -> + spawn_opt(fun init/0, [{scheduler, 0}]). + +init() -> + %% setup sdl, window and renderer + ok = sdl:start([video]), + ok = sdl:stop_on_exit(), + {ok, Window} = sdl_window:create("Planets", 10, 10, 500, 500, []), + {ok, Renderer} = sdl_renderer:create(Window, -1, [accelerated, present_vsync]), + %% clear screen (once ever in this example) + ok = sdl_renderer:set_draw_color(Renderer, 0,0,0,0), + ok = sdl_renderer:clear(Renderer), + %% start animaton + loop(#{window=>Window, renderer=>Renderer, t=>os:timestamp()}). + +%% animation loop +loop(State) -> + events_loop(), + render(State), + loop(State). + +%% check for termination +events_loop() -> + case sdl_events:poll() of + false -> ok; + #{type:=quit} -> terminate(); + _ -> events_loop() + end. + +%% render one frame +render(#{renderer:=Renderer, t:=TT}=State) -> + T = timer:now_diff(os:timestamp(), TT) / 20000, + ok = sdl_renderer:set_draw_color(Renderer, 0,0,0,0), + ok = sdl_renderer:clear(Renderer), + %% draw one dot (it is not cleared next frame) + draw_star(Renderer, T), + draw_planet(Renderer, 7, 200, 450, 600, 100, T), + draw_planet(Renderer, 3, 100, 280, 300, 30, T), + draw_planet(Renderer, 3, 100, 900, 300, 30, T+70), + draw_planet(Renderer, 5, 200, 290, 200, 30, T+100), + draw_planet(Renderer, 12, 300, 650, 700, 300, T), + %% render + ok = sdl_renderer:present(Renderer). + +draw_star(Renderer, T) -> + ok = sdl_renderer:set_draw_color(Renderer, 255, 255, 255, 255), + ok = sdl_renderer:draw_points(Renderer, circle(100, 250, 50, 120, T, 1)), + ok = sdl_renderer:draw_points(Renderer, circle(100, 250, 53, 30, -T, 1)), + ok = sdl_renderer:draw_points(Renderer, circle(100, 250, 45, 300, T/100, 1)). + + +draw_planet(Renderer, W, N, R, D, V, T) -> + X = 100 + erlang:round(R * math:cos(T/D)), + Y = 250 + erlang:round(R * math:sin(T/D) / 5), + ok = sdl_renderer:set_draw_color(Renderer, 100, 100, 100, 255), + ok = sdl_renderer:draw_points(Renderer, circle(X, Y, W, N, T/V, 1.25)), + ok = sdl_renderer:set_draw_color(Renderer, 255, 255, 255, 255), + ok = sdl_renderer:draw_points(Renderer, circle(X, Y, W, N, T/V, 1)). + +%% T effects a slow ant crawl of the dashed circle line when N is small enough +%% in relation to R. +%% S gives a breathing effect of the size, scaling the entire radius. +circle(X, Y, R0, N, T, S) -> + R = S * (R0 + math:cos(T/20)), %% radius + D = math:pi() * 2 / N, + [ #{x => X + erlang:round(R * math:cos((TT+T/30)/D)), + y => Y + erlang:round(R * math:sin((TT+T/30)/D))} + || TT <- lists:seq(1, N)]. + +terminate() -> + init:stop(), + exit(normal). diff --git a/examples/planets/start.sh b/examples/planets/start.sh new file mode 100755 index 0000000..19cba3a --- /dev/null +++ b/examples/planets/start.sh @@ -0,0 +1,2 @@ +#!/bin/sh +erl +stbt db -pa ../../ebin -eval "planets:run()."