-- ============================================================ -- Telão 3D via Shader | [Metropoles]telao -- Abordagem: engineApplyShaderToWorldTexture -- Modelo alvo : 16000 (drvin_screen) -- TXD : con_drivein.txd -- Textura alvo: "drvin_screen" -- ============================================================ local SCREEN_TEXTURE = "drvin_screen" -- textura da face do telão no modelo 16000 local screenShader = nil local renderTarget = nil screens = {} -- { [id] = element } — global para main.lua acessar -- Shader FX inline: substitui a textura do modelo pelo RenderTarget do browser local SHADER_FX = [[ texture Tex0; technique ScreenReplace { pass P0 { Texture[0] = Tex0; Lighting = false; // vídeo sem influência de luz AlphaBlendEnable = false; ZEnable = true; ZWriteEnable = true; } } ]] -- ─── Gerenciamento de telas ─────────────────────────────────── function addScreen(id, screenElement) screens[id] = screenElement -- Aplica o shader apenas ao objeto específico criado no servidor if isElement(screenShader) and isElement(screenElement) then local ok = engineApplyShaderToWorldTexture(screenShader, SCREEN_TEXTURE, screenElement) outputDebugString("[Metropoles]telao: shader aplicado ao obj " .. tostring(id) .. " -> " .. tostring(ok)) end if addDebugInfo then addDebugInfo("screenCount", getScreenCount()) end end function removeScreen(id) local el = screens[id] if isElement(screenShader) and isElement(el) then engineRemoveShaderFromWorldTexture(screenShader, SCREEN_TEXTURE, el) end screens[id] = nil if addDebugInfo then addDebugInfo("screenCount", getScreenCount()) end end function clearScreens() for id, el in pairs(screens) do if isElement(screenShader) and isElement(el) then engineRemoveShaderFromWorldTexture(screenShader, SCREEN_TEXTURE, el) end end screens = {} if addDebugInfo then addDebugInfo("screenCount", 0) end end function getScreenCount() local n = 0 for _ in pairs(screens) do n = n + 1 end return n end -- ─── Inicialização ──────────────────────────────────────────── addEventHandler("onClientResourceStart", resourceRoot, function() -- RenderTarget 16:9 que receberá o conteúdo do browser renderTarget = dxCreateRenderTarget(1280, 720, false) -- Shader inline — sem arquivo .fx externo -- elementTypes "object" garante que só afeta objetos (mais performático) screenShader = dxCreateShader(SHADER_FX, 0, 0, false, "object") if not isElement(renderTarget) then outputDebugString("[Metropoles]telao: ERRO — RenderTarget não criado!", 1) end if not isElement(screenShader) then outputDebugString("[Metropoles]telao: ERRO — Shader não compilou! Verifique o código FX.", 1) else outputDebugString("[Metropoles]telao: Shader OK — aguardando objetos 16000 sincronizados.") end if addDebugInfo then addDebugInfo("renderTarget", isElement(renderTarget)) end if addDebugInfo then addDebugInfo("shader", isElement(screenShader)) end end) addEventHandler("onClientResourceStop", resourceRoot, function() -- Limpeza: remove shader do mundo antes de destruir if isElement(screenShader) then engineRemoveShaderFromWorldTexture(screenShader, SCREEN_TEXTURE) destroyElement(screenShader) end if isElement(renderTarget) then destroyElement(renderTarget) end screenShader = nil renderTarget = nil end) -- ─── Loop de renderização ───────────────────────────────────── addEventHandler("onClientRender", root, function() local tex = getBrowserTexture() if not tex or not isElement(renderTarget) or not isElement(screenShader) then return end if getScreenCount() == 0 then return end -- 1) Desenha o browser no RenderTarget dxSetRenderTarget(renderTarget, true) dxDrawImage(0, 0, 1280, 720, tex) dxSetRenderTarget() -- restaura framebuffer principal -- 2) Envia o RT como textura para o shader -- O shader substitui "drvin_screen" em todos os objetos registrados dxSetShaderValue(screenShader, "Tex0", renderTarget) if addDebugInfo then addDebugInfo("shaderFeeding", true) end end)