123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
* LICENSE for more details.
*)(* Textures for the 3D backends, like Image_decode for 2D images (as
* RGBA too, see Rgba), and independent of rendering too; the
* difference with Image_decode: no GIF animation, and local file paths
* are the common case. *)(*****************************************************************************)(* Load + cache *)(*****************************************************************************)letload_exn(src:string):Rgba_image.t=letpath=Download.local_file~prefix:"playground3d_texture"srcinmatchImage_decode.decode_string(Image_decode.read_filepath)with|img->img|exceptionFailuremsg->failwith(Printf.sprintf"could not decode texture %s: %s"srcmsg)(* claude: a texture carried inside the program rather than read from
* a file (see Playground3d.embedded_texture and Base64): the bytes are
* decoded straight from memory, no file involved -- which is what lets
* a game run from any directory. *)letload_base64_exn(base64:string):Rgba_image.t=matchImage_decode.decode_string(Base64.decodebase64)with|img->img|exceptionFailuremsg->failwith(Printf.sprintf"could not decode an embedded texture: %s"msg)letcache:(string,Rgba_image.toption)Hashtbl.t=Hashtbl.create16(* [src] is the key of the cache whether it names a file, a URL or
* some bytes: [how] says where to get the pixels from *)letload_with(src:string)(how:unit->Rgba_image.t):Rgba_image.toption=matchHashtbl.find_optcachesrcwith|Someresult->result|None->letresult=trySome(how())withexn->Printf.eprintf"playground3d: failed to load texture %s: %s\n%!"src(Printexc.to_stringexn);NoneinHashtbl.addcachesrcresult;resultletload(src:string):Rgba_image.toption=load_withsrc(fun()->load_exnsrc)letload_base64~(key:string)~(base64:string):Rgba_image.toption=load_withkey(fun()->load_base64_exnbase64)(*****************************************************************************)(* Preloading (same rationale as Image_decode.ml's preload/load_queued) *)(*****************************************************************************)letqueued:stringQueue.t=Queue.create()letpreloadsrc=Queue.pushsrcqueuedletload_queued()=Queue.iter(funsrc->ignore(loadsrc:Rgba_image.toption))queued;Queue.clearqueued