Difference between revisions of "Gradients (日本語)"
(Created page with "==gradient== === 概要 === <source lang="lua">gradient {color1, color2, color3, ..., direction = 'horizontal' or 'vertical'}</source> 引数テーブルの "direction" によ...") |
m |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
− | ==gradient== | + | == gradient (Mesh 版) == |
+ | === 概要 === | ||
+ | <source lang="lua">mesh = gradientMesh( direction, color1, color2, ... )</source> | ||
+ | 階調度全体を一定間隔で均一に配置を行った配色テーブルからグラデーションのオブジェクト (中身は [[Mesh (日本語)|Mesh]]) を作成します。 これは後述のグラデーション関数よりも性能が良いです。 | ||
+ | === 引数 === | ||
+ | {{param|string|direction|グラデーションの方向 ('''horizontal''' または '''vertical''')。}} | ||
+ | {{param|table|color1|最初の配色テーブル。}} | ||
+ | {{param|table|color2|第二の配色テーブル。}} | ||
+ | {{param|table|...|追加の配色テーブル。}} | ||
+ | === 返値 === | ||
+ | {{param|Mesh|mesh|gradient オブジェクト。}} | ||
+ | === ソース === | ||
+ | <source lang="lua"> | ||
+ | -- 色の乗算 | ||
+ | local COLOR_MUL = love._version >= "11.0" and 1 or 255 | ||
+ | |||
+ | function gradientMesh(dir, ...) | ||
+ | -- 方向の判定 | ||
+ | local isHorizontal = true | ||
+ | if dir == "vertical" then | ||
+ | isHorizontal = false | ||
+ | elseif dir ~= "horizontal" then | ||
+ | error("bad argument #1 to 'gradient' (invalid value)", 2) | ||
+ | end | ||
+ | |||
+ | -- 色の判定 | ||
+ | local colorLen = select("#", ...) | ||
+ | if colorLen < 2 then | ||
+ | error("color list is less than two", 2) | ||
+ | end | ||
+ | |||
+ | -- メッシュの生成 | ||
+ | local meshData = {} | ||
+ | if isHorizontal then | ||
+ | for i = 1, colorLen do | ||
+ | local color = select(i, ...) | ||
+ | local x = (i - 1) / (colorLen - 1) | ||
+ | |||
+ | meshData[#meshData + 1] = {x, 1, x, 1, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} | ||
+ | meshData[#meshData + 1] = {x, 0, x, 0, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} | ||
+ | end | ||
+ | else | ||
+ | for i = 1, colorLen do | ||
+ | local color = select(i, ...) | ||
+ | local y = (i - 1) / (colorLen - 1) | ||
+ | |||
+ | meshData[#meshData + 1] = {1, y, 1, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} | ||
+ | meshData[#meshData + 1] = {0, y, 0, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} | ||
+ | end | ||
+ | end | ||
+ | |||
+ | -- 1x1 の画像寸法から成るメッシュを返します | ||
+ | return love.graphics.newMesh(meshData, "strip", "static") | ||
+ | end | ||
+ | </source> | ||
+ | |||
+ | === 注釈 === | ||
+ | 生成された [[Mesh (日本語)|Mesh]] の寸法は 1x1 となります。グラデーションの寸法は [[love.graphics.draw (日本語)|love.graphics.draw]] の尺度係数で決定されます。この異形を使うときは後述の [[#drawinrect|drawinrect]] 関数は不要です (本当に使用する必要はありません)。 | ||
+ | |||
+ | == gradient (Image 版) == | ||
=== 概要 === | === 概要 === | ||
<source lang="lua">gradient {color1, color2, color3, ..., direction = 'horizontal' or 'vertical'}</source> | <source lang="lua">gradient {color1, color2, color3, ..., direction = 'horizontal' or 'vertical'}</source> | ||
− | 引数テーブルの "direction" により指定された方向へ、階調度全体を一定間隔で均一に配置を行った配色テーブルからグラデーションのオブジェクト ( | + | 引数テーブルの "direction" により指定された方向へ、階調度全体を一定間隔で均一に配置を行った配色テーブルからグラデーションのオブジェクト (中身は [[Image (日本語)|Image]]) を作成します。 |
− | === | + | === ソース === |
<source lang="lua"> | <source lang="lua"> | ||
function gradient(colors) | function gradient(colors) | ||
Line 12: | Line 71: | ||
direction = false | direction = false | ||
else | else | ||
− | error("Invalid direction '" .. tostring(direction) "' for gradient. Horizontal or vertical expected.") | + | error("Invalid direction '" .. tostring(direction) .. "' for gradient. Horizontal or vertical expected.") |
end | end | ||
local result = love.image.newImageData(direction and 1 or #colors, direction and #colors or 1) | local result = love.image.newImageData(direction and 1 or #colors, direction and #colors or 1) | ||
Line 29: | Line 88: | ||
end | end | ||
</source> | </source> | ||
− | ==drawinrect== | + | |
+ | == drawinrect == | ||
=== 概要 === | === 概要 === | ||
<source lang="lua">drawinrect(img, x, y, w, h, r, ox, oy, kx, ky)</source> | <source lang="lua">drawinrect(img, x, y, w, h, r, ox, oy, kx, ky)</source> | ||
Line 40: | Line 100: | ||
end | end | ||
</source> | </source> | ||
+ | |||
== 用例 == | == 用例 == | ||
+ | === drawing horizontal rainbow that fills the entire screen using Mesh variant === | ||
+ | <source lang="lua"> | ||
+ | -- assume you already have gradientMesh function | ||
+ | local rainbow | ||
+ | |||
+ | function love.load() | ||
+ | rainbow = gradientMesh("horizontal", | ||
+ | {255, 0, 0}; | ||
+ | {255, 255, 0}; | ||
+ | {0, 255, 0}; | ||
+ | {0, 255, 255}; | ||
+ | {0, 0, 255}; | ||
+ | {255, 0, 0}; | ||
+ | ) | ||
+ | end | ||
+ | |||
+ | function love.draw() | ||
+ | love.graphics.draw(rainbow, 0, 0, 0, love.graphics.getDimensions()) | ||
+ | end | ||
+ | </source> | ||
+ | |||
=== 画面中央に 100 x 100 ピクセルの水平方向の虹 (すなわち、上部は赤であり、下部は紫) を描画します。 === | === 画面中央に 100 x 100 ピクセルの水平方向の虹 (すなわち、上部は赤であり、下部は紫) を描画します。 === | ||
<source lang="lua"> | <source lang="lua"> | ||
Line 59: | Line 141: | ||
end | end | ||
</source> | </source> | ||
+ | |||
=== 画面全体を塗りつぶす垂直方向の白黒領域 (すなわち、左部は黒であり、右部は白) を描画します。 === | === 画面全体を塗りつぶす垂直方向の白黒領域 (すなわち、左部は黒であり、右部は白) を描画します。 === | ||
<source lang="lua"> | <source lang="lua"> | ||
Line 75: | Line 158: | ||
[[Category:Snippets (日本語)]] | [[Category:Snippets (日本語)]] | ||
{{#set:Author=SelectricSimian}} | {{#set:Author=SelectricSimian}} | ||
+ | {{#set:LOVE Version=any}} | ||
{{#set:Description=画像と補間を使用してグラデーションを高速描画します。}} | {{#set:Description=画像と補間を使用してグラデーションを高速描画します。}} |
Latest revision as of 09:52, 17 December 2019
gradient (Mesh 版)
概要
mesh = gradientMesh( direction, color1, color2, ... )
階調度全体を一定間隔で均一に配置を行った配色テーブルからグラデーションのオブジェクト (中身は Mesh) を作成します。 これは後述のグラデーション関数よりも性能が良いです。
引数
string direction
- グラデーションの方向 (horizontal または vertical)。
table color1
- 最初の配色テーブル。
table color2
- 第二の配色テーブル。
table ...
- 追加の配色テーブル。
返値
Mesh mesh
- gradient オブジェクト。
ソース
-- 色の乗算
local COLOR_MUL = love._version >= "11.0" and 1 or 255
function gradientMesh(dir, ...)
-- 方向の判定
local isHorizontal = true
if dir == "vertical" then
isHorizontal = false
elseif dir ~= "horizontal" then
error("bad argument #1 to 'gradient' (invalid value)", 2)
end
-- 色の判定
local colorLen = select("#", ...)
if colorLen < 2 then
error("color list is less than two", 2)
end
-- メッシュの生成
local meshData = {}
if isHorizontal then
for i = 1, colorLen do
local color = select(i, ...)
local x = (i - 1) / (colorLen - 1)
meshData[#meshData + 1] = {x, 1, x, 1, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)}
meshData[#meshData + 1] = {x, 0, x, 0, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)}
end
else
for i = 1, colorLen do
local color = select(i, ...)
local y = (i - 1) / (colorLen - 1)
meshData[#meshData + 1] = {1, y, 1, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)}
meshData[#meshData + 1] = {0, y, 0, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)}
end
end
-- 1x1 の画像寸法から成るメッシュを返します
return love.graphics.newMesh(meshData, "strip", "static")
end
注釈
生成された Mesh の寸法は 1x1 となります。グラデーションの寸法は love.graphics.draw の尺度係数で決定されます。この異形を使うときは後述の drawinrect 関数は不要です (本当に使用する必要はありません)。
gradient (Image 版)
概要
gradient {color1, color2, color3, ..., direction = 'horizontal' or 'vertical'}
引数テーブルの "direction" により指定された方向へ、階調度全体を一定間隔で均一に配置を行った配色テーブルからグラデーションのオブジェクト (中身は Image) を作成します。
ソース
function gradient(colors)
local direction = colors.direction or "horizontal"
if direction == "horizontal" then
direction = true
elseif direction == "vertical" then
direction = false
else
error("Invalid direction '" .. tostring(direction) .. "' for gradient. Horizontal or vertical expected.")
end
local result = love.image.newImageData(direction and 1 or #colors, direction and #colors or 1)
for i, color in ipairs(colors) do
local x, y
if direction then
x, y = 0, i - 1
else
x, y = i - 1, 0
end
result:setPixel(x, y, color[1], color[2], color[3], color[4] or 255)
end
result = love.graphics.newImage(result)
result:setFilter('linear', 'linear')
return result
end
drawinrect
概要
drawinrect(img, x, y, w, h, r, ox, oy, kx, ky)
絶対的な大きさの長方形にて拡大・縮小された画像を描画する便利な関数です(画像の大きさとは相対的な大きさではなく、 love.graphics.draw() が処理するものです)。ほぼに常に拡大・縮小されたものを描画したい理由があるとき、および配色数により境界が変更されることを望まない場合、グラデーションに対して有用です。
ソース
function drawinrect(img, x, y, w, h, r, ox, oy, kx, ky)
return -- 効率的にするためのちょっとした付け足しのための末尾の呼び出し。
love.graphics.draw(img, x, y, r, w / img:getWidth(), h / img:getHeight(), ox, oy, kx, ky)
end
用例
drawing horizontal rainbow that fills the entire screen using Mesh variant
-- assume you already have gradientMesh function
local rainbow
function love.load()
rainbow = gradientMesh("horizontal",
{255, 0, 0};
{255, 255, 0};
{0, 255, 0};
{0, 255, 255};
{0, 0, 255};
{255, 0, 0};
)
end
function love.draw()
love.graphics.draw(rainbow, 0, 0, 0, love.graphics.getDimensions())
end
画面中央に 100 x 100 ピクセルの水平方向の虹 (すなわち、上部は赤であり、下部は紫) を描画します。
require "gradient"
local rainbow = gradient {
direction = 'horizontal';
{255, 0, 0};
{255, 255, 0};
{0, 255, 0};
{0, 255, 255};
{0, 0, 255};
{255, 0, 0};
}
function love.draw()
drawinrect(rainbow, love.graphics.getWidth() / 2 - 50, love.graphics.getHeight() / 2 - 50, 100)
end
画面全体を塗りつぶす垂直方向の白黒領域 (すなわち、左部は黒であり、右部は白) を描画します。
require "gradient"
local greyscale = gradient {
direction = 'vertical';
{0, 0, 0};
{255, 255, 255};
}
function love.draw()
drawinrect(greyscale, 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
end