hate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +95 -0
- data/Rakefile +17 -0
- data/bin/hate +7 -0
- data/example/main.rb +95 -0
- data/lib/hate.rb +16 -0
- data/lib/hate/audio.rb +0 -0
- data/lib/hate/core.rb +123 -0
- data/lib/hate/game.rb +6 -0
- data/lib/hate/graphics.rb +19 -0
- data/lib/hate/graphics/camera.rb +39 -0
- data/lib/hate/graphics/color.rb +9 -0
- data/lib/hate/graphics/light.rb +19 -0
- data/lib/hate/graphics/manager.rb +73 -0
- data/lib/hate/graphics/shader.rb +61 -0
- data/lib/hate/graphics/shaders/lights/point.fragment +31 -0
- data/lib/hate/graphics/shaders/lights/point.vertex +27 -0
- data/lib/hate/graphics/shapes.rb +118 -0
- data/lib/hate/graphics/window.rb +105 -0
- data/lib/hate/input.rb +35 -0
- data/lib/hate/network.rb +0 -0
- data/lib/hate/physics.rb +0 -0
- data/lib/hate/system.rb +0 -0
- data/lib/util/gl.rb +206 -0
- data/lib/util/trollop.rb +782 -0
- metadata +100 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
module Hate
|
2
|
+
module Graphics
|
3
|
+
module Manager
|
4
|
+
|
5
|
+
@objects = []
|
6
|
+
@shaders = []
|
7
|
+
@lights = []
|
8
|
+
@cameras = []
|
9
|
+
|
10
|
+
def self.lights
|
11
|
+
@lights
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run
|
15
|
+
@cameras.each do |obj|
|
16
|
+
obj.run
|
17
|
+
end
|
18
|
+
|
19
|
+
@objects.each do |obj|
|
20
|
+
obj.run
|
21
|
+
end
|
22
|
+
|
23
|
+
@shaders.each do |obj|
|
24
|
+
obj.run
|
25
|
+
end
|
26
|
+
|
27
|
+
@lights.each do |obj|
|
28
|
+
obj.run
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.add_object(obj)
|
33
|
+
@objects << obj
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.remove_object(obj)
|
37
|
+
@objects.delete obj
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.add_shader(obj)
|
41
|
+
@shaders << obj
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.remove_shader(obj)
|
45
|
+
@shaders.delete obj
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.add_light(obj)
|
49
|
+
@lights << obj
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.remove_light(obj)
|
53
|
+
@lights.delete obj
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.add_camera(obj)
|
57
|
+
@cameras << obj
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.remove_camera(obj)
|
61
|
+
@cameras.delete obj
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.default_camera
|
65
|
+
add_camera Hate::Graphics::Camera.new if @cameras.empty?
|
66
|
+
@cameras.each do |obj|
|
67
|
+
return obj if obj.is_default?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Hate
|
2
|
+
module Graphics
|
3
|
+
module Shader
|
4
|
+
|
5
|
+
class Program
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@program = glCreateProgram
|
9
|
+
end
|
10
|
+
|
11
|
+
def attach(shader)
|
12
|
+
glAttachShader(@program, shader)
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def compile
|
17
|
+
glLinkProgram(@program)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
glUseProgram(@program)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class Base
|
28
|
+
|
29
|
+
attr_reader :shader
|
30
|
+
|
31
|
+
def initialize(file)
|
32
|
+
source = []
|
33
|
+
source << MemoryPointer.from_string(File.open(file).read)
|
34
|
+
arg = MemoryPointer.new(:pointer, source.length)
|
35
|
+
source.each_with_index do |p, i|
|
36
|
+
arg[i].put_pointer(0, p)
|
37
|
+
end
|
38
|
+
|
39
|
+
if self.class == Hate::Graphics::Shader::Vertex
|
40
|
+
@shader = glCreateShader(GL_VERTEX_SHADER)
|
41
|
+
elsif self.class == Hate::Graphics::Shader::Fragment
|
42
|
+
@shader = glCreateShader(GL_FRAGMENT_SHADER)
|
43
|
+
end
|
44
|
+
|
45
|
+
glShaderSource(@shader, source.size, arg, nil)
|
46
|
+
glCompileShader(@shader)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class Vertex < Base
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
class Fragment < Base
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
varying vec4 diffuse,ambientGlobal, ambient;
|
2
|
+
varying vec3 normal,lightDir,halfVector;
|
3
|
+
varying float dist;
|
4
|
+
|
5
|
+
void main()
|
6
|
+
{
|
7
|
+
vec3 n,halfV,viewV,ldir;
|
8
|
+
float NdotL,NdotHV;
|
9
|
+
vec4 color = ambientGlobal;
|
10
|
+
float att;
|
11
|
+
/* a fragment shader can't write a varying variable, hence we need
|
12
|
+
|
13
|
+
a new variable to store the normalized interpolated normal */
|
14
|
+
n = normalize(normal);
|
15
|
+
/* compute the dot product between normal and normalized lightdir */
|
16
|
+
|
17
|
+
NdotL = max(dot(n,normalize(lightDir)),0.0);
|
18
|
+
if (NdotL > 0.0) {
|
19
|
+
|
20
|
+
att = 1.0 / (gl_LightSource[0].constantAttenuation +
|
21
|
+
gl_LightSource[0].linearAttenuation * dist +
|
22
|
+
gl_LightSource[0].quadraticAttenuation * dist * dist);
|
23
|
+
color += att * (diffuse * NdotL + ambient);
|
24
|
+
halfV = normalize(halfVector);
|
25
|
+
|
26
|
+
NdotHV = max(dot(n,halfV),0.0);
|
27
|
+
color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular *
|
28
|
+
pow(NdotHV,gl_FrontMaterial.shininess);
|
29
|
+
}
|
30
|
+
gl_FragColor = color;
|
31
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
varying vec4 diffuse,ambientGlobal,ambient;
|
2
|
+
varying vec3 normal,lightDir,halfVector;
|
3
|
+
varying float dist;
|
4
|
+
|
5
|
+
void main()
|
6
|
+
{
|
7
|
+
vec4 ecPos;
|
8
|
+
vec3 aux;
|
9
|
+
normal = normalize(gl_NormalMatrix * gl_Normal);
|
10
|
+
|
11
|
+
/* these are the new lines of code to compute the light's direction */
|
12
|
+
ecPos = gl_ModelViewMatrix * gl_Vertex;
|
13
|
+
aux = vec3(gl_LightSource[0].position-ecPos);
|
14
|
+
lightDir = normalize(aux);
|
15
|
+
dist = length(aux);
|
16
|
+
halfVector = normalize(gl_LightSource[0].halfVector.xyz);
|
17
|
+
|
18
|
+
/* Compute the diffuse, ambient and globalAmbient terms */
|
19
|
+
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
|
20
|
+
/* The ambient terms have been separated since one of them */
|
21
|
+
|
22
|
+
/* suffers attenuation */
|
23
|
+
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
|
24
|
+
ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
|
25
|
+
gl_Position = ftransform();
|
26
|
+
|
27
|
+
}
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Hate
|
2
|
+
module Graphics
|
3
|
+
module Shapes
|
4
|
+
|
5
|
+
class Base
|
6
|
+
|
7
|
+
attr_accessor :memory, :size
|
8
|
+
attr_reader :x, :y, :z
|
9
|
+
attr_reader :ra, :rx, :ry, :rz
|
10
|
+
attr_reader :c
|
11
|
+
|
12
|
+
def initialize(s=1.0)
|
13
|
+
@size = s
|
14
|
+
|
15
|
+
@memory = nil
|
16
|
+
compile
|
17
|
+
|
18
|
+
translate
|
19
|
+
rotate
|
20
|
+
color
|
21
|
+
end
|
22
|
+
|
23
|
+
def translate(x=0.0, y=0.0, z=0.0)
|
24
|
+
@x, @y, @z = x, y, z
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def rotate(a=0.0, x=0.0, y=0.0, z=0.0)
|
29
|
+
@ra, @rx, @ry, @rz = a, x, y, z
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def color(r=0.0, g=0.0, b=0.0)
|
34
|
+
@c = [r, g, b]
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def compile
|
39
|
+
@memory = glGenLists(1) if @memory.nil?
|
40
|
+
glNewList(@memory, GL_COMPILE)
|
41
|
+
build
|
42
|
+
glEndList
|
43
|
+
end
|
44
|
+
|
45
|
+
def run
|
46
|
+
glLoadIdentity
|
47
|
+
glPushMatrix
|
48
|
+
glColor3f(@c[0], @c[1], @c[2])
|
49
|
+
glTranslatef(@x, @y, @z)
|
50
|
+
glRotatef(@ra, @rx, @ry, @rz)
|
51
|
+
@memory.nil? ? build : glCallList(@memory)
|
52
|
+
glPopMatrix
|
53
|
+
end
|
54
|
+
|
55
|
+
def destroy
|
56
|
+
glDeleteLists(@memory)
|
57
|
+
@memory = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
class Square < Base
|
63
|
+
|
64
|
+
def build
|
65
|
+
glutSolidCube(@size)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
class Cube < Base
|
71
|
+
|
72
|
+
def build
|
73
|
+
glBegin(GL_QUADS)
|
74
|
+
|
75
|
+
glNormal3f(0.0, 0.0, 1.0)
|
76
|
+
glVertex3f( @size, @size,-@size)
|
77
|
+
glVertex3f(-@size, @size,-@size)
|
78
|
+
glVertex3f(-@size, @size, @size)
|
79
|
+
glVertex3f( @size, @size, @size)
|
80
|
+
|
81
|
+
glNormal3f(0.0, 0.0, -1.0)
|
82
|
+
glVertex3f( @size,-@size, @size)
|
83
|
+
glVertex3f(-@size,-@size, @size)
|
84
|
+
glVertex3f(-@size,-@size,-@size)
|
85
|
+
glVertex3f( @size,-@size,-@size)
|
86
|
+
|
87
|
+
glNormal3f(0.0, 1.0, 0.0)
|
88
|
+
glVertex3f( @size, @size, @size)
|
89
|
+
glVertex3f(-@size, @size, @size)
|
90
|
+
glVertex3f(-@size,-@size, @size)
|
91
|
+
glVertex3f( @size,-@size, @size)
|
92
|
+
|
93
|
+
glNormal3f(0.0, -1.0, 0.0)
|
94
|
+
glVertex3f( @size,-@size,-@size)
|
95
|
+
glVertex3f(-@size,-@size,-@size)
|
96
|
+
glVertex3f(-@size, @size,-@size)
|
97
|
+
glVertex3f( @size, @size,-@size)
|
98
|
+
|
99
|
+
glNormal3f(1.0, 0.0, 0.0)
|
100
|
+
glVertex3f(-@size, @size, @size)
|
101
|
+
glVertex3f(-@size, @size,-@size)
|
102
|
+
glVertex3f(-@size,-@size,-@size)
|
103
|
+
glVertex3f(-@size,-@size, @size)
|
104
|
+
|
105
|
+
glNormal3f(-1.0, 0.0, 0.0)
|
106
|
+
glVertex3f(@size, @size,-@size)
|
107
|
+
glVertex3f(@size, @size, @size)
|
108
|
+
glVertex3f(@size,-@size, @size)
|
109
|
+
glVertex3f(@size,-@size,-@size)
|
110
|
+
|
111
|
+
glEnd
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Hate
|
2
|
+
module Graphics
|
3
|
+
|
4
|
+
DEFAULT_WIDTH = 800
|
5
|
+
DEFAULT_HEIGHT = 600
|
6
|
+
DEFAULT_COLOR = nil
|
7
|
+
DEFAULT_BACKGROUND = nil
|
8
|
+
|
9
|
+
class Window
|
10
|
+
|
11
|
+
attr_reader :width, :height
|
12
|
+
attr_reader :frames
|
13
|
+
|
14
|
+
def initialize(w=nil, h=nil, title='New Game')
|
15
|
+
@width = w || Hate::Graphics::DEFAULT_WIDTH
|
16
|
+
@height = h || Hate::Graphics::DEFAULT_HEIGHT
|
17
|
+
|
18
|
+
@frames = 0
|
19
|
+
|
20
|
+
if SDL.Init(SDL::INIT_EVERYTHING) == 0
|
21
|
+
SDL.EnableUNICODE(1)
|
22
|
+
else
|
23
|
+
throw Main::Graphics::SDLException, "SDL Exception: #{SDL.GetError()}"
|
24
|
+
end
|
25
|
+
SDL.SetVideoMode(@width, @height, 24, SDL::OPENGL)
|
26
|
+
SDL.Init(SDL::INIT_VIDEO)
|
27
|
+
|
28
|
+
glEnable(GL_DEPTH_TEST)
|
29
|
+
glEnable(GL_CULL_FACE)
|
30
|
+
glEnable(GL_COLOR_MATERIAL)
|
31
|
+
|
32
|
+
glShadeModel(GL_SMOOTH)
|
33
|
+
glClearColor(1.0, 1.0, 1.0, 0.0)
|
34
|
+
glClearDepth(1.0)
|
35
|
+
glDepthFunc(GL_LEQUAL)
|
36
|
+
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Small performance hit
|
37
|
+
|
38
|
+
# Hardware lights
|
39
|
+
Hate::Graphics::Manager.lights.each_with_index do |light, i|
|
40
|
+
glLightfv(eval("GL_LIGHT%i" % (i + 1)), GL_AMBIENT, light.ambient)
|
41
|
+
glLightfv(eval("GL_LIGHT%i" % (i + 1)), GL_DIFFUSE, light.diffuse)
|
42
|
+
glLightfv(eval("GL_LIGHT%i" % (i + 1)), GL_POSITION, light.position)
|
43
|
+
glEnable(eval("GL_LIGHT%i" % (i + 1)))
|
44
|
+
end
|
45
|
+
glEnable(GL_LIGHTING) if Hate::Graphics::Manager.lights.size > 0
|
46
|
+
|
47
|
+
reshape(@width, @height)
|
48
|
+
end
|
49
|
+
|
50
|
+
def draw
|
51
|
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
52
|
+
Hate::Core::Callbacks.draw
|
53
|
+
Hate::Graphics::Manager.run
|
54
|
+
SDL.GL_SwapBuffers()
|
55
|
+
@frames += 1
|
56
|
+
end
|
57
|
+
|
58
|
+
def reshape(x, y)
|
59
|
+
Hate::Graphics::Manager.default_camera.reshape(x, y)
|
60
|
+
end
|
61
|
+
|
62
|
+
def update
|
63
|
+
until (event = SDL::PollEvent()).nil?
|
64
|
+
events(event)
|
65
|
+
end
|
66
|
+
Hate::Core::Callbacks.update if @frames % 2 == 0 # Only call update every second cycle
|
67
|
+
end
|
68
|
+
|
69
|
+
def events(event)
|
70
|
+
case event.type
|
71
|
+
when SDL::KEYDOWN
|
72
|
+
Hate::Input::Keyboard.pressed(event.keysym.sym)
|
73
|
+
when SDL::KEYUP
|
74
|
+
Hate::Input::Keyboard.released(event.keysym.sym)
|
75
|
+
when SDL::MOUSEBUTTONDOWN
|
76
|
+
Hate::Input::Mouse.pressed(event.x, event.y, event.button)
|
77
|
+
when SDL::MOUSEBUTTONUP
|
78
|
+
Hate::Input::Mouse.released(event.x, event.y, event.button)
|
79
|
+
when SDL::MOUSEMOTION
|
80
|
+
Hate::Input::Mouse.motion(event.x, event.y, event.xrel, event.yrel, event.state)
|
81
|
+
when SDL::VIDEORESIZE
|
82
|
+
reshape(event.w, event.h)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def time
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def start
|
91
|
+
loop do
|
92
|
+
update
|
93
|
+
draw
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def quit
|
98
|
+
SDL.QuitSubSystem(SDL::INIT_VIDEO)
|
99
|
+
SDL.Quit
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
data/lib/hate/input.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Hate
|
2
|
+
module Input
|
3
|
+
module Keyboard
|
4
|
+
|
5
|
+
@key_states = Array.new(256)
|
6
|
+
|
7
|
+
def self.pressed(k)
|
8
|
+
@key_states[k] = true
|
9
|
+
Hate::Core::Callbacks.keypressed(k)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.released(k)
|
13
|
+
@key_states[k] = false
|
14
|
+
Hate::Core::Callbacks.keyreleased(k)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module Mouse
|
20
|
+
|
21
|
+
def self.pressed(x, y, button)
|
22
|
+
Hate::Core::Callbacks.mousepressed(x, y, button)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.released(x, y, button)
|
26
|
+
Hate::Core::Callbacks.mousereleased(x, y, button)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.motion(x, y, xr, yr, state)
|
30
|
+
Hate::Core::Callbacks.mousemotion(x, y, xr, yr, state)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|