mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
280
lua/pac3/libraries/urltex.lua
Normal file
280
lua/pac3/libraries/urltex.lua
Normal file
@@ -0,0 +1,280 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
local urltex = {}
|
||||
|
||||
urltex.TextureSize = 1024
|
||||
urltex.ActivePanel = urltex.ActivePanel or NULL
|
||||
urltex.Queue = urltex.Queue or {}
|
||||
urltex.Cache = urltex.Cache or {}
|
||||
|
||||
concommand.Add("pac_urltex_clear_cache", function()
|
||||
urltex.Cache = {}
|
||||
urltex.Queue = {}
|
||||
end)
|
||||
|
||||
if urltex.ActivePanel:IsValid() then
|
||||
urltex.ActivePanel:Remove()
|
||||
end
|
||||
|
||||
local enable = CreateClientConVar("pac_enable_urltex", "1", true)
|
||||
local EMPTY_FUNC = function() end
|
||||
local function findFlag(url, flagID)
|
||||
local startPos, endPos = url:find(flagID)
|
||||
if not startPos then return url, false end
|
||||
|
||||
if url:sub(endPos + 1, endPos + 1) == ' ' or url:sub(startPos - 1, startPos - 1) == ' ' then
|
||||
url = url:gsub(' ?' .. flagID .. ' ?', '')
|
||||
return url, true
|
||||
end
|
||||
|
||||
return url, false
|
||||
end
|
||||
|
||||
function urltex.GetMaterialFromURL(url, callback, skip_cache, shader, size, size_hack, additionalData)
|
||||
if size_hack == nil then
|
||||
size_hack = true
|
||||
end
|
||||
|
||||
additionalData = additionalData or {}
|
||||
shader = shader or "VertexLitGeneric"
|
||||
if not enable:GetBool() then return end
|
||||
local noclampS, noclamp, noclampT
|
||||
|
||||
url, noclampS = findFlag(url, 'noclamps')
|
||||
url, noclampT = findFlag(url, 'noclampt')
|
||||
url, noclamp = findFlag(url, 'noclamp')
|
||||
|
||||
local urlAddress = url
|
||||
local urlIndex = url
|
||||
|
||||
if noclamp then
|
||||
urlIndex = urlIndex .. ' noclamp'
|
||||
elseif noclampS then
|
||||
urlIndex = urlIndex .. ' noclampS'
|
||||
elseif noclampT then
|
||||
urlIndex = urlIndex .. ' noclampT'
|
||||
end
|
||||
|
||||
noclamp = noclamp or noclampS and noclampT
|
||||
|
||||
local renderTargetNeeded =
|
||||
noclampS or
|
||||
noclamp or
|
||||
noclampT
|
||||
|
||||
if isfunction(callback) and not skip_cache and urltex.Cache[urlIndex] then
|
||||
local tex = urltex.Cache[urlIndex]
|
||||
local mat = CreateMaterial("pac3_urltex_" .. pac.Hash(), shader, additionalData)
|
||||
mat:SetTexture("$basetexture", tex)
|
||||
callback(mat, tex)
|
||||
return
|
||||
end
|
||||
|
||||
callback = callback or EMPTY_FUNC
|
||||
|
||||
if urltex.Queue[urlIndex] then
|
||||
table.insert(urltex.Queue[urlIndex].callbacks, callback)
|
||||
else
|
||||
urltex.Queue[urlIndex] = {
|
||||
url = urlAddress,
|
||||
urlIndex = urlIndex,
|
||||
callbacks = {callback},
|
||||
tries = 0,
|
||||
size = size,
|
||||
size_hack = size_hack,
|
||||
shader = shader,
|
||||
noclampS = noclampS,
|
||||
noclampT = noclampT,
|
||||
noclamp = noclamp,
|
||||
rt = renderTargetNeeded,
|
||||
additionalData = additionalData
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function urltex.Think()
|
||||
if not pac.IsEnabled() then return end
|
||||
|
||||
if table.Count(urltex.Queue) > 0 then
|
||||
for url, data in pairs(urltex.Queue) do
|
||||
-- when the panel is gone start a new one
|
||||
if not urltex.ActivePanel:IsValid() then
|
||||
urltex.StartDownload(data.url, data)
|
||||
end
|
||||
end
|
||||
urltex.Busy = true
|
||||
else
|
||||
urltex.Busy = false
|
||||
end
|
||||
end
|
||||
|
||||
timer.Create("urltex_queue", 0.1, 0, urltex.Think)
|
||||
|
||||
function urltex.StartDownload(url, data)
|
||||
if urltex.ActivePanel:IsValid() then
|
||||
urltex.ActivePanel:Remove()
|
||||
end
|
||||
|
||||
url = pac.FixUrl(url)
|
||||
local size = tonumber(data.size or urltex.TextureSize)
|
||||
local id = "urltex_download_" .. url
|
||||
local pnl
|
||||
local frames_passed = 0
|
||||
|
||||
local function createDownloadPanel()
|
||||
pnl = vgui.Create("DHTML")
|
||||
-- Tested in PPM/2, this code works perfectly
|
||||
pnl:SetVisible(false)
|
||||
pnl:SetSize(size, size)
|
||||
pnl:SetHTML([[<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
html
|
||||
{
|
||||
overflow:hidden;
|
||||
]] .. (data.size_hack and "margin: -8px -8px;" or "margin: 0px 0px;") .. [[
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
setInterval(function() {
|
||||
console.log('REAL_FRAME_PASSED');
|
||||
}, 50);
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<img src="]] .. url .. [[" alt="" width="]] .. size .. [[" height="]] .. size .. [[" />
|
||||
</body>
|
||||
</html>]])
|
||||
|
||||
pnl:Refresh()
|
||||
|
||||
function pnl:ConsoleMessage(msg)
|
||||
if msg == 'REAL_FRAME_PASSED' then
|
||||
frames_passed = frames_passed + 1
|
||||
end
|
||||
end
|
||||
|
||||
urltex.ActivePanel = pnl
|
||||
end
|
||||
|
||||
local go = false
|
||||
local time = 0
|
||||
local timeoutNum = 0
|
||||
local think
|
||||
|
||||
local function onTimeout()
|
||||
timeoutNum = timeoutNum + 1
|
||||
if IsValid(pnl) then pnl:Remove() end
|
||||
|
||||
if timeoutNum < 5 then
|
||||
pac.dprint("material download %q timed out.. trying again for the %ith time", url, timeoutNum)
|
||||
-- try again
|
||||
go = false
|
||||
time = 0
|
||||
createDownloadPanel()
|
||||
else
|
||||
pac.dprint("material download %q timed out for good", url, timeoutNum)
|
||||
pac.RemoveHook("Think", id)
|
||||
timer.Remove(id)
|
||||
urltex.Queue[data.urlIndex] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function think()
|
||||
-- panel is no longer valid
|
||||
if not pnl:IsValid() then
|
||||
onTimeout()
|
||||
return
|
||||
end
|
||||
|
||||
-- give it some time.. IsLoading is sometimes lying, especially on chromium branch
|
||||
if not go and not pnl:IsLoading() then
|
||||
time = pac.RealTime + 1
|
||||
go = true
|
||||
end
|
||||
|
||||
if go and time < pac.RealTime and frames_passed > 20 then
|
||||
pnl:UpdateHTMLTexture()
|
||||
local html_mat = pnl:GetHTMLMaterial()
|
||||
|
||||
if html_mat then
|
||||
local crc = pac.Hash()
|
||||
local vertex_mat = CreateMaterial("pac3_urltex_" .. crc, data.shader, data.additionalData)
|
||||
local tex = html_mat:GetTexture("$basetexture")
|
||||
tex:Download()
|
||||
vertex_mat:SetTexture("$basetexture", tex)
|
||||
-- tex:Download()
|
||||
|
||||
urltex.Cache[data.urlIndex] = tex
|
||||
|
||||
pac.RemoveHook("Think", id)
|
||||
timer.Remove(id)
|
||||
urltex.Queue[data.urlIndex] = nil
|
||||
local rt
|
||||
|
||||
if data.rt then
|
||||
local textureFlags = 0
|
||||
textureFlags = textureFlags + 4 -- clamp S
|
||||
textureFlags = textureFlags + 8 -- clamp T
|
||||
textureFlags = textureFlags + 16 -- anisotropic
|
||||
textureFlags = textureFlags + 256 -- no mipmaps
|
||||
-- textureFlags = textureFlags + 2048 -- Texture is procedural
|
||||
textureFlags = textureFlags + 32768 -- Texture is a render target
|
||||
-- textureFlags = textureFlags + 67108864 -- Usable as a vertex texture
|
||||
|
||||
if data.noclamp then
|
||||
textureFlags = textureFlags - 4
|
||||
textureFlags = textureFlags - 8
|
||||
elseif data.noclampS then
|
||||
textureFlags = textureFlags - 4
|
||||
elseif data.noclampT then
|
||||
textureFlags = textureFlags - 8
|
||||
end
|
||||
|
||||
local vertex_mat2 = CreateMaterial("pac3_urltex_" .. crc .. '_hack', 'UnlitGeneric', data.additionalData)
|
||||
vertex_mat2:SetTexture("$basetexture", tex)
|
||||
rt = GetRenderTargetEx("pac3_urltex_" .. crc, size, size, RT_SIZE_NO_CHANGE, MATERIAL_RT_DEPTH_NONE, textureFlags, CREATERENDERTARGETFLAGS_UNFILTERABLE_OK, IMAGE_FORMAT_RGB888)
|
||||
render.PushRenderTarget(rt)
|
||||
render.Clear(0, 0, 0, 255, false, false)
|
||||
cam.Start2D()
|
||||
surface.SetMaterial(vertex_mat2)
|
||||
surface.SetDrawColor(255, 255, 255)
|
||||
surface.DrawTexturedRect(0, 0, size, size)
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
vertex_mat:SetTexture('$basetexture', rt)
|
||||
urltex.Cache[data.urlIndex] = rt
|
||||
end
|
||||
|
||||
timer.Simple(0, function()
|
||||
pnl:Remove()
|
||||
end)
|
||||
|
||||
if data.callbacks then
|
||||
for i, callback in pairs(data.callbacks) do
|
||||
callback(vertex_mat, rt or tex)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pac.AddHook("Think", id, think)
|
||||
|
||||
-- 5 sec max timeout, 5 maximal timeouts
|
||||
timer.Create(id, 5, 5, onTimeout)
|
||||
createDownloadPanel()
|
||||
end
|
||||
|
||||
return urltex
|
||||
Reference in New Issue
Block a user