-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathlesson02.erl
122 lines (98 loc) · 3.06 KB
/
lesson02.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
-module(lesson02).
-behaviour(wx_object).
-export([init/1, code_change/3, handle_info/2, handle_event/2,
handle_call/3, terminate/2,
start/1]).
-include_lib("wx/include/wx.hrl").
-include_lib("wx/include/gl.hrl").
-include_lib("wx/include/glu.hrl").
-record(state, {
parent,
config,
canvas,
timer,
time
}).
start(Config) ->
wx_object:start_link(?MODULE, Config, []).
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
do_init(Config) ->
Parent = proplists:get_value(parent, Config),
Size = proplists:get_value(size, Config),
Opts = [{size, Size}, {style, ?wxSUNKEN_BORDER}],
GLAttrib = [{attribList, [?WX_GL_RGBA,
?WX_GL_DOUBLEBUFFER,
?WX_GL_MIN_RED, 8,
?WX_GL_MIN_GREEN, 8,
?WX_GL_MIN_BLUE, 8,
?WX_GL_DEPTH_SIZE, 24, 0]}],
Canvas = wxGLCanvas:new(Parent, Opts ++ GLAttrib),
wxGLCanvas:connect(Canvas, size),
wxWindow:hide(Parent),
wxWindow:reparent(Canvas, Parent),
wxWindow:show(Parent),
wxGLCanvas:setCurrent(Canvas),
setup_gl(Canvas),
Timer = timer:send_interval(20, self(), update),
{Parent, #state{parent = Parent, config = Config, canvas = Canvas, timer = Timer}}.
handle_event(#wx{event = #wxSize{size = {W, H}}}, State) ->
case W =:= 0 orelse H =:= 0 of
true -> skip;
_ ->
resize_gl_scene(W, H)
end,
{noreply, State}.
handle_info(update, State) ->
wx:batch(fun() -> render(State) end),
{noreply, State};
handle_info(stop, State) ->
timer:cancel(State#state.timer),
catch wxGLCanvas:destroy(State#state.canvas),
{stop, normal, State}.
handle_call(Msg, _From, State) ->
io:format("Call: ~p~n", [Msg]),
{reply, ok, State}.
code_change(_, _, State) ->
{stop, not_yet_implemented, State}.
terminate(_Reason, State) ->
catch wxGLCanvas:destroy(State#state.canvas),
timer:cancel(State#state.timer),
timer:sleep(300).
resize_gl_scene(Width, Height) ->
gl:viewport(0, 0, Width, Height),
gl:matrixMode(?GL_PROJECTION),
gl:loadIdentity(),
glu:perspective(45.0, Width / Height, 0.1, 100.0),
gl:matrixMode(?GL_MODELVIEW),
gl:loadIdentity().
setup_gl(Win) ->
{W, H} = wxWindow:getClientSize(Win),
resize_gl_scene(W, H),
gl:shadeModel(?GL_SMOOTH),
gl:clearColor(0.0, 0.0, 0.0, 0.0),
gl:clearDepth(1.0),
gl:enable(?GL_DEPTH_TEST),
gl:depthFunc(?GL_LEQUAL),
gl:hint(?GL_PERSPECTIVE_CORRECTION_HINT, ?GL_NICEST),
ok.
render(#state{parent = _Window, canvas = Canvas} = _State) ->
draw(),
wxGLCanvas:swapBuffers(Canvas).
draw() ->
gl:clear(?GL_COLOR_BUFFER_BIT bor ?GL_DEPTH_BUFFER_BIT),
gl:loadIdentity(),
gl:translatef(-1.5, 0.0, -6.0),
gl:'begin'(?GL_TRIANGLES),
gl:vertex3f(0.0, 1.0, 0.0),
gl:vertex3f(-1.0, -1.0, 0.0),
gl:vertex3f(1.0, -1.0, 0.0),
gl:'end'(),
gl:translatef(3.0, 0.0, 0.0),
gl:'begin'(?GL_QUADS),
gl:vertex3f(-1.0, 1.0, 0.0),
gl:vertex3f( 1.0, 1.0, 0.0),
gl:vertex3f( 1.0, -1.0, 0.0),
gl:vertex3f(-1.0, -1.0, 0.0),
gl:'end'(),
ok.