gamnit and related: improve doc
[nit.git] / lib / gamnit / depth / depth_core.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Base entities of the depth 3D game framework
16 module depth_core
17
18 intrude import gamnit::flat
19
20 # Visible 3D entity in the game world
21 #
22 # Similar to `gamnit::Sprite` which is in 2D.
23 #
24 # Each actor associates a `model` to the position `center`.
25 # The appearance is modified by `rotation`, `scale` and `alpha`,
26 # as well as the attributes of `model` itself.
27 #
28 # ~~~
29 # import gamnit::depth
30 #
31 # # Load model from the assets folder
32 # var model = new Model("path/in/assets.obj")
33 #
34 # # Create and configure an actor
35 # var actor = new Actor(model, new Point3d[Float](0.0, 0.0, 0.0))
36 # actor.scale = 2.0
37 #
38 # # Add to the visible game world
39 # app.actors.add actor
40 # ~~~
41 class Actor
42
43 # Model used to draw this actor
44 var model: Model
45
46 # Position of this sprite in world coordinates
47 var center: Point3d[Float] is writable
48
49 # Rotation on the Z axis
50 var rotation = 0.0 is writable
51
52 # Scale applied to the model
53 var scale = 1.0 is writable
54
55 # Transparency applied to the model on draw
56 #
57 # This value may be ignored by some materials.
58 # Non-opaque values may result in artifacts as there is no specialized
59 # support for transparent models and the depth buffer.
60 var alpha = 1.0 is writable
61 end
62
63 # 3D model composed of `Mesh` and `Material`, loaded from the assets folder by default
64 #
65 # Instances can be created at any time and must be loaded after or at the end of `on_create`.
66 # If loading fails, the model is replaced by `placeholder_model`.
67 #
68 # ~~~
69 # import gamnit::depth
70 #
71 # var model = new Model("path/in/assets.obj")
72 # model.load
73 # ~~~
74 #
75 # The most simple model is `LeafModel`, composed of a single `Mesh` and `Material`.
76 # It can be easily created programmatically to display simple geometries.
77 # Whereas `CompositeModel` is composed of one or many `LeafModel` and is usually
78 # loaded from the assets folder as a `ModelAsset`.
79 # Instances of `ModelAsset` must be in the format OBJ and MAT,
80 # and their texture in PNG or JPG.
81 abstract class Model
82
83 # Load this model in memory
84 fun load do end
85
86 # All `LeafModel` composing this model
87 #
88 # Usually, there is one `LeafModel` per material.
89 # At each frame, each material is asked to draw all the live `LeafModel` instaces.
90 fun leaves: Array[LeafModel] is abstract
91 end
92
93 # Model composed of one or many other `LeafModel`
94 class CompositeModel
95 super Model
96
97 redef var leaves = new Array[LeafModel]
98 end
99
100 # Basic model with a single `mesh` and `material`
101 #
102 # Only leaves are actually drawn by the `material`.
103 class LeafModel
104 super Model
105
106 # Mesh forming this model
107 var mesh: Mesh
108
109 # Material applied on this model
110 var material: Material
111
112 redef var leaves = [self]
113 end
114
115 # Material for models, or how to draw the model
116 #
117 # To create a simple basic blueish material, use `new Material`.
118 #
119 # Each class of material is associated to a `GLProgram` and its GPU shaders.
120 # The simple material `SmoothMaterial` allows to set an ambient, diffuse and specular color.
121 # To which `TextureMaterial` adds three textures, for each kind of light.
122 # The `NormalsMaterial` may be useful for debugging, it show the orientation of
123 # the normal vectors as colors.
124 #
125 # ~~~
126 # import gamnit::depth
127 #
128 # var blueish_material = new Material
129 # var redish_material = new SmoothMaterial([0.3, 0.0, 0.0],
130 # [0.6, 0.0, 0.0],
131 # [1.0, 1.0, 1.0])
132 # var normals_material = new NormalsMaterial
133 # ~~~
134 abstract class Material
135
136 # Draw a `model` from `actor`
137 #
138 # This method should be refined by subclasses as the default implementation is a no-op.
139 #
140 # This method is called on many materials for many `actor` and `model` at each frame.
141 # It is expected to use a `GLProgram` and call an equivalent to `glDrawArrays`.
142 # However, it should not call `glClear` nor `GamnitDisplay::flip`.
143 fun draw(actor: Actor, model: LeafModel) do end
144 end
145
146 # Mesh with all geometry data
147 #
148 # May be created via `Plane`, `Cube` or `UVSphere`,
149 # or loaded from the assets folder indirectly with a `Model`.
150 #
151 # ~~~
152 # import gamnit::depth
153 #
154 # var plane = new Plane
155 # var cube = new Cube
156 # var sphere = new UVSphere(1.0, 32, 16)
157 # ~~~
158 class Mesh
159
160 # Vertices coordinates
161 var vertices = new Array[Float] is lazy, writable
162
163 # Indices to draw triangles with `glDrawElements`
164 #
165 # If `not_empty`, use `glDrawElements`, otherwise use `glDrawArrays`.
166 var indices = new Array[Int] is lazy, writable
167
168 private var indices_c = new CUInt16Array.from(indices) is lazy, writable
169
170 # Normals on each vertex
171 var normals = new Array[Float] is lazy, writable
172
173 # Coordinates on the texture per vertex
174 var texture_coords = new Array[Float] is lazy, writable
175
176 # `GLDrawMode` used to display this mesh, defaults to `gl_TRIANGLES`
177 fun draw_mode: GLDrawMode do return gl_TRIANGLES
178 end
179
180 # Source of light
181 #
182 # Instances of this class define a light source position and type.
183 class Light
184
185 # TODO point light, spotlight, directional light, etc.
186
187 # Center of this light source in world coordinates
188 var position = new Point3d[Float](0.0, 1000.0, 0.0)
189 end
190
191 redef class App
192
193 # Live actors to be drawn on screen
194 var actors = new Array[Actor]
195
196 # Single light of the scene
197 var light = new Light
198
199 # TODO move `actors & light` to a scene object
200 # TODO support more than 1 light
201 end