1
- -- push.lua v0.2
1
+ -- push.lua v0.4
2
2
3
- -- Copyright (c) 2017 Ulysse Ramage
3
+ -- Copyright (c) 2020 Ulysse Ramage
4
4
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
5
-- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
7
8
+ local love11 = love .getVersion () == 11
9
+ local getDPI = love11 and love .window .getDPIScale or love .window .getPixelScale
10
+ local windowUpdateMode = love11 and love .window .updateMode or function (width , height , settings )
11
+ local _ , _ , flags = love .window .getMode ()
12
+ for k , v in pairs (settings ) do flags [k ] = v end
13
+ love .window .setMode (width , height , flags )
14
+ end
15
+
8
16
local push = {
9
17
10
18
defaults = {
11
19
fullscreen = false ,
12
20
resizable = false ,
13
21
pixelperfect = false ,
14
22
highdpi = true ,
15
- canvas = true
23
+ canvas = true ,
24
+ stencil = true
16
25
}
17
26
18
27
}
19
28
setmetatable (push , push )
20
29
21
- -- TODO: rendering resolution?
22
- -- TODO: clean up code
23
-
24
30
function push :applySettings (settings )
25
31
for k , v in pairs (settings ) do
26
32
self [" _" .. k ] = v
@@ -39,11 +45,11 @@ function push:setupScreen(WWIDTH, WHEIGHT, RWIDTH, RHEIGHT, settings)
39
45
self :applySettings (self .defaults ) -- set defaults first
40
46
self :applySettings (settings ) -- then fill with custom settings
41
47
42
- love . window . setMode ( self ._RWIDTH , self ._RHEIGHT , {
48
+ windowUpdateMode ( self ._RWIDTH , self ._RHEIGHT , {
43
49
fullscreen = self ._fullscreen ,
44
50
resizable = self ._resizable ,
45
51
highdpi = self ._highdpi
46
- } )
52
+ })
47
53
48
54
self :initValues ()
49
55
@@ -62,25 +68,31 @@ function push:setupScreen(WWIDTH, WHEIGHT, RWIDTH, RHEIGHT, settings)
62
68
end
63
69
64
70
function push :setupCanvas (canvases )
65
- table.insert (canvases , { name = " _render" }) -- final render
71
+ table.insert (canvases , { name = " _render" , private = true }) -- final render
66
72
67
73
self ._canvas = true
68
74
self .canvases = {}
69
75
70
76
for i = 1 , # canvases do
71
- self .canvases [i ] = {
72
- name = canvases [i ].name ,
73
- shader = canvases [i ].shader ,
74
- canvas = love .graphics .newCanvas (self ._WWIDTH , self ._WHEIGHT )
75
- }
77
+ push :addCanvas (canvases [i ])
76
78
end
77
79
78
80
return self
79
81
end
82
+ function push :addCanvas (params )
83
+ table.insert (self .canvases , {
84
+ name = params .name ,
85
+ private = params .private ,
86
+ shader = params .shader ,
87
+ canvas = love .graphics .newCanvas (self ._WWIDTH , self ._WHEIGHT ),
88
+ stencil = params .stencil or self ._stencil
89
+ })
90
+ end
80
91
81
92
function push :setCanvas (name )
82
93
if not self ._canvas then return true end
83
- return love .graphics .setCanvas ( self :getCanvasTable (name ).canvas )
94
+ local canvasTable = self :getCanvasTable (name )
95
+ return love .graphics .setCanvas ({ canvasTable .canvas , stencil = canvasTable .stencil })
84
96
end
85
97
function push :getCanvasTable (name )
86
98
for i = 1 , # self .canvases do
@@ -98,7 +110,7 @@ function push:setShader(name, shader)
98
110
end
99
111
100
112
function push :initValues ()
101
- self ._PSCALE = self ._highdpi and love . window . getPixelScale () or 1
113
+ self ._PSCALE = ( not love11 and self ._highdpi ) and getDPI () or 1
102
114
103
115
self ._SCALE = {
104
116
x = self ._RWIDTH / self ._WWIDTH * self ._PSCALE ,
@@ -119,19 +131,15 @@ function push:initValues()
119
131
self ._GHEIGHT = self ._RHEIGHT * self ._PSCALE - self ._OFFSET .y * 2
120
132
end
121
133
122
- --[[ DEPRECATED ]] --
123
134
function push :apply (operation , shader )
124
- if operation == " start" then
125
- self :start ()
126
- elseif operation == " finish" or operation == " end" then
127
- self :finish (shader )
128
- end
135
+ self ._drawFunctions [operation ](self , shader )
129
136
end
130
137
131
138
function push :start ()
132
139
if self ._canvas then
133
140
love .graphics .push ()
134
- love .graphics .setCanvas (self .canvases [1 ].canvas )
141
+ love .graphics .setCanvas ({ self .canvases [1 ].canvas , stencil = self .canvases [1 ].stencil })
142
+
135
143
else
136
144
love .graphics .translate (self ._OFFSET .x , self ._OFFSET .y )
137
145
love .graphics .setScissor (self ._OFFSET .x , self ._OFFSET .y , self ._WWIDTH * self ._SCALE .x , self ._WHEIGHT * self ._SCALE .y )
@@ -140,32 +148,73 @@ function push:start()
140
148
end
141
149
end
142
150
151
+ function push :applyShaders (canvas , shaders )
152
+ local _shader = love .graphics .getShader ()
153
+ if # shaders <= 1 then
154
+ love .graphics .setShader (shaders [1 ])
155
+ love .graphics .draw (canvas )
156
+ else
157
+ local _canvas = love .graphics .getCanvas ()
158
+
159
+ local _tmp = self :getCanvasTable (" _tmp" )
160
+ if not _tmp then -- create temp canvas only if needed
161
+ self :addCanvas ({ name = " _tmp" , private = true , shader = nil })
162
+ _tmp = self :getCanvasTable (" _tmp" )
163
+ end
164
+
165
+ love .graphics .push ()
166
+ love .graphics .origin ()
167
+ local outputCanvas
168
+ for i = 1 , # shaders do
169
+ local inputCanvas = i % 2 == 1 and canvas or _tmp .canvas
170
+ outputCanvas = i % 2 == 0 and canvas or _tmp .canvas
171
+ love .graphics .setCanvas (outputCanvas )
172
+ love .graphics .clear ()
173
+ love .graphics .setShader (shaders [i ])
174
+ love .graphics .draw (inputCanvas )
175
+ love .graphics .setCanvas (inputCanvas )
176
+ end
177
+ love .graphics .pop ()
178
+
179
+ love .graphics .setCanvas (_canvas )
180
+ love .graphics .draw (outputCanvas )
181
+ end
182
+ love .graphics .setShader (_shader )
183
+ end
184
+
143
185
function push :finish (shader )
144
186
love .graphics .setBackgroundColor (unpack (self ._borderColor ))
145
187
if self ._canvas then
146
188
local _render = self :getCanvasTable (" _render" )
147
189
148
190
love .graphics .pop ()
149
191
150
- love .graphics .setColor (255 , 255 , 255 )
192
+ local white = love11 and 1 or 255
193
+ love .graphics .setColor (white , white , white )
151
194
152
195
-- draw canvas
153
196
love .graphics .setCanvas (_render .canvas )
154
- for i = 1 , # self .canvases - 1 do -- do not draw _render yet
197
+ for i = 1 , # self .canvases do -- do not draw _render yet
155
198
local _table = self .canvases [i ]
156
- love .graphics .setShader (_table .shader )
157
- love .graphics .draw (_table .canvas )
199
+ if not _table .private then
200
+ local _canvas = _table .canvas
201
+ local _shader = _table .shader
202
+ self :applyShaders (_canvas , type (_shader ) == " table" and _shader or { _shader })
203
+ end
158
204
end
159
205
love .graphics .setCanvas ()
160
-
206
+
161
207
-- draw render
162
208
love .graphics .translate (self ._OFFSET .x , self ._OFFSET .y )
163
- love .graphics .setShader (shader or self :getCanvasTable (" _render" ).shader )
164
- love .graphics .draw (self :getCanvasTable (" _render" ).canvas , 0 , 0 , 0 , self ._SCALE .x , self ._SCALE .y )
209
+ local shader = shader or _render .shader
210
+ love .graphics .push ()
211
+ love .graphics .scale (self ._SCALE .x , self ._SCALE .y )
212
+ self :applyShaders (_render .canvas , type (shader ) == " table" and shader or { shader })
213
+ love .graphics .pop ()
165
214
166
215
-- clear canvas
167
216
for i = 1 , # self .canvases do
168
- love .graphics .setCanvas ( self .canvases [i ].canvas )
217
+ love .graphics .setCanvas (self .canvases [i ].canvas )
169
218
love .graphics .clear ()
170
219
end
171
220
193
242
194
243
-- doesn't work - TODO
195
244
function push :toReal (x , y )
196
- return x + self ._OFFSET .x , y + self ._OFFSET .y
245
+ return x + self ._OFFSET .x , y + self ._OFFSET .y
197
246
end
198
247
199
248
function push :switchFullscreen (winw , winh )
@@ -213,13 +262,12 @@ function push:switchFullscreen(winw, winh)
213
262
214
263
love .window .setFullscreen (self ._fullscreen , " desktop" )
215
264
if not self ._fullscreen and (winw or winh ) then
216
- love . window . setMode (self ._RWIDTH , self ._RHEIGHT ) -- set window dimensions
265
+ windowUpdateMode (self ._RWIDTH , self ._RHEIGHT ) -- set window dimensions
217
266
end
218
267
end
219
268
220
269
function push :resize (w , h )
221
- local pixelScale = love .window .getPixelScale ()
222
- if self ._highdpi then w , h = w / pixelScale , h / pixelScale end
270
+ if self ._highdpi then w , h = w / self ._PSCALE , h / self ._PSCALE end
223
271
self ._RWIDTH = w
224
272
self ._RHEIGHT = h
225
273
self :initValues ()
0 commit comments