-
Notifications
You must be signed in to change notification settings - Fork 347
/
Copy pathDrawable.hx
257 lines (221 loc) · 6.33 KB
/
Drawable.hx
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
package h2d;
/**
A base class for all 2D objects that will draw something on the screen.
Unlike Object base class, all properties of Drawable only apply to the current object and are not inherited by its children.
**/
class Drawable extends Object {
/**
The color multiplier for the drawable. Can be used to adjust individually each of the four channels R,G,B,A (default [1,1,1,1])
**/
public var color(default,default) : h3d.Vector4;
/**
By enabling smoothing, scaling the object up or down will use hardware bilinear filtering resulting in a less crisp aspect.
By default smooth is `null` in which case `Scene.defaultSmooth` value is used.
**/
public var smooth : Null<Bool>;
/**
Enables texture uv wrap for this Drawable, causing tiles with uv exceeding the texture size to repeat instead of clamping on edges.
Note that `tileWrap` does not use the `Tile` region as a wrapping area but instead uses underlying `h3d.mat.Texture` size.
This is due to implementation specifics, as it just sets the `Texture.wrap` to either `Repeat` or `Clamp`.
Because of that, proper Tile tiling can be expected only when the tile covers an entire Texture area.
**/
public var tileWrap(default, set) : Bool;
/**
Setting a colorKey color value will discard all pixels that have this exact color in the tile.
**/
public var colorKey(default, set) : Null<Int>;
/**
Setting a colorMatrix will apply a color transformation. See also `adjustColor`.
**/
public var colorMatrix(get, set) : Null<h3d.Matrix>;
/**
Setting colorAdd will add the amount of color of each channel R,G,B,A to the object pixels.
**/
public var colorAdd(get, set) : Null<h3d.Vector>;
var shaders : hxsl.ShaderList;
/**
Create a new Drawable instance with given parent.
@param parent An optional parent `h2d.Object` instance to which Drawable adds itself if set.
**/
function new(parent : h2d.Object) {
super(parent);
color = new h3d.Vector4(1, 1, 1, 1);
}
function set_tileWrap(b) {
return tileWrap = b;
}
function get_colorAdd() {
var s = getShader(h3d.shader.ColorAdd);
return s == null ? null : s.color;
}
function set_colorAdd( c : h3d.Vector ) {
var s = getShader(h3d.shader.ColorAdd);
if( s == null ) {
if( c != null ) {
s = addShader(new h3d.shader.ColorAdd());
s.color = c;
}
} else {
if( c == null )
removeShader(s);
else
s.color = c;
}
return c;
}
override function drawFiltered(ctx:RenderContext, tile:Tile) {
var old = shaders;
shaders = null;
super.drawFiltered(ctx, tile);
shaders = old;
}
function set_colorKey(v:Null<Int>) {
var s = getShader(h3d.shader.ColorKey);
if( s == null ) {
if( v != null )
s = addShader(new h3d.shader.ColorKey(0xFF000000 | v));
} else {
if( v == null )
removeShader(s);
else
s.colorKey.setColor(0xFF000000 | v);
}
return colorKey = v;
}
/**
Set the `Drawable.colorMatrix` value by specifying which effects to apply.
Calling `adjustColor()` without arguments will reset the colorMatrix to `null`.
**/
public function adjustColor( ?col : h3d.Matrix.ColorAdjust ) : Void {
if( col == null )
colorMatrix = null;
else {
var m = colorMatrix;
if( m == null ) {
m = new h3d.Matrix();
colorMatrix = m;
}
m.identity();
m.adjustColor(col);
}
}
function get_colorMatrix() {
var s = getShader(h3d.shader.ColorMatrix);
return s == null ? null : s.matrix;
}
function set_colorMatrix(m:h3d.Matrix) {
var s = getShader(h3d.shader.ColorMatrix);
if( s == null ) {
if( m != null ) {
s = addShader(new h3d.shader.ColorMatrix());
s.matrix = m;
}
} else {
if( m == null )
removeShader(s);
else
s.matrix = m;
}
return m;
}
/**
Returns the first shader of the given shader class among the drawable shaders.
@param stype The class of the shader to look up.
**/
public function getShader< T:hxsl.Shader >( stype : Class<T> ) : T {
if (shaders != null) for( s in shaders ) {
var s = Std.downcast(s, stype);
if( s != null )
return s;
}
return null;
}
/**
Returns an iterator of all drawable shaders
**/
public inline function getShaders() {
return shaders.iterator();
}
/**
Add a shader to the drawable shaders.
Keep in mind, that as stated before, drawable children do not inherit Drawable properties, which includes shaders.
**/
public function addShader<T:hxsl.Shader>( s : T ) : T {
if( s == null ) throw "Can't add null shader";
shaders = hxsl.ShaderList.addSort(s, shaders);
return s;
}
/**
Remove a shader from the drawable shaders, returns true if found or false if it was not part of our shaders.
**/
public function removeShader( s : hxsl.Shader ) {
var prev = null, cur = shaders;
while( cur != null ) {
if( cur.s == s ) {
if( prev == null )
shaders = cur.next;
else
prev.next = cur.next;
return true;
}
prev = cur;
cur = cur.next;
}
return false;
}
override function emitTile( ctx : RenderContext, tile : Tile ) {
if( tile == null )
tile = new Tile(null, 0, 0, 5, 5);
if( !ctx.hasBuffering() ) {
if( !ctx.drawTile(this, tile) ) return;
return;
}
if( !ctx.beginDrawBatch(this, tile.getTexture()) ) return;
var alpha = color.a * ctx.globalAlpha;
var ax = absX + tile.dx * matA + tile.dy * matC;
var ay = absY + tile.dx * matB + tile.dy * matD;
var buf = ctx.buffer;
var pos = ctx.bufPos;
buf.grow(pos + 4 * 8);
inline function emit(v:Float) buf[pos++] = v;
emit(ax);
emit(ay);
emit(tile.u);
emit(tile.v);
emit(color.r);
emit(color.g);
emit(color.b);
emit(alpha);
var tw = tile.width;
var th = tile.height;
var dx1 = tw * matA;
var dy1 = tw * matB;
var dx2 = th * matC;
var dy2 = th * matD;
emit(ax + dx1);
emit(ay + dy1);
emit(tile.u2);
emit(tile.v);
emit(color.r);
emit(color.g);
emit(color.b);
emit(alpha);
emit(ax + dx2);
emit(ay + dy2);
emit(tile.u);
emit(tile.v2);
emit(color.r);
emit(color.g);
emit(color.b);
emit(alpha);
emit(ax + dx1 + dx2);
emit(ay + dy1 + dy2);
emit(tile.u2);
emit(tile.v2);
emit(color.r);
emit(color.g);
emit(color.b);
emit(alpha);
ctx.bufPos = pos;
}
}