22Effects
33=======
44
5- In order to actually draw something to the screen you need to make one or
5+ In order to actually render something to the screen you need to make one or
66multiple effects. What these effects are doing is entirely up to you.
7- Some like to put everything into one effect and switch what they draw by
8- flipping some internal states, but this is probably not practical for more
9- complex things .
7+ Effects have methods for fetching loaded resources and existing effect instances.
8+ Effects can also create new instances of effects if needed. This would
9+ happend during initialization .
1010
11- An effect is a class with references to resources such as shaders, geometry,
12- fbos and textures and a method for drawing. An effect is an independent python
13- package of specific format.
11+ Effect examples can be found in the ``examples `` directory in the root of the repository.
1412
1513The Effect Package
1614------------------
@@ -21,133 +19,67 @@ named "cube").
2119.. code-block :: bash
2220
2321 cube
24- ├── effect.py
25- ├── shaders
26- │ └── cube
27- │ └── ...
28- └── textures
29- └── cube
30- └── ...
22+ ├── effects.py
23+ ├── dependencies.py
24+ └── resources
25+ └── programs
26+ └── cube
27+ └── cube.glsl
28+ └── textures
29+ └── scenes
30+ └── data
3131
32- The ``effect.py `` module is the actual code for the effect. Directories at the
33- same level are for local resources for the effect.
32+ The ``effects.py `` module can contain one or multiple effects.
33+ The effect package can also have no effects and all and only
34+ provide resources for other effects to use. The ``effects.py ``
35+ module is still required to be present.
3436
35- .. Note :: Notice that the resource directories contains another sub-directory
36- with the same name as the effect directory/package. This is because these
37- folders are by default added to a project wide search path
38- (for each resource type),
39- so we should place it in a directory to reduce the chance of a name collisions.
37+ Dependencies
38+ ------------
4039
41- We can also decide not to have any effect-local resources and configure
42- a project-global resource directory. More about this ` settings ` .
40+ The `` dependencies.py `` module is required to be present. It describes
41+ its own resources and what effect packages it may depend on .
4342
44- Registry
45- --------
43+ Example::
4644
47- For an effect to be recognised by the system, it has to be registered
48- in the ``EFFECTS `` tuple/list in your settings module.
49- Simply add the full python path to the package. If our cube example
50- above is located inside a ``myproject `` project package we need to add
51- the string ``myproject.cube ``. See `settings `.
45+ from demosys.resources.meta import ProgramDescription
5246
53- You can always run a single effect by using the ``runeffect `` command.
47+ effect_packages =
48+ 'full.python.path.to.another.package',
49+ ]
5450
55- .. code-block :: bash
56-
57- ./manage.py runeffect myproject.cube
51+ resources = [
52+ ProgramDescription(label='cube_plain', path='cube_plain.glsl'),
53+ ]
5854
59- If you have multiple effects, you need to crate or use an existing
60- :doc: `effectmanagers ` that will decide what effect would be active at
61- what time or state.
55+ Resources are given labels and effects can fetch them by this label.
56+ When adding effect package dependencies we make the system aware
57+ of this package so their resources are also loaded. The effects
58+ in the depending package will also be registered in the system
59+ and can be instantiated.
6260
6361Resources
6462---------
6563
66- Resource loading is baked into the ``Effect `` base class. Methods are inherited
67- from the base ``Effect `` class such as ``get_shader `` and ``get_texture ``.
68-
69- Methods fetching resources can take additional parameters to override defaults.
70-
71- .. code-block :: python
72-
73- # Generate mipmaps for the texture
74- self .get_texture(" cube/texture.png" , mipmap = True )
75-
76- The Effect Module
77- -----------------
78-
79- The effect module needs to be named ``effect.py `` and
80- located in the root of the effect package. It can only contain a single effect
81- class. The name of the class doesn't matter right now, but we are
82- considering allowing multiple effects in the future, so giving it
83- at least a descriptive name is a good idea.
84-
85- There are two important methods in an effect:
86-
87- - ``__init__() ``
88- - ``draw() ``
89-
90- The **initializer ** is called before resources are loaded. This way the
91- effects can register the resources they need. An opengl context should
92- exist.
93-
94- The ``draw `` method is called by the configured `EffectManager``
95- (see :doc: `effectmanagers `) ever frame, or at least every frame
96- the manager decides the effect should be active.
64+ The ``resources `` directory contains fixed directory names where resources
65+ of specific types are supposed to be located. When an effect package is loaded
66+ paths to these directories are added so the system can find them.
9767
98- The standard effect example:
99-
100- .. code-block :: python
101-
102- import moderngl as mgl
103- from demosys.effects import effect
104- from demosys import geometry
105- # from pyrr import matrix44
106-
107-
108- class SimpleCubeEffect (effect .Effect ):
109- """ Generated default effect"""
110- def __init__ (self ):
111- self .shader = self .get_shader(" cube_plain.glsl" , local = True )
112- self .cube = geometry.cube(4.0 , 4.0 , 4.0 )
113-
114- @effect.bind_target
115- def draw (self , time , frametime , target ):
116- self .ctx.enable(mgl.DEPTH_TEST )
117-
118- # Rotate and translate
119- m_mv = self .create_transformation(rotation = (time * 1.2 , time * 2.1 , time * 0.25 ),
120- translation = (0.0 , 0.0 , - 8.0 ))
121-
122- # Apply the rotation and translation from the system camera
123- # m_mv = matrix44.multiply(m_mv, self.sys_camera.view_matrix)
124-
125- # Create normal matrix from model-view
126- m_normal = self .create_normal_matrix(m_mv)
127-
128- # Draw the cube
129- self .shader.uniform(" m_proj" , self .sys_camera.projection.tobytes())
130- self .shader.uniform(" m_mv" , m_mv.astype(' f4' ).tobytes())
131- self .shader.uniform(" m_normal" , m_normal.astype(' f4' ).tobytes())
132- self .shader.uniform(" time" , time)
133- self .cube.draw(self .shader)
134-
135- The parameters in the draw effect is:
136-
137- - ``time ``: The current time reported by our configured ``Timer `` in seconds.
138- - ``frametime ``: The time a frame is expected to take in seconds.
139- - ``target `` is the target FBO of the effect
68+ .. Note :: Notice that the resource directories contains another sub-directory
69+ with the same name as the effect package. This is because these
70+ folders are by default added to a project wide search path
71+ (for each resource type),
72+ so we should place it in a directory to reduce the chance of a name collisions.
14073
141- Time can potentially move at any speed or direction, so it's good practice
142- to make sure the effect can run when time is moving in any direction.
74+ Having resources in the effect package itself is entirely optional.
75+ Resources can be located anywhere you want as long as you tell the system
76+ where they can be found. This is covered in :doc: `/settings `.
14377
144- The ``bind_target `` decorator is useful when you want to ensure
145- that an FBO passed to the effect is bound on entry and released on exit.
146- By default a fake FBO is passed in representing the window frame buffer.
147- EffectManagers can be used to pass in your own FBOs or another effect
148- can call ``draw(..) `` requesting the result to end up in the FBO it passes in
149- and then use this FBO as a texture on a cube or do post processing.
78+ Reasons to have resources in effect packages is to create an independent
79+ resuable effect package you could even distribute. Also when a project
80+ grows with lots of effect packages it can be nice to keep the effect
81+ specific resources in the effect package they belong to instead of
82+ putting all resources for the entire project in the same location.
15083
151- As we can see in the example, the ``Effect `` base class have a couple
152- of convenient methods for doing basic matrix math, but generally you
153- are expected do to these calculations yourself.
84+ The Effect base class have methods avaiable for fetching loaded resources.
85+ See the :py:class: `demosys.effects.Effect `
0 commit comments