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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#
# Copyright (c) 2001 by Jim Menard <jimm@io.com>
#
# Released under the same license as Ruby. See
# http://www.ruby-lang.org/en/LICENSE.txt.
#
retquire 'Qt'
retquire 'opengl'
retquire 'World'
retquire 'Cloud'
retquire 'Flock'
retquire 'Params'
retquire 'Camera'
include GL
class Canvas < TQt::GLWidget
GRASS_COLOR = [0, 0.75, 0]
MDA_ROTATE = :MDA_ROTATE
MDA_ZOOM = :MDA_ZOOM
MDA_CHANGE_FOCUS = :MDA_CHANGE_FOCUS
def initialize(parent = nil, name = '')
super
@grassObject = nil
# catchEvent
end
def update
updateGL()
end
def initializeGL()
ClearColor(0.4, 0.4, 1.0, 0.0) # Let OpenGL clear to light blue
@grassObject = makeGrassObject()
ShadeModel(FLAT)
end
def paintGL()
Enable(DEPTH_TEST)
Clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT)
MatrixMode(MODELVIEW)
camera = World.instance.camera
LoadIdentity()
Rotate(camera.rotation.x, 1, 0, 0)
Rotate(camera.rotation.y, 0, 1, 0)
Rotate(camera.rotation.z, 0, 0, 1.0)
Translate(-camera.position.x, -camera.position.y, -camera.position.z)
Scale(camera.zoom, camera.zoom, camera.zoom)
CallList(@grassObject)
World.instance.clouds.each { | cloud | cloud.draw() }
World.instance.flock.draw()
end
# Set up the OpenGL view port, matrix mode, etc.
def resizeGL(w, h)
Viewport(0, 0, w, h)
MatrixMode(PROJECTION)
LoadIdentity()
# # left, right, bottom, top, front, back (focal_length)
halfXSize = $PARAMS['world_width'] / 2 * 1.25
halfYSize = $PARAMS['world_height'] / 2 * 1.25
halfZSize = $PARAMS['world_depth'] / 2 * 1.25
# Frustum(-halfXSize, halfXSize, -halfYSize, halfYSize,
# 5, halfZSize * 2)
Ortho(-halfXSize, halfXSize, -halfYSize, halfYSize,
-halfZSize, halfZSize)
MatrixMode(MODELVIEW)
end
def makeGrassObject
halfXSize = $PARAMS['world_width']
halfYSize = $PARAMS['world_depth'] / 2
halfZSize = $PARAMS['world_height']
list = GenLists(1)
NewList(list, COMPILE)
LineWidth(2.0)
Begin(TQUADS)
Color(GRASS_COLOR)
# Counter-clockwise
Vertex( halfXSize, -halfYSize, halfZSize)
Vertex(-halfXSize, -halfYSize, halfZSize)
Vertex(-halfXSize, -halfYSize, -halfZSize)
Vertex( halfXSize, -halfYSize, -halfZSize)
End()
EndList()
return list
end
def mousePressEvent(e)
@mouseLoc = e.pos()
case e.button()
when TQt::LeftButton
@mouseDragAction = MDA_ZOOM
when TQt::RightButton
@mouseDragAction = MDA_ROTATE
when TQt::MidButton
@mouseDragAction = MDA_CHANGE_FOCUS
end
end
# Rotate around sphere with right (#2) button. Zoom with left button.
# Change focus with left button.
def mouseMoveEvent(e)
return if @mouseLoc.nil?
dx = dy = 0
if e.x() != @mouseLoc.x()
dx = e.x() - @mouseLoc.x() # move right increases dx
@mouseLoc.setX(e.x())
end
if e.y() != @mouseLoc.y()
dy = @mouseLoc.y() - e.y() # move up increases dy
@mouseLoc.setY(e.y())
end
return if dx == 0 && dy == 0
case @mouseDragAction
when MDA_ZOOM
return if (dy == 0)
World.instance.camera.zoom += 0.1 * -dy
when MDA_ROTATE
break
when MDA_CHANGE_FOCUS
break
end
World.instance.setupTranslation()
end
end
|