1
0
Fork 0
mirror of https://github.com/Reuh/ubiquitousse.git synced 2025-10-27 09:09:30 +00:00
ubiquitousse/gltf/draw.can
2022-09-16 20:04:46 +09:00

91 lines
2.6 KiB
Text

--- drawing facilities for glTF models
-- 2x2 white texture, used as a default for undefined textures in materials
let whiteTexture = love.graphics.newCanvas(2,2)
whiteTexture:renderTo(()
love.graphics.setColor(1,1,1)
love.graphics.rectangle("fill",0,0,2,2)
end)
-- send a uniform to the shader if possible
let maybeSend = (s, name, val)
if s:hasUniform(name) then
s:send(name, val)
end
end
let maybeSendTexture = (s, name, tex)
if s:hasUniform(name) then
if tex then
s:send(name, tex.index.image)
else
s:send(name, whiteTexture)
end
end
end
-- apply a material to the shader & LÖVE state
let applyMaterial = (s, mat)
maybeSend(s, "baseColorFactor", mat.pbrMetallicRoughness.baseColorFactor)
maybeSendTexture(s, "baseColorTexture", mat.pbrMetallicRoughness.baseColorTexture)
maybeSend(s, "metallicFactor", mat.pbrMetallicRoughness.metallicFactor)
maybeSend(s, "roughnessFactor", mat.pbrMetallicRoughness.roughnessFactor)
maybeSendTexture(s, "metallicRoughnessTexture", mat.pbrMetallicRoughness.metallicRoughnessTexture)
maybeSendTexture(s, "normalTexture", mat.normalTexture)
maybeSendTexture(s, "occlusionTexture", mat.occlusionTexture)
if mat.occlusionTexture then
maybeSend(s, "occlusionTextureStrength", mat.occlusionTexture.strength)
else
maybeSend(s, "occlusionTextureStrength", 1)
end
maybeSendTexture(s, "emissiveTexture", mat.emissiveTexture)
if mat.emissiveTexture then
maybeSend(s, "emissiveTextureScale", mat.emissiveTexture.scale)
else
maybeSend(s, "emissiveTextureScale", 1)
end
maybeSend(s, "emissiveFactor", mat.emissiveFactor)
if mat.alphaMode == "BLEND" then
love.graphics.setBlendMode("alpha")
maybeSend(s, "alphaCutoff", 0)
else
love.graphics.setBlendMode("replace")
maybeSend(s, "alphaCutoff", mat.alphaMode == "BLEND" and mat.alphaCutoff or 0)
end
if mat.doubleSided then
love.graphics.setMeshCullMode("none")
else
love.graphics.setMeshCullMode("back")
end
end
-- draw a glTF node and its children
let drawNode = (node, s)
if node.mesh then
s:send("modelMatrix", "column", node.matrix)
for _, primitive in ipairs(node.mesh.primitives) do
applyMaterial(s, primitive.material)
love.graphics.draw(primitive.mesh)
end
end
for _, child in ipairs(node.children) do
drawNode(child, s)
end
end
-- draw the main scene from glTF data
-- shader s is optional; will use current shder if not given
let drawMainScene = (gltf, s)
love.graphics.push("all")
love.graphics.setDepthMode("lequal", true)
if s then
love.graphics.setShader(s)
else
s = love.graphics.getShader()
end
for _, node in ipairs(gltf.scene.nodes) do
drawNode(node, s)
end
love.graphics.pop("all")
end
return drawMainScene