add stb_image_write, some cleanup

This commit is contained in:
Matthew 2025-11-09 11:44:56 +11:00
parent 0765cc5e3b
commit 1501b5bc07
6 changed files with 2069 additions and 253 deletions

56
alloc.d
View File

@ -90,6 +90,14 @@ Alloc(T)(T[] target)
return arr;
}
string
Alloc(string target)
{
u8[] str = Alloc!(u8)(target.length);
str[] = cast(u8[])target[];
return ConvToStr(str);
}
T[]
Alloc(T)(T[] target, u64 start, u64 len)
{
@ -98,6 +106,14 @@ Alloc(T)(T[] target, u64 start, u64 len)
return arr;
}
string
Alloc(string target, u64 start, u64 len)
{
u8[] str = Alloc!(u8)(len);
str[0 .. $] = cast(u8[])target[start .. start+len];
return ConvToStr(str);
}
T[]
Alloc(T)(u64 count, T set)
{
@ -242,23 +258,39 @@ T[]
Alloc(T)(Arena* arena, T[] target)
{
T[] arr = Alloc!(T)(arena, target.length);
arr[] = target[];
arr[] = target[];
return arr;
}
string
Alloc(Arena* arena, string target)
{
u8[] str = Alloc!(u8)(arena, target.length);
str[] = cast(u8[])target[];
return ConvToStr(str);
}
T[]
Alloc(T)(Arena* arena, T[] target, u64 start, u64 len)
{
T[] arr = Alloc!(T)(arena, len);
T[] arr = Alloc!(T)(arena, len);
arr[0 .. $] = target[start .. start+len];
return arr;
}
string
Alloc(Arena* arena, string target, u64 start, u64 len)
{
u8[] str = Alloc!(u8)(arena, len);
str[0 .. $] = cast(u8[])target[start .. start+len];
return ConvToStr(str);
}
T[]
Alloc(T)(Arena* arena, u64 count, T set)
{
T[] arr = Alloc!(T)(arena, count);
arr[] = set;
arr[] = set;
return arr;
}
@ -362,14 +394,30 @@ ScratchAlloc(T)(T[] target)
return arr;
}
string
ScratchAlloc(string target)
{
u8[] str = ScratchAlloc!(u8)(target.length);
str[] = cast(u8[])target[];
return ConvToStr(str);
}
T[]
ScratchAlloc(T)(T[] target, u64 start, u64 len)
{
T[] arr = ScratchAlloc!(T)(len);
T[] arr = ScratchAlloc!(T)(len);
arr[0 .. $] = target[start .. start+len];
return arr;
}
string
ScratchAlloc(string target, u64 start, u64 len)
{
u8[] str = ScratchAlloc!(u8)(len);
str[0 .. $] = cast(u8[])target[start .. start+len];
return ConvToStr(str);
}
T[]
ScratchAlloc(T)(u64 count, T set)
{

290
assets.d
View File

@ -20,15 +20,9 @@ u8[][] Asset_Data;
const u32 FILE_VERSION = 3;
const u32 MODEL_VERSION = 2;
enum AssetType : u32
{
None,
ModelObj,
Shader,
Texture,
}
alias AT = AssetType;
/*************************
****** FILE PACKER ******
*************************/
struct FileHeader
{
@ -48,25 +42,58 @@ struct ModelHeader
u64 index_offset;
u64 material_count;
u64 material_offset;
u64 texture_count;
u64 texture_offset;
}
struct Vertex
struct PackedMaterial
{
Vec4 color;
Vec4 tangent;
Vec3 pos;
Vec3 normal;
Vec2 uv;
StringID name;
Vec3[MatColor.max] colors;
StringHeader[MatMap.max] maps;
}
struct PackedModel
{
StringID name;
PackedMaterial[] mats;
Vertex[] vtx;
u32[] idx;
string[] strs;
}
/*************************
****** FILE PACKER ******
*************************/
/************************
*** ASSET STRUCTURES ***
************************/
alias StringID = u64;
enum AssetType : u32
{
None,
Model,
Shader,
Texture,
}
alias AT = AssetType;
struct AssetInfo
{
u64 hash;
u64 offset;
u64 length;
AssetType type;
}
struct ModelData
{
Vertex[] vertices;
u32[] indices;
MaterialData[] materials;
TextureInfo[] textures;
string name;
Vertex[] vtx;
u32[] idx;
MaterialData[] mats;
}
struct MaterialData
@ -78,78 +105,27 @@ struct MaterialData
IllumModel illum;
}
struct TextureInfo
struct StringHeader
{
string name;
u32 id;
u32 id;
u32 length;
}
struct TextureHeader
{
u64 str_length;
u64 str_offset;
u32 texture_id;
}
/************************
*** ASSET STRUCTURES ***
************************/
struct ModelMeta
{
u64 index_count;
}
/**************************
***** GFX STRUCTURES *****
**************************/
struct TexData
struct Vertex
{
void* data;
TexMeta meta;
}
struct TexMeta
{
u32 w;
u32 h;
u32 ch;
}
struct AssetInfo
{
u64 hash;
u64 offset;
u64 length;
AssetType type;
}
enum MatProp
{
None,
Ambient,
Albedo,
Specular,
SpecularExp,
Dissolve, // Transparency 1.0 -> opaque
Transparency, // Transparency 0.0 -> opaque
Transmission,
OpticalDensity,
Illumination,
AmbientMap,
AlbedoMap,
SpecularMap,
SpecularHighlightMap,
AlphaMap,
BumpMap,
DisplacementMap,
Stencil,
Roughness,
RoughnessMap,
Metallic,
MetallicMap,
Sheen,
SheenMap,
ClearcoatThickness,
ClearcoatRoughness,
Emissive,
EmissiveMap,
Anisotropy,
AnisotropyMap,
NormalMap,
Vec4 color;
Vec4 tangent;
Vec3 pos;
Vec3 normal;
Vec2 uv;
}
enum IllumModel : u32
@ -213,127 +189,12 @@ enum MatMap : u32
Max,
}
/**************************
***** GFX STRUCTURES *****
**************************/
bool Asset_Pack_Opened = false;
MatProp
GetMatProp(string str)
{
switch(str) with(MatProp)
{
// Vec3
case "Ka": return Ambient;
case "Kd": return Albedo;
case "Ks": return Specular;
case "Tf": return Transmission;
case "Ke": return Emissive;
// Illum
case "illum": return Illumination;
// string
case "map_Ka": return AmbientMap;
case "map_Kd": return AlbedoMap;
case "map_Ks": return SpecularMap;
case "map_Ns": return SpecularHighlightMap;
case "map_d": return AlphaMap;
case "map_bump":
case "bump": return BumpMap;
case "map_Pr": return RoughnessMap;
case "map_Pm": return MetallicMap;
case "map_Ke": return EmissiveMap;
case "map_Ps": return SheenMap;
case "norm": return NormalMap;
case "anisor": return AnisotropyMap;
case "disp": return DisplacementMap;
case "decal": return Stencil;
// f32
case "Ns": return SpecularExp;
case "d": return Dissolve;
case "Tr": return Transparency;
case "Ni": return OpticalDensity;
case "Pr": return Roughness;
case "Pm": return Metallic;
case "Pc": return ClearcoatThickness;
case "Pcr": return ClearcoatRoughness;
case "aniso": return Anisotropy;
case "Ps": return Sheen;
default: return None;
}
}
MatColor
GetMatColor(MatProp prop)
{
switch(prop) with(MatProp)
{
case Ambient: return MatColor.Ambient;
case Albedo: return MatColor.Albedo;
case Specular: return MatColor.Specular;
case Transmission: return MatColor.Transmission;
case Emissive: return MatColor.Emissive;
default: assert(false, "Unknown MatProp to MatColor conversion");
}
}
MatFloat
GetMatFloat(MatProp prop)
{
switch(prop) with(MatProp)
{
case SpecularExp: return MatFloat.SpecularExp;
case Transparency:
case Dissolve: return MatFloat.Alpha;
case OpticalDensity: return MatFloat.OpticalDensity;
case Roughness: return MatFloat.Roughness;
case Metallic: return MatFloat.Metallic;
case ClearcoatThickness: return MatFloat.ClearcoatThickness;
case ClearcoatRoughness: return MatFloat.ClearcoatRoughness;
case Anisotropy: return MatFloat.Anisotropy;
case Sheen: return MatFloat.Sheen;
default: assert(false, "Unknown MatProp to MatFloat conversion");
}
}
MatMap
GetMatMap(MatProp prop)
{
switch(prop) with(MatProp)
{
case AmbientMap: return MatMap.Ambient;
case AlbedoMap: return MatMap.Albedo;
case SpecularMap: return MatMap.Specular;
case SpecularHighlightMap: return MatMap.SpecularHighlight;
case AlphaMap: return MatMap.Alpha;
case BumpMap: return MatMap.Bump;
case RoughnessMap: return MatMap.Roughness;
case MetallicMap: return MatMap.Metallic;
case EmissiveMap: return MatMap.Emissive;
case SheenMap: return MatMap.Sheen;
case NormalMap: return MatMap.Normal;
case AnisotropyMap: return MatMap.Anisotropy;
case DisplacementMap: return MatMap.Displacement;
case Stencil: return MatMap.Ambient;
default: assert(false, "Unknown MatProp to MatMap conversion");
}
}
MatMap
GetMatMap(string str)
{
return GetMatMap(GetMatProp(str));
}
MatFloat
GetMatFloat(string str)
{
return GetMatFloat(GetMatProp(str));
}
MatColor
GetMatColor(string str)
{
return GetMatColor(GetMatProp(str));
}
debug
{
void
@ -496,13 +357,18 @@ else
}
}
unittest
PackedModel
Convert(Arena* arena, ModelData* md)
{
{
MatProp prop = GetMatProp("Ka");
}
PackedModel packed = {
name: 0,
strs: Alloc!(string)(arena, 1+md.mats.length),
};
packed.strs[0] = Alloc(arena, md.name);
return packed;
}

1724
external/stb/stb_image_write.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,9 @@
#define STB_IMAGE_IMPLEMENTATION
#include "external/stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "external/stb/stb_image_write.h"
#define CGLM_FORCE_DEPTH_ZERO_TO_ONE
#include "external/cglm/cglm.h"
#define TINYOBJ_LOADER_C_IMPLEMENTATION
#include "external/tinyobjloader/tinyobj_loader_c.h"

244
packer.d
View File

@ -4,6 +4,7 @@ import includes;
import dlib.util;
import dlib.aliases;
import dlib.assets;
import dlib.platform;
import std.stdio;
import std.string;
@ -16,12 +17,55 @@ import std.conv;
import std.array;
AssetType[string] Lookup = [
".obj": AT.ModelObj,
".obj": AT.Model,
".png": AT.Texture,
".jpg": AT.Texture,
".spv": AT.Shader,
];
enum MatProp
{
None,
Ambient,
Albedo,
Specular,
SpecularExp,
Dissolve, // Transparency 1.0 -> opaque
Transparency, // Transparency 0.0 -> opaque
Transmission,
OpticalDensity,
Illumination,
AmbientMap,
AlbedoMap,
SpecularMap,
SpecularHighlightMap,
AlphaMap,
BumpMap,
DisplacementMap,
Stencil,
Roughness,
RoughnessMap,
Metallic,
MetallicMap,
Sheen,
SheenMap,
ClearcoatThickness,
ClearcoatRoughness,
Emissive,
EmissiveMap,
Anisotropy,
AnisotropyMap,
NormalMap,
}
struct PackedString
{
StringHeader header;
string str;
alias header this;
}
struct Texture
{
string name;
@ -37,16 +81,13 @@ struct MeshGroup
u32 length;
}
struct MeshIdx
union MeshIdx
{
union
struct
{
struct
{
u32 v, n, uv;
};
u32[3] arr;
u32 v, n, uv;
};
u32[3] arr;
}
struct Model
@ -67,31 +108,180 @@ Texture[] g_model_textures = [];
void main(string[] argv)
{
Log("running");
if(isDir("build"))
{
chdir("build");
}
bool pack = false;
bool font = false;
bool pack = false;
bool out_dir = false;
string font_file;
for(u64 i = 0; i < argv.length; i += 1)
{
if(argv[i] == "-dir" && i+1 < argv.length)
{
if(!exists(argv[i+1]))
{
mkdir(argv[i+1]);
}
if(!isDir(argv[i+1]))
{
assert(false, "Out directory is not a directory");
}
chdir(argv[i+1]);
out_dir = true;
i += 1;
continue;
}
if(argv[i] == "-pack")
{
pack = true;
}
}
if(!out_dir)
{
if(!Cwd!(string)().endsWith("build"))
{
if(!exists("build"))
{
mkdir("build");
}
if(exists("build") && isDir("build"))
{
chdir("build");
}
else assert(false, "Unable to make default build directory");
}
}
if(pack)
{
PackFile();
TestFile();
debug TestFile();
}
}
MatProp
GetMatProp(string str)
{
switch(str) with(MatProp)
{
// Vec3
case "Ka": return Ambient;
case "Kd": return Albedo;
case "Ks": return Specular;
case "Tf": return Transmission;
case "Ke": return Emissive;
// Illum
case "illum": return Illumination;
// string
case "map_Ka": return AmbientMap;
case "map_Kd": return AlbedoMap;
case "map_Ks": return SpecularMap;
case "map_Ns": return SpecularHighlightMap;
case "map_d": return AlphaMap;
case "map_bump":
case "bump": return BumpMap;
case "map_Pr": return RoughnessMap;
case "map_Pm": return MetallicMap;
case "map_Ke": return EmissiveMap;
case "map_Ps": return SheenMap;
case "norm": return NormalMap;
case "anisor": return AnisotropyMap;
case "disp": return DisplacementMap;
case "decal": return Stencil;
// f32
case "Ns": return SpecularExp;
case "d": return Dissolve;
case "Tr": return Transparency;
case "Ni": return OpticalDensity;
case "Pr": return Roughness;
case "Pm": return Metallic;
case "Pc": return ClearcoatThickness;
case "Pcr": return ClearcoatRoughness;
case "aniso": return Anisotropy;
case "Ps": return Sheen;
default: return None;
}
}
MatColor
GetMatColor(MatProp prop)
{
switch(prop) with(MatProp)
{
case Ambient: return MatColor.Ambient;
case Albedo: return MatColor.Albedo;
case Specular: return MatColor.Specular;
case Transmission: return MatColor.Transmission;
case Emissive: return MatColor.Emissive;
default: assert(false, "Unknown MatProp to MatColor conversion");
}
}
MatFloat
GetMatFloat(MatProp prop)
{
switch(prop) with(MatProp)
{
case SpecularExp: return MatFloat.SpecularExp;
case Transparency:
case Dissolve: return MatFloat.Alpha;
case OpticalDensity: return MatFloat.OpticalDensity;
case Roughness: return MatFloat.Roughness;
case Metallic: return MatFloat.Metallic;
case ClearcoatThickness: return MatFloat.ClearcoatThickness;
case ClearcoatRoughness: return MatFloat.ClearcoatRoughness;
case Anisotropy: return MatFloat.Anisotropy;
case Sheen: return MatFloat.Sheen;
default: assert(false, "Unknown MatProp to MatFloat conversion");
}
}
MatMap
GetMatMap(MatProp prop)
{
switch(prop) with(MatProp)
{
case AmbientMap: return MatMap.Ambient;
case AlbedoMap: return MatMap.Albedo;
case SpecularMap: return MatMap.Specular;
case SpecularHighlightMap: return MatMap.SpecularHighlight;
case AlphaMap: return MatMap.Alpha;
case BumpMap: return MatMap.Bump;
case RoughnessMap: return MatMap.Roughness;
case MetallicMap: return MatMap.Metallic;
case EmissiveMap: return MatMap.Emissive;
case SheenMap: return MatMap.Sheen;
case NormalMap: return MatMap.Normal;
case AnisotropyMap: return MatMap.Anisotropy;
case DisplacementMap: return MatMap.Displacement;
case Stencil: return MatMap.Ambient;
default: assert(false, "Unknown MatProp to MatMap conversion");
}
}
MatMap
GetMatMap(string str)
{
return GetMatMap(GetMatProp(str));
}
MatFloat
GetMatFloat(string str)
{
return GetMatFloat(GetMatProp(str));
}
MatColor
GetMatColor(string str)
{
return GetMatColor(GetMatProp(str));
}
void
PackFile()
{
@ -162,21 +352,6 @@ PackFile()
ap.rawWrite(asset_info);
}
TexMeta
GetTexMeta(u8[] data)
{
int ch = 4;
int width, height, has_ch;
auto img = stbi_load_from_memory(data.ptr, cast(int)data.length, &width, &height, &has_ch, ch);
assert(img != null, "stbi_load_from_image failure: image is NULL");
assert(width > 0 && height > 0 && has_ch > 0, "stbi_load_from_image failure: dimensions are invalid");
stbi_image_free(img);
return TexMeta(w: width, h: height, ch: has_ch);
}
void
TestFile()
{
@ -467,7 +642,6 @@ ConvertObj(string file_name)
mtl = null;
}
}
}
assert(mtls[mtls.length-1].name == "sp_zid_vani");
@ -530,4 +704,8 @@ unittest
{ // Obj test
Model model = ConvertObj("./test/sponza.obj");
}
{
MatProp prop = GetMatProp("Ka");
}
}

View File

@ -480,8 +480,7 @@ Cwd(T)()
}
else static if(is(T: string))
{
string s = (cast(immutable(char)*)buf.ptr)[0 .. strlen(buf.ptr)];
return s;
return ConvToStr(buf)[0 .. strlen(buf.ptr)];
}
}