Compare commits
10 Commits
b4c0efa748
...
61bef68b40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61bef68b40 | ||
|
|
5ce2942e71 | ||
|
|
c7a9c2f78f | ||
|
|
efc6477180 | ||
|
|
b603d997cf | ||
|
|
70a9074415 | ||
|
|
1f91eb9cf1 | ||
|
|
ce923a77fb | ||
|
|
0f6bfcdc4b | ||
|
|
d416f6d36e |
BIN
assets/fonts/Lexend-Regular.ttf
Normal file
BIN
assets/fonts/Lexend-Regular.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/glyph_atlas_lexend.bmp
Normal file
BIN
assets/fonts/glyph_atlas_lexend.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 768 KiB |
BIN
assets/fonts/glyph_atlas_lexend.tga
Normal file
BIN
assets/fonts/glyph_atlas_lexend.tga
Normal file
Binary file not shown.
BIN
assets/fonts/glyph_coords_lexend.co
Normal file
BIN
assets/fonts/glyph_coords_lexend.co
Normal file
Binary file not shown.
@ -1,17 +1,23 @@
|
|||||||
struct VertexShaderInput {
|
struct VertexShaderInput {
|
||||||
// Per Vertex
|
// Per Vertex
|
||||||
float4 pos : VERTEX_POSITION;
|
float4 pos : VERTEX_POSITION;
|
||||||
float4 uvst : COORDINATES;
|
float2 uv : UV_VERTEX;
|
||||||
uint vid : SV_VertexID;
|
uint vid : SV_VertexID;
|
||||||
|
|
||||||
// Per Instance
|
// Per Instance
|
||||||
float4 pos_size : INSTANCE_POSITION_SIZE;
|
float4 pos_size : INSTANCE_POSITION_SIZE;
|
||||||
uint tile_type : TILE_TYPE;
|
uint tile_type : TILE_TYPE;
|
||||||
|
float4 uv0uv1 : UV_INSTANCE;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer constants {
|
||||||
|
float aspect_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexShaderOutput {
|
struct VertexShaderOutput {
|
||||||
float4 pos : SV_POSITION;
|
float4 pos : SV_POSITION;
|
||||||
float4 uvst : COORDINATES;
|
float4 uv0uv1 : COORDINATES;
|
||||||
uint tile_type : TILE_TYPE;
|
uint tile_type : TILE_TYPE;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -19,9 +25,6 @@ struct VertexShaderOutput {
|
|||||||
VertexShaderOutput main(VertexShaderInput input) {
|
VertexShaderOutput main(VertexShaderInput input) {
|
||||||
VertexShaderOutput output;
|
VertexShaderOutput output;
|
||||||
|
|
||||||
float2 rect_pos = input.pos_size.xy;
|
|
||||||
float2 rect_size = input.pos_size.zw;
|
|
||||||
|
|
||||||
float3x3 coord_sys = {
|
float3x3 coord_sys = {
|
||||||
2, 0, -1,
|
2, 0, -1,
|
||||||
0, -2, 1,
|
0, -2, 1,
|
||||||
@ -37,16 +40,24 @@ VertexShaderOutput main(VertexShaderInput input) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
float3x3 size = {
|
float3x3 size = {
|
||||||
rect_size.x, 0, 0,
|
input.pos_size.z, 0, 0,
|
||||||
0, rect_size.y, 0,
|
0, input.pos_size.w, 0,
|
||||||
0, 0, 1
|
0, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
output.pos.xy = mul(pos, mul(size, input.pos.xyz)).xy;
|
output.pos.xy = mul(pos, mul(size, input.pos.xyz)).xy;
|
||||||
//output.pos.xy = mul(pos, input.pos.xyz).xy;
|
|
||||||
|
float correction_factor = aspect_ratio / (16.0 / 9.0);
|
||||||
|
if(correction_factor < 1)
|
||||||
|
output.pos.y *= correction_factor;
|
||||||
|
else
|
||||||
|
output.pos.x /= correction_factor;
|
||||||
|
|
||||||
output.pos.zw = float2(0, 1);
|
output.pos.zw = float2(0, 1);
|
||||||
|
|
||||||
output.uvst = input.uvst;
|
output.uv0uv1.zw = float2(0, 0);
|
||||||
|
|
||||||
|
output.uv0uv1.xy = lerp(input.uv0uv1.xy, input.uv0uv1.zw, input.uv.xy);
|
||||||
output.tile_type = input.tile_type;
|
output.tile_type = input.tile_type;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
24
assets/shader/font_pixel_shader.hlsl
Normal file
24
assets/shader/font_pixel_shader.hlsl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
struct PixelShaderInput {
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float4 uvst : COORDINATES;
|
||||||
|
uint tile_type : TILE_TYPE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PixelShaderOutput {
|
||||||
|
float4 color : SV_TARGET;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture2D<float> tex1 : register(t0);
|
||||||
|
|
||||||
|
SamplerState texture_sampler : register(s0);
|
||||||
|
|
||||||
|
PixelShaderOutput main(PixelShaderInput input) {
|
||||||
|
PixelShaderOutput output;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
output.color = float4(1, 1, 1, tex1.Sample(texture_sampler, float2(input.uvst.xy)));
|
||||||
|
#else
|
||||||
|
output.color = float4(1, 0, 1, 1);
|
||||||
|
#endif
|
||||||
|
return output;
|
||||||
|
}
|
||||||
63
assets/shader/font_vertex_shader.hlsl
Normal file
63
assets/shader/font_vertex_shader.hlsl
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
struct VertexShaderInput {
|
||||||
|
// Per Vertex
|
||||||
|
float4 pos : VERTEX_POSITION;
|
||||||
|
float2 uv : UV_VERTEX;
|
||||||
|
uint vid : SV_VertexID;
|
||||||
|
|
||||||
|
// Per Instance
|
||||||
|
float4 pos_size : INSTANCE_POSITION_SIZE;
|
||||||
|
uint tile_type : TILE_TYPE;
|
||||||
|
float4 uv0uv1 : UV_INSTANCE;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexShaderOutput {
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float4 uv0uv1 : COORDINATES;
|
||||||
|
uint tile_type : TILE_TYPE;
|
||||||
|
};
|
||||||
|
|
||||||
|
cbuffer constants {
|
||||||
|
float aspect_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
VertexShaderOutput main(VertexShaderInput input) {
|
||||||
|
VertexShaderOutput output;
|
||||||
|
|
||||||
|
float3x3 coord_sys = {
|
||||||
|
2, 0, -1,
|
||||||
|
0, -2, 1,
|
||||||
|
0, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
input.pos_size.xy = mul(coord_sys, float3(input.pos_size.xy, 1)).xy;
|
||||||
|
|
||||||
|
float3x3 pos = {
|
||||||
|
1, 0, input.pos_size.x,
|
||||||
|
0, 1, input.pos_size.y,
|
||||||
|
0, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
float3x3 size = {
|
||||||
|
input.pos_size.z, 0, 0,
|
||||||
|
0, input.pos_size.w, 0,
|
||||||
|
0, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
output.pos.xy = mul(pos, mul(size, input.pos.xyz)).xy;
|
||||||
|
|
||||||
|
float correction_factor = aspect_ratio / (16.0 / 9.0);
|
||||||
|
if (correction_factor < 1)
|
||||||
|
output.pos.y *= correction_factor;
|
||||||
|
else
|
||||||
|
output.pos.x /= correction_factor;
|
||||||
|
|
||||||
|
output.pos.zw = float2(0, 1);
|
||||||
|
|
||||||
|
output.uv0uv1.zw = float2(0, 0);
|
||||||
|
|
||||||
|
output.uv0uv1.xy = lerp(input.uv0uv1.xy, input.uv0uv1.zw, input.uv.xy);
|
||||||
|
output.tile_type = input.tile_type;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
BIN
bin/font_creator.exe
Normal file
BIN
bin/font_creator.exe
Normal file
Binary file not shown.
BIN
bin/font_creator.pdb
Normal file
BIN
bin/font_creator.pdb
Normal file
Binary file not shown.
BIN
bin/pokemon.exe
BIN
bin/pokemon.exe
Binary file not shown.
BIN
bin/pokemon.pdb
BIN
bin/pokemon.pdb
Binary file not shown.
162
font_creator.vcxproj
Normal file
162
font_creator.vcxproj
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{47fdfb7b-4bd1-4255-9740-81e9e21495d1}</ProjectGuid>
|
||||||
|
<RootNamespace>fontcreator</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>ClangCL</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)vs_trash\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)vs_trash\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\font_main.cpp" />
|
||||||
|
<ClCompile Include="src\load_entire_file.cpp" />
|
||||||
|
<ClCompile Include="src\log.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\glyphs.h" />
|
||||||
|
<ClInclude Include="src\stb_image.h" />
|
||||||
|
<ClInclude Include="src\stb_image_write.h" />
|
||||||
|
<ClInclude Include="src\stb_rect_pack.h" />
|
||||||
|
<ClInclude Include="src\stb_truetype.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
45
font_creator.vcxproj.filters
Normal file
45
font_creator.vcxproj.filters
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\font_main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\log.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\load_entire_file.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\stb_truetype.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\stb_image_write.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\stb_rect_pack.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\stb_image.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\glyphs.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
14
font_creator.vcxproj.user
Normal file
14
font_creator.vcxproj.user
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ShowAllFiles>true</ShowAllFiles>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin\</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin\</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
Binary file not shown.
BIN
gamedesign/map_layout/tile_sizes.png
Normal file
BIN
gamedesign/map_layout/tile_sizes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
16
pokemon.sln
16
pokemon.sln
@ -5,16 +5,32 @@ VisualStudioVersion = 16.0.31019.35
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pokemon", "pokemon.vcxproj", "{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pokemon", "pokemon.vcxproj", "{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "font_creator", "font_creator.vcxproj", "{47FDFB7B-4BD1-4255-9740-81E9E21495D1}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x64.ActiveCfg = Debug|x64
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x64.Build.0 = Debug|x64
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Debug|x86.Build.0 = Debug|Win32
|
||||||
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x64.ActiveCfg = Release|x64
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x64.ActiveCfg = Release|x64
|
||||||
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x64.Build.0 = Release|x64
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x64.Build.0 = Release|x64
|
||||||
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{07F7D6C3-29D6-4D4C-BA7D-0D867747FB24}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{47FDFB7B-4BD1-4255-9740-81E9E21495D1}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -74,8 +74,8 @@
|
|||||||
<IntDir>$(SolutionDir)vs_trash\</IntDir>
|
<IntDir>$(SolutionDir)vs_trash\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)bin</OutDir>
|
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||||
<IntDir>$(SolutionDir)vs_trash</IntDir>
|
<IntDir>$(SolutionDir)vs_trash\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@ -111,6 +111,17 @@
|
|||||||
<AdditionalOptions>-Wno-missing-braces -Wno-parentheses -Wno-reorder-init-list -Wno-unused-variable -Wno-format %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>-Wno-missing-braces -Wno-parentheses -Wno-reorder-init-list -Wno-unused-variable -Wno-format %(AdditionalOptions)</AdditionalOptions>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\create_window.cpp" />
|
<ClCompile Include="src\create_window.cpp" />
|
||||||
|
|||||||
@ -4,7 +4,11 @@
|
|||||||
<ShowAllFiles>true</ShowAllFiles>
|
<ShowAllFiles>true</ShowAllFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin</LocalDebuggerWorkingDirectory>
|
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin\</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(ProjectDir)bin\</LocalDebuggerWorkingDirectory>
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
100
src/font_main.cpp
Normal file
100
src/font_main.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "stb_rect_pack.h"
|
||||||
|
#include "stb_truetype.h"
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
#include "load_entire_file.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "defer.h"
|
||||||
|
#include "glyphs.h"
|
||||||
|
|
||||||
|
struct Glyph {
|
||||||
|
int x_off;
|
||||||
|
int y_off;
|
||||||
|
char* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Glyph_Coord glyph_coords[512];
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stbtt_fontinfo font_info;
|
||||||
|
stbrp_context packer_context;
|
||||||
|
stbrp_node packer_nodes[600];
|
||||||
|
stbrp_rect packer_rects[100];
|
||||||
|
|
||||||
|
Glyph glyphs[512];
|
||||||
|
|
||||||
|
String font_file = load_entire_file("../assets/fonts/Lexend-Regular.ttf");
|
||||||
|
|
||||||
|
if (!font_file.length) {
|
||||||
|
log_error("Loading font file has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stbtt_InitFont(&font_info, (unsigned char*)font_file.data, 0)) {
|
||||||
|
log_error("Init Font has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float font_scale = stbtt_ScaleForPixelHeight(&font_info, 48);
|
||||||
|
|
||||||
|
stbrp_init_target(&packer_context, 512, 512, packer_nodes, sizeof(packer_nodes) / sizeof(*packer_nodes));
|
||||||
|
int rect_number = 0;
|
||||||
|
for (int i = ' '; i <= '~'; i++) {
|
||||||
|
int glyph_width;
|
||||||
|
int glyph_height;
|
||||||
|
int glyph_offset_x;
|
||||||
|
int glyph_offset_y;
|
||||||
|
glyphs[rect_number].data = (char*) stbtt_GetCodepointBitmap(&font_info, font_scale, font_scale, i, &glyph_width, &glyph_height, &glyph_offset_x, &glyph_offset_y);
|
||||||
|
glyphs[rect_number].x_off = glyph_offset_x;
|
||||||
|
glyphs[rect_number].y_off = glyph_offset_y;
|
||||||
|
|
||||||
|
packer_rects[rect_number].id = i;
|
||||||
|
packer_rects[rect_number].w = glyph_width;
|
||||||
|
packer_rects[rect_number].h = glyph_height;
|
||||||
|
rect_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
stbrp_pack_rects(&packer_context, packer_rects, rect_number);
|
||||||
|
char* glyph_atlas = (char*) malloc(512 * 512);
|
||||||
|
for (int x = 0; x < 512; x++) {
|
||||||
|
for (int y = 0; y < 512; y++) {
|
||||||
|
glyph_atlas[y * 512 + x] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < rect_number; i++) {
|
||||||
|
glyph_coords[i].x = packer_rects[i].x / 512.0f;
|
||||||
|
glyph_coords[i].y = packer_rects[i].y / 512.0f;
|
||||||
|
glyph_coords[i].width = packer_rects[i].w / 512.0f;
|
||||||
|
glyph_coords[i].height = packer_rects[i].h / 512.0f;
|
||||||
|
for (int x = 0; x < packer_rects[i].w; x++) {
|
||||||
|
for (int y = 0; y < packer_rects[i].h; y++) {
|
||||||
|
glyph_atlas[(y + packer_rects[i].y) * 512 + x + packer_rects[i].x] = glyphs[i].data[y * packer_rects[i].w + x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* file = fopen("../assets/fonts/glyph_coords_lexend.co", "wb");
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
log_error("Glyph coords file creation has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
defer(fclose(file));
|
||||||
|
|
||||||
|
if (fwrite(glyph_coords, sizeof(*glyph_coords) * rect_number, 1, file) != 1) {
|
||||||
|
log_error("fwrite for glyph_coords has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stbi_write_bmp("../assets/fonts/glyph_atlas_lexend.bmp", 512, 512, 1, glyph_atlas)) {
|
||||||
|
log_error("stbi_write_bmp has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
8
src/glyphs.h
Normal file
8
src/glyphs.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct Glyph_Coord {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
};
|
||||||
@ -92,7 +92,7 @@ void swap(uint32_t& a, uint32_t& b) {
|
|||||||
b = h;
|
b = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
BMP_Texture load_tga_file(const char* path) {
|
Image_Info load_tga_file(const char* path) {
|
||||||
auto file = load_entire_file(path);
|
auto file = load_entire_file(path);
|
||||||
auto start_file = file;
|
auto start_file = file;
|
||||||
|
|
||||||
@ -107,7 +107,11 @@ BMP_Texture load_tga_file(const char* path) {
|
|||||||
expect(color_map_type, 0, "wrong color map type");
|
expect(color_map_type, 0, "wrong color map type");
|
||||||
|
|
||||||
auto image_type = read<uint8_t>(file);
|
auto image_type = read<uint8_t>(file);
|
||||||
expect(image_type, 10, "wrong image type");
|
//expect(image_type, 10, "wrong image type");
|
||||||
|
if (image_type != 10 && image_type != 11) {
|
||||||
|
log_error("wrong image type, not monochrome or not rgb");
|
||||||
|
return{ 0, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
auto color_map_info = read<TGA_Color_Map_Info >(file);
|
auto color_map_info = read<TGA_Color_Map_Info >(file);
|
||||||
expect(color_map_info.size, 0, "no existing color map");
|
expect(color_map_info.size, 0, "no existing color map");
|
||||||
@ -159,7 +163,7 @@ BMP_Texture load_tga_file(const char* path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_origin == 32) {
|
if (image_origin != 32) {
|
||||||
for (int y = 0; y < (image_specification.height / 2); y++) {
|
for (int y = 0; y < (image_specification.height / 2); y++) {
|
||||||
for (int x = 0; x < image_specification.width; x++)
|
for (int x = 0; x < image_specification.width; x++)
|
||||||
swap(start_pixel[y * image_specification.width + x], start_pixel[image_specification.width * (image_specification.height - y - 1) + x]);
|
swap(start_pixel[y * image_specification.width + x], start_pixel[image_specification.width * (image_specification.height - y - 1) + x]);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct BMP_Texture {
|
struct Image_Info {
|
||||||
int64_t bmp_width;
|
int64_t width;
|
||||||
int64_t bmp_height;
|
int64_t height;
|
||||||
uint32_t* pixel;
|
uint32_t* pixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
BMP_Texture load_tga_file(const char* path);
|
Image_Info load_tga_file(const char* path);
|
||||||
296
src/main.cpp
296
src/main.cpp
@ -18,6 +18,9 @@
|
|||||||
#include "math_graphics.h"
|
#include "math_graphics.h"
|
||||||
#include "load_tga_file.h"
|
#include "load_tga_file.h"
|
||||||
#include "load_entire_file.h"
|
#include "load_entire_file.h"
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
#include "glyphs.h"
|
||||||
|
|
||||||
typedef uint8_t uint8;
|
typedef uint8_t uint8;
|
||||||
typedef uint16_t uint16;
|
typedef uint16_t uint16;
|
||||||
@ -45,6 +48,7 @@ ID3D11Buffer* vertex_buffer;
|
|||||||
ID3D11Buffer* index_buffer;
|
ID3D11Buffer* index_buffer;
|
||||||
ID3D11Buffer* tiles_instance_buffer;
|
ID3D11Buffer* tiles_instance_buffer;
|
||||||
ID3D11Buffer* player_instance_buffer;
|
ID3D11Buffer* player_instance_buffer;
|
||||||
|
ID3D11Buffer* constant_buffer;
|
||||||
|
|
||||||
ID3DBlob* vertex_shader_code;
|
ID3DBlob* vertex_shader_code;
|
||||||
ID3D11VertexShader* vertex_shader;
|
ID3D11VertexShader* vertex_shader;
|
||||||
@ -52,6 +56,14 @@ ID3D11VertexShader* vertex_shader;
|
|||||||
ID3DBlob* pixel_shader_code;
|
ID3DBlob* pixel_shader_code;
|
||||||
ID3D11PixelShader* pixel_shader;
|
ID3D11PixelShader* pixel_shader;
|
||||||
|
|
||||||
|
ID3DBlob* font_vertex_shader_code;
|
||||||
|
ID3D11VertexShader* font_vertex_shader;
|
||||||
|
|
||||||
|
ID3DBlob* font_pixel_shader_code;
|
||||||
|
ID3D11PixelShader* font_pixel_shader;
|
||||||
|
|
||||||
|
ID3D11Buffer* quad_instance_buffer;
|
||||||
|
|
||||||
int16 window_width;
|
int16 window_width;
|
||||||
int16 window_height;
|
int16 window_height;
|
||||||
|
|
||||||
@ -61,17 +73,16 @@ bool Running = true;
|
|||||||
#define view_width 17
|
#define view_width 17
|
||||||
#define view_height 13
|
#define view_height 13
|
||||||
|
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
V4 pos;
|
V4 pos;
|
||||||
V4 uvst;
|
V2 uv0uv1;
|
||||||
};
|
};
|
||||||
|
|
||||||
Vertex vertices[] = {
|
Vertex vertices[] = {
|
||||||
{{ -1, 1, 1, 1 } , { 0, 1, 0, 0 }},
|
{{ -1, 1, 1, 1 }, {0, 0}},
|
||||||
{{ 1, -1, 1, 1 } , { 1, 0, 0, 0 }},
|
{{ 1, -1, 1, 1 }, {1, 1}},
|
||||||
{{ -1, -1, 1, 1 } , { 0, 0, 0, 0 }},
|
{{ -1, -1, 1, 1 }, {0, 1}},
|
||||||
{{ 1, 1, 1, 1 } , { 1, 1, 0, 0 }},
|
{{ 1, 1, 1, 1 }, {1, 0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16 indices[] = {
|
uint16 indices[] = {
|
||||||
@ -82,13 +93,14 @@ uint16 indices[] = {
|
|||||||
struct Instance {
|
struct Instance {
|
||||||
V4 pos_size;
|
V4 pos_size;
|
||||||
uint32 tile_type;
|
uint32 tile_type;
|
||||||
|
V4 uv0uv1;
|
||||||
};
|
};
|
||||||
|
|
||||||
Instance tiles_instances[view_width * view_height] = {
|
Instance tiles_instances[view_width * view_height] = {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Instance player_instance = { {0.5f, 0.5f, 1.0f / view_width, 1.0f / view_height } };
|
Instance player_instance = { {0.5f, 0.5f, 1.0f / view_width, 1.0f / view_height}, 0, {0, 0, 1, 1}};
|
||||||
|
|
||||||
struct Tile {
|
struct Tile {
|
||||||
uint32 type;
|
uint32 type;
|
||||||
@ -109,6 +121,15 @@ Player player = {
|
|||||||
.pos_y = 6,
|
.pos_y = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Instance quad_instance = { {0.1f, 0.1f, 0.1f, 0.1f } };
|
||||||
|
|
||||||
|
struct PerFrame {
|
||||||
|
float aspect_ratio;
|
||||||
|
float empty[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
PerFrame per_frame = {1};
|
||||||
|
|
||||||
void save_map() {
|
void save_map() {
|
||||||
log("Save file is under construction.");
|
log("Save file is under construction.");
|
||||||
FILE* file = fopen("../assets/map/map.sv", "wb");
|
FILE* file = fopen("../assets/map/map.sv", "wb");
|
||||||
@ -249,6 +270,15 @@ LRESULT WindowMsgs(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam) {
|
|||||||
printf("size\n");
|
printf("size\n");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case WM_SIZING: {
|
||||||
|
window_width = ((RECT*)lParam)->right - ((RECT*)lParam)->left;
|
||||||
|
window_height = ((RECT*)lParam)->bottom - ((RECT*)lParam)->top;
|
||||||
|
if (swap_chain)
|
||||||
|
swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
printf("sizing\n");
|
||||||
|
Result = 1;
|
||||||
|
} break;
|
||||||
|
|
||||||
case WM_DESTROY: {
|
case WM_DESTROY: {
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
printf("destroy\n");
|
printf("destroy\n");
|
||||||
@ -265,11 +295,34 @@ LRESULT WindowMsgs(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam) {
|
|||||||
|
|
||||||
case WM_LBUTTONDOWN: {
|
case WM_LBUTTONDOWN: {
|
||||||
int16 mouse_x = (int16)(lParam & 0xffff);
|
int16 mouse_x = (int16)(lParam & 0xffff);
|
||||||
int16 mouse_y = (int16)((lParam & 0xffff0000) >> 16);
|
int16 mouse_y = (int16)((lParam & 0xffff0000) >> 16);
|
||||||
|
|
||||||
|
V2 X = V2{ -1, 1 };
|
||||||
|
V2 Y = V2{ -1, 1 };
|
||||||
|
|
||||||
|
float correction_factor = (window_width / (float)window_height) / (16.0 / 9.0);
|
||||||
|
if (correction_factor < 1)
|
||||||
|
Y *= correction_factor;
|
||||||
|
else
|
||||||
|
X /= correction_factor;
|
||||||
|
|
||||||
|
float m_x = remap(0, window_width, -1, 1, mouse_x);
|
||||||
|
float m_y = remap(0, window_height, -1, 1, mouse_y);
|
||||||
|
|
||||||
|
mouse_x = remap(X.x, X.y, 0, window_width, m_x);
|
||||||
|
mouse_y = remap(Y.x, Y.y, 0, window_height, m_y);
|
||||||
|
|
||||||
float tile_width = window_width / (float) view_width;
|
float tile_width = window_width / (float) view_width;
|
||||||
float tile_height = window_height / (float) view_height;
|
float tile_height = window_height / (float) view_height;
|
||||||
|
|
||||||
int tile_x = (int)(mouse_x / tile_width) + player.pos_x - (view_width / 2);
|
int tile_x = (int)(mouse_x / tile_width) + player.pos_x - (view_width / 2);
|
||||||
int tile_y = (int)(mouse_y / tile_height) + player.pos_y - (view_height / 2);
|
int tile_y = (int)(mouse_y / tile_height) + player.pos_y - (view_height / 2);
|
||||||
|
|
||||||
|
if (mouse_x < 0)
|
||||||
|
tile_x = -1;
|
||||||
|
if (mouse_y< 0)
|
||||||
|
tile_y = -1;
|
||||||
|
|
||||||
if(0 <= tile_x && tile_x < map_width &&
|
if(0 <= tile_x && tile_x < map_width &&
|
||||||
0 <= tile_y && tile_y < map_height)
|
0 <= tile_y && tile_y < map_height)
|
||||||
map_tiles[tile_x + map_width * tile_y].type = (map_tiles[tile_x + map_width * tile_y].type + 1) % 4;
|
map_tiles[tile_x + map_width * tile_y].type = (map_tiles[tile_x + map_width * tile_y].type + 1) % 4;
|
||||||
@ -379,6 +432,8 @@ bool LoadShaders() {
|
|||||||
ID3DBlob* error_msgs = 0;
|
ID3DBlob* error_msgs = 0;
|
||||||
HRESULT error_code = 0;
|
HRESULT error_code = 0;
|
||||||
|
|
||||||
|
//Basic Shader
|
||||||
|
|
||||||
if (error_code = D3DCompileFromFile(L"../Assets/Shader/basic_vertex_shader.hlsl", 0, 0, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertex_shader_code, &error_msgs)) {
|
if (error_code = D3DCompileFromFile(L"../Assets/Shader/basic_vertex_shader.hlsl", 0, 0, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertex_shader_code, &error_msgs)) {
|
||||||
log("CompileFromFile has failed");
|
log("CompileFromFile has failed");
|
||||||
if (error_msgs)
|
if (error_msgs)
|
||||||
@ -402,6 +457,32 @@ bool LoadShaders() {
|
|||||||
log_error("CreatePixelShader has failed");
|
log_error("CreatePixelShader has failed");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Font Shader
|
||||||
|
|
||||||
|
if (error_code = D3DCompileFromFile(L"../Assets/Shader/font_vertex_shader.hlsl", 0, 0, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &font_vertex_shader_code, &error_msgs)) {
|
||||||
|
log("CompileFromFile has failed");
|
||||||
|
if (error_msgs)
|
||||||
|
log_error("%.*s", error_msgs->GetBufferSize(), error_msgs->GetBufferPointer());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->CreateVertexShader(font_vertex_shader_code->GetBufferPointer(), font_vertex_shader_code->GetBufferSize(), 0, &font_vertex_shader)) {
|
||||||
|
log_error("CreateVertexShader has failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code = D3DCompileFromFile(L"../Assets/Shader/font_pixel_shader.hlsl", 0, 0, "main", "ps_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS | D3DCOMPILE_OPTIMIZATION_LEVEL0, 0, &font_pixel_shader_code, &error_msgs)) {
|
||||||
|
log("CompileFromFile has failed");
|
||||||
|
if (error_msgs)
|
||||||
|
log_error("%.*s", error_msgs->GetBufferSize(), error_msgs->GetBufferPointer());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->CreatePixelShader(font_pixel_shader_code->GetBufferPointer(), font_pixel_shader_code->GetBufferSize(), 0, &font_pixel_shader)) {
|
||||||
|
log_error("CreatePixelShader has failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -493,9 +574,10 @@ bool init_directx11(HWND Window) {
|
|||||||
|
|
||||||
D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
|
D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
|
||||||
{ "VERTEX_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "VERTEX_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "COORDINATES", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
{ "UV_VERTEX", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
{ "INSTANCE_POSITION_SIZE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
|
{ "INSTANCE_POSITION_SIZE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
|
||||||
{ "TILE_TYPE", 0, DXGI_FORMAT_R32_UINT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1},
|
{ "TILE_TYPE", 0, DXGI_FORMAT_R32_UINT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1},
|
||||||
|
{ "UV_INSTANCE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 20, D3D11_INPUT_PER_INSTANCE_DATA, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (device->CreateInputLayout(input_element_desc, sizeof(input_element_desc) / sizeof(*input_element_desc), vertex_shader_code->GetBufferPointer(), vertex_shader_code->GetBufferSize(), &input_layout)) {
|
if (device->CreateInputLayout(input_element_desc, sizeof(input_element_desc) / sizeof(*input_element_desc), vertex_shader_code->GetBufferPointer(), vertex_shader_code->GetBufferSize(), &input_layout)) {
|
||||||
@ -523,6 +605,8 @@ bool init_directx11(HWND Window) {
|
|||||||
index_buffer = CreateBuffer("index_buffer", sizeof(indices), indices, D3D11_BIND_INDEX_BUFFER);
|
index_buffer = CreateBuffer("index_buffer", sizeof(indices), indices, D3D11_BIND_INDEX_BUFFER);
|
||||||
tiles_instance_buffer = CreateBuffer("tiles_instance_buffer", sizeof(tiles_instances), tiles_instances, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
tiles_instance_buffer = CreateBuffer("tiles_instance_buffer", sizeof(tiles_instances), tiles_instances, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
player_instance_buffer = CreateBuffer("player_instance_buffer", sizeof(player_instance), &player_instance, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
player_instance_buffer = CreateBuffer("player_instance_buffer", sizeof(player_instance), &player_instance, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
|
quad_instance_buffer = CreateBuffer("quad_instance_buffer", sizeof(quad_instance), &quad_instance, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
|
constant_buffer = CreateBuffer("constant_buffer", sizeof(per_frame), &per_frame, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||||
|
|
||||||
D3D11_SAMPLER_DESC sampler_desc = {
|
D3D11_SAMPLER_DESC sampler_desc = {
|
||||||
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
|
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
|
||||||
@ -573,7 +657,7 @@ bool init_directx11(HWND Window) {
|
|||||||
ID3D11ShaderResourceView* create_shader_texture_array(int num_textures, char** bmp_texture_paths, String debug_name) {
|
ID3D11ShaderResourceView* create_shader_texture_array(int num_textures, char** bmp_texture_paths, String debug_name) {
|
||||||
assert(num_textures >= 1);
|
assert(num_textures >= 1);
|
||||||
|
|
||||||
BMP_Texture* bmp_textures = (BMP_Texture*) malloc(num_textures * sizeof(BMP_Texture));
|
Image_Info* bmp_textures = (Image_Info*) malloc(num_textures * sizeof(Image_Info));
|
||||||
defer(free(bmp_textures));
|
defer(free(bmp_textures));
|
||||||
|
|
||||||
for (int i = 0; i < num_textures; i++) {
|
for (int i = 0; i < num_textures; i++) {
|
||||||
@ -587,13 +671,13 @@ ID3D11ShaderResourceView* create_shader_texture_array(int num_textures, char** b
|
|||||||
defer(for (int i = 0; i < num_textures; i++) { free(bmp_textures[i].pixel); });
|
defer(for (int i = 0; i < num_textures; i++) { free(bmp_textures[i].pixel); });
|
||||||
|
|
||||||
for (int i = 1; i < num_textures; i++) {
|
for (int i = 1; i < num_textures; i++) {
|
||||||
assert(bmp_textures[i].bmp_width == bmp_textures[i - 1].bmp_width);
|
assert(bmp_textures[i].width == bmp_textures[i - 1].width);
|
||||||
assert(bmp_textures[i].bmp_height == bmp_textures[i - 1].bmp_height);
|
assert(bmp_textures[i].height == bmp_textures[i - 1].height);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC texture_desc = {
|
D3D11_TEXTURE2D_DESC texture_desc = {
|
||||||
.Width = (UINT) bmp_textures[0].bmp_width,
|
.Width = (UINT) bmp_textures[0].width,
|
||||||
.Height = (UINT) bmp_textures[0].bmp_height,
|
.Height = (UINT) bmp_textures[0].height,
|
||||||
.MipLevels = 1,
|
.MipLevels = 1,
|
||||||
.ArraySize = (UINT) num_textures,
|
.ArraySize = (UINT) num_textures,
|
||||||
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
|
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
@ -610,7 +694,7 @@ ID3D11ShaderResourceView* create_shader_texture_array(int num_textures, char** b
|
|||||||
for (int i = 0; i < num_textures; i++) {
|
for (int i = 0; i < num_textures; i++) {
|
||||||
initial_data[i] = {
|
initial_data[i] = {
|
||||||
.pSysMem = bmp_textures[i].pixel,
|
.pSysMem = bmp_textures[i].pixel,
|
||||||
.SysMemPitch = (UINT)bmp_textures[i].bmp_width * 4,
|
.SysMemPitch = (UINT)bmp_textures[i].width * 4,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,12 +717,16 @@ ID3D11ShaderResourceView* create_shader_texture_array(int num_textures, char** b
|
|||||||
|
|
||||||
|
|
||||||
// 1 Texture erzeugen
|
// 1 Texture erzeugen
|
||||||
ID3D11ShaderResourceView* create_shader_texture(char* bmp_texture_path) {
|
ID3D11ShaderResourceView* create_shader_texture(char* tga_texture_path) {
|
||||||
BMP_Texture bmp_texture = load_tga_file(bmp_texture_path);
|
Image_Info tga_texture = load_tga_file(tga_texture_path);
|
||||||
|
if (!tga_texture.pixel) {
|
||||||
|
log_error("Load file has failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC texture_desc = {
|
D3D11_TEXTURE2D_DESC texture_desc = {
|
||||||
.Width = (UINT)bmp_texture.bmp_width,
|
.Width = (UINT)tga_texture.width,
|
||||||
.Height = (UINT)bmp_texture.bmp_height,
|
.Height = (UINT)tga_texture.height,
|
||||||
.MipLevels = 1,
|
.MipLevels = 1,
|
||||||
.ArraySize = 1,
|
.ArraySize = 1,
|
||||||
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
|
.Format = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
@ -650,8 +738,66 @@ ID3D11ShaderResourceView* create_shader_texture(char* bmp_texture_path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
D3D11_SUBRESOURCE_DATA initial_data = {
|
D3D11_SUBRESOURCE_DATA initial_data = {
|
||||||
.pSysMem = bmp_texture.pixel,
|
.pSysMem = tga_texture.pixel,
|
||||||
.SysMemPitch = (UINT)bmp_texture.bmp_width * 4,
|
.SysMemPitch = (UINT)tga_texture.width * 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
ID3D11Texture2D* texture;
|
||||||
|
if ((hresult = device->CreateTexture2D(&texture_desc, &initial_data, &texture)) != S_OK) {
|
||||||
|
log_error("CreateTexture2D has failed. %ld", hresult);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DX11SetDebugName(texture, { strlen(tga_texture_path), tga_texture_path });
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* resource_view;
|
||||||
|
if ((hresult = device->CreateShaderResourceView(texture, 0, &resource_view)) != S_OK) {
|
||||||
|
log_error("CreateShaderResourceView failed. %ld", hresult);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DX11SetDebugName(resource_view, {strlen(tga_texture_path), tga_texture_path });
|
||||||
|
|
||||||
|
free(tga_texture.pixel);
|
||||||
|
return resource_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* create_shader_texture_bmp(char* bmp_texture_path) {
|
||||||
|
//Image_Info bmp_texture = load_tga_file(bmp_texture_path);
|
||||||
|
int x, y, n;
|
||||||
|
unsigned char* bmp_texture = stbi_load(bmp_texture_path, &x, &y, &n, 0);
|
||||||
|
if (!bmp_texture) {
|
||||||
|
log_error("Load file has failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_FORMAT bmp_format;
|
||||||
|
|
||||||
|
if (n == 1)
|
||||||
|
bmp_format = DXGI_FORMAT_R8_UNORM;
|
||||||
|
else if (n == 2)
|
||||||
|
bmp_format = DXGI_FORMAT_R8G8_UNORM;
|
||||||
|
else if (n == 3) {
|
||||||
|
log_error("3 channel dxgi format not supported");
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
bmp_format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
|
||||||
|
|
||||||
|
D3D11_TEXTURE2D_DESC texture_desc = {
|
||||||
|
.Width = (UINT)x,
|
||||||
|
.Height = (UINT)y,
|
||||||
|
.MipLevels = 1,
|
||||||
|
.ArraySize = 1,
|
||||||
|
.Format = bmp_format,
|
||||||
|
.SampleDesc = {.Count = 1, .Quality = 0},
|
||||||
|
.Usage = D3D11_USAGE_DEFAULT,
|
||||||
|
.BindFlags = D3D11_BIND_SHADER_RESOURCE,
|
||||||
|
.CPUAccessFlags = 0,
|
||||||
|
.MiscFlags = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA initial_data = {
|
||||||
|
.pSysMem = bmp_texture,
|
||||||
|
.SysMemPitch = (UINT)x * n,
|
||||||
};
|
};
|
||||||
|
|
||||||
ID3D11Texture2D* texture;
|
ID3D11Texture2D* texture;
|
||||||
@ -666,12 +812,48 @@ ID3D11ShaderResourceView* create_shader_texture(char* bmp_texture_path) {
|
|||||||
log_error("CreateShaderResourceView failed. %ld", hresult);
|
log_error("CreateShaderResourceView failed. %ld", hresult);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DX11SetDebugName(resource_view, {strlen(bmp_texture_path), bmp_texture_path});
|
DX11SetDebugName(resource_view, { strlen(bmp_texture_path), bmp_texture_path });
|
||||||
|
|
||||||
free(bmp_texture.pixel);
|
free(bmp_texture);
|
||||||
return resource_view;
|
return resource_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render_quad(V2 pos, V2 size, ID3D11ShaderResourceView* texture, V2 uv0, V2 uv1) {
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* quad_texture = texture;
|
||||||
|
|
||||||
|
quad_instance.pos_size.xy = pos;
|
||||||
|
quad_instance.pos_size.zw = size;
|
||||||
|
quad_instance.uv0uv1.uv0 = uv0;
|
||||||
|
quad_instance.uv0uv1.uv1 = uv1;
|
||||||
|
|
||||||
|
//Grafikkarte updaten
|
||||||
|
D3D11_MAPPED_SUBRESOURCE quad_mapped_subressource;
|
||||||
|
devicecontext->Map(quad_instance_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &quad_mapped_subressource);
|
||||||
|
memcpy(quad_mapped_subressource.pData, &quad_instance, sizeof(quad_instance));
|
||||||
|
devicecontext->Unmap(quad_instance_buffer, 0);
|
||||||
|
|
||||||
|
UINT input_strides[] = {
|
||||||
|
sizeof(Vertex),
|
||||||
|
sizeof(Instance),
|
||||||
|
};
|
||||||
|
|
||||||
|
UINT input_offsets[] = {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
ID3D11Buffer* quad_input_buffer[] = {
|
||||||
|
vertex_buffer,
|
||||||
|
quad_instance_buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
devicecontext->IASetVertexBuffers(0, sizeof(quad_input_buffer) / sizeof(*quad_input_buffer), quad_input_buffer, input_strides, input_offsets);
|
||||||
|
devicecontext->PSSetShaderResources(0, 1, &quad_texture);
|
||||||
|
devicecontext->DrawIndexedInstanced(6, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
CoInitializeEx(0, COINIT_MULTITHREADED);
|
CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||||
|
|
||||||
@ -687,34 +869,58 @@ int main() {
|
|||||||
tiles_instances[x + y * view_width].pos_size.zw = { 1.0f / view_width, 1.0f / view_height };
|
tiles_instances[x + y * view_width].pos_size.zw = { 1.0f / view_width, 1.0f / view_height };
|
||||||
tiles_instances[x + y * view_width].pos_size.xy = { (float)x / view_width, (float)y / (float)view_height };
|
tiles_instances[x + y * view_width].pos_size.xy = { (float)x / view_width, (float)y / (float)view_height };
|
||||||
tiles_instances[x + y * view_width].pos_size.xy += tiles_instances[x + y * view_width].pos_size.zw * 0.5f;
|
tiles_instances[x + y * view_width].pos_size.xy += tiles_instances[x + y * view_width].pos_size.zw * 0.5f;
|
||||||
|
tiles_instances[x + y * view_width].uv0uv1 = { 0, 0, 1, 1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_directx11(Window))
|
if (init_directx11(Window))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Eine Textur erzeugen
|
|
||||||
ID3D11ShaderResourceView* tile_texture = 0;
|
|
||||||
if (!(tile_texture = create_shader_texture("../assets/tile_grass_2.tga"))) {
|
|
||||||
log_error("CreateShaderTexture has failed.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11ShaderResourceView* player_texture = 0;
|
ID3D11ShaderResourceView* player_texture = 0;
|
||||||
if (!(player_texture = create_shader_texture("../assets/strawberry.tga"))) {
|
if (!(player_texture = create_shader_texture("../assets/strawberry.tga"))) {
|
||||||
log_error("CreateShaderTexture has failed.");
|
log_error("CreateShaderTexture has failed.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* quad_texture = 0;
|
||||||
|
if (!(quad_texture = create_shader_texture("../assets/tile_grass_2.tga"))) {
|
||||||
|
log_error("CreateShaderTexture has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//mehrere Texturen erzeugen
|
//mehrere Texturen erzeugen
|
||||||
|
ID3D11ShaderResourceView* tile_texture = 0;
|
||||||
char* tile_texture_array[] = { "../assets/tile_empty.tga", "../assets/tile_grass_2.tga" , "../assets/tile_dirt.tga" , "../assets/tile_water.tga", "../assets/tile_error.tga" };
|
char* tile_texture_array[] = { "../assets/tile_empty.tga", "../assets/tile_grass_2.tga" , "../assets/tile_dirt.tga" , "../assets/tile_water.tga", "../assets/tile_error.tga" };
|
||||||
if (!(tile_texture = create_shader_texture_array(sizeof(tile_texture_array) / sizeof(*tile_texture_array), tile_texture_array, "tile_textures"))) {
|
if (!(tile_texture = create_shader_texture_array(sizeof(tile_texture_array) / sizeof(*tile_texture_array), tile_texture_array, "tile_textures"))) {
|
||||||
log_error("CreateShaderTextrueArray has failed.");
|
log_error("CreateShaderTextrueArray has failed.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID3D11ShaderResourceView* glyph_texture = 0;
|
||||||
|
if (!(glyph_texture = create_shader_texture_bmp("../assets/fonts/glyph_atlas_lexend.tga"))) {
|
||||||
|
log_error("CreateShaderTexture has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
load_map();
|
load_map();
|
||||||
|
|
||||||
|
String file = load_entire_file("../assets/fonts/glyph_coords_lexend.co");
|
||||||
|
if (!file.length) {
|
||||||
|
log_error("Loading glyph_coords_lexend has failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glyphs_num = file.length / sizeof(Glyph_Coord);
|
||||||
|
if (glyphs_num != '~' - ' ' + 1) {
|
||||||
|
log_error("Wrong number of glyphs.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Glyph_Coord* glyph_coords = (Glyph_Coord*) file.data;
|
||||||
|
|
||||||
|
V2 quad_pos = { 0.101f, 0.101f };
|
||||||
|
V2 quad_size = { 0.1f, 0.1f };
|
||||||
|
|
||||||
MSG Message;
|
MSG Message;
|
||||||
while (Running) {
|
while (Running) {
|
||||||
while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) {
|
while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) {
|
||||||
@ -738,14 +944,20 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
per_frame.aspect_ratio = (float) window_width / (float) window_height;
|
||||||
|
|
||||||
//Grafikkarte updaten
|
//Grafikkarte updaten
|
||||||
D3D11_MAPPED_SUBRESOURCE mapped_subressource;
|
D3D11_MAPPED_SUBRESOURCE mapped_subressource;
|
||||||
devicecontext->Map(tiles_instance_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subressource);
|
devicecontext->Map(tiles_instance_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subressource);
|
||||||
memcpy(mapped_subressource.pData, tiles_instances, sizeof(tiles_instances));
|
memcpy(mapped_subressource.pData, tiles_instances, sizeof(tiles_instances));
|
||||||
devicecontext->Unmap(tiles_instance_buffer, 0);
|
devicecontext->Unmap(tiles_instance_buffer, 0);
|
||||||
|
|
||||||
|
devicecontext->Map(constant_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_subressource);
|
||||||
|
memcpy(mapped_subressource.pData, &per_frame, sizeof(per_frame));
|
||||||
|
devicecontext->Unmap(constant_buffer, 0);
|
||||||
|
|
||||||
devicecontext->OMSetRenderTargets(1, &render_target_view, 0);
|
devicecontext->OMSetRenderTargets(1, &render_target_view, 0);
|
||||||
V4 clear_color = { 0, 0, 0, 1 };
|
V4 clear_color = { 1, 0, 1, 1 };
|
||||||
devicecontext->ClearRenderTargetView(render_target_view, clear_color.E);
|
devicecontext->ClearRenderTargetView(render_target_view, clear_color.E);
|
||||||
|
|
||||||
devicecontext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
devicecontext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
@ -770,8 +982,8 @@ int main() {
|
|||||||
|
|
||||||
devicecontext->IASetVertexBuffers(0, sizeof(tiles_input_buffers) / sizeof(*tiles_input_buffers), tiles_input_buffers, input_strides, input_offsets);
|
devicecontext->IASetVertexBuffers(0, sizeof(tiles_input_buffers) / sizeof(*tiles_input_buffers), tiles_input_buffers, input_strides, input_offsets);
|
||||||
devicecontext->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R16_UINT, 0);
|
devicecontext->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R16_UINT, 0);
|
||||||
|
devicecontext->VSSetConstantBuffers(0, 1, &constant_buffer);
|
||||||
|
|
||||||
devicecontext->IASetInputLayout(input_layout);
|
|
||||||
devicecontext->VSSetShader(vertex_shader, 0, 0);
|
devicecontext->VSSetShader(vertex_shader, 0, 0);
|
||||||
devicecontext->PSSetShader(pixel_shader, 0, 0);
|
devicecontext->PSSetShader(pixel_shader, 0, 0);
|
||||||
|
|
||||||
@ -785,14 +997,28 @@ int main() {
|
|||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
player_instance_buffer,
|
player_instance_buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
devicecontext->IASetVertexBuffers(0, sizeof(player_input_buffers) / sizeof(*player_input_buffers), player_input_buffers, input_strides, input_offsets);
|
devicecontext->IASetVertexBuffers(0, sizeof(player_input_buffers) / sizeof(*player_input_buffers), player_input_buffers, input_strides, input_offsets);
|
||||||
|
|
||||||
devicecontext->PSSetShaderResources(0, 1, &player_texture);
|
devicecontext->PSSetShaderResources(0, 1, &player_texture);
|
||||||
devicecontext->DrawIndexedInstanced(6, 1, 0, 0, 0);
|
devicecontext->DrawIndexedInstanced(6, 1, 0, 0, 0);
|
||||||
|
|
||||||
//
|
//Moving Quad
|
||||||
swap_chain->Present(0, 0);
|
//quad_pos += {0.001f, 0.001f};
|
||||||
|
|
||||||
|
render_quad(quad_pos, quad_size, quad_texture, { 0, 0 }, { 0.5, 1 });
|
||||||
|
render_quad({ 0.1, 0.2 }, { 0.01, 0.01 }, quad_texture, { 0, 0 }, { 1, 1 });
|
||||||
|
|
||||||
|
devicecontext->VSSetShader(font_vertex_shader, 0, 0);
|
||||||
|
devicecontext->PSSetShader(font_pixel_shader, 0, 0);
|
||||||
|
|
||||||
|
//Glyph test rendering
|
||||||
|
|
||||||
|
int buchstabe = 'M' - ' ';
|
||||||
|
|
||||||
|
render_quad({ 0.5, 0.7 }, { glyph_coords[buchstabe].width * ( 512.0f / window_width), glyph_coords[buchstabe].height * (512.0f / window_height)}, glyph_texture, { glyph_coords[buchstabe].x, glyph_coords[buchstabe].y }, { glyph_coords[buchstabe].x + glyph_coords[buchstabe].width, glyph_coords[buchstabe].y + glyph_coords[buchstabe].height } );
|
||||||
|
|
||||||
|
swap_chain->Present(1, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -70,10 +70,19 @@ constexpr inline T min(T a, T b) {
|
|||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr float lerp(float a, float t, float b) {
|
constexpr float lerp(float a, float b, float t) {
|
||||||
return (1.0f - t) * a + t * b;
|
return (1.0f - t) * a + t * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ilerp(float a, float b, float v) {
|
||||||
|
return (v - a) / (b - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
float remap(float in_a, float in_b, float out_a, float out_b, float v) {
|
||||||
|
float t = ilerp(in_a, in_b, v);
|
||||||
|
return lerp(out_a, out_b, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
//Vektorberechnung 2-dim
|
//Vektorberechnung 2-dim
|
||||||
@ -103,7 +112,6 @@ union V2 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Negation von 2-dim Vektor
|
//Negation von 2-dim Vektor
|
||||||
inline V2 operator -(V2 a) {
|
inline V2 operator -(V2 a) {
|
||||||
return {
|
return {
|
||||||
@ -144,7 +152,6 @@ inline V2 operator *(float a, V2 b) {
|
|||||||
a * b.x,
|
a * b.x,
|
||||||
a * b.y
|
a * b.y
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Skalarmultiplikation -> erst Vektor, dann Skalar
|
//Skalarmultiplikation -> erst Vektor, dann Skalar
|
||||||
@ -153,10 +160,15 @@ inline V2 operator *(V2 a, float b) {
|
|||||||
a.x * b,
|
a.x * b,
|
||||||
a.y * b
|
a.y * b
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Division mit nem Skalar Oo -> Skalar geteilt durch Vektor
|
//Skalarmultiplikation -> mit V2 Pointer
|
||||||
|
inline V2 &operator *= (V2 &a, float b) {
|
||||||
|
a = a * b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Division mit einem Skalar Oo -> Skalar geteilt durch Vektor
|
||||||
inline V2 operator /(float a, V2 b) {
|
inline V2 operator /(float a, V2 b) {
|
||||||
return {
|
return {
|
||||||
a / b.x,
|
a / b.x,
|
||||||
@ -164,7 +176,7 @@ inline V2 operator /(float a, V2 b) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//Division mit nem Skalar Oo -> Vektor geteilt durch Skalar
|
//Division mit einem Skalar Oo -> Vektor geteilt durch Skalar
|
||||||
inline V2 operator /(V2 a, float b) {
|
inline V2 operator /(V2 a, float b) {
|
||||||
return {
|
return {
|
||||||
a.x / b,
|
a.x / b,
|
||||||
@ -172,6 +184,19 @@ inline V2 operator /(V2 a, float b) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Division mit einem Skalar -> 2 Vektoren
|
||||||
|
inline V2 operator /(V2 a, V2 b) {
|
||||||
|
return {
|
||||||
|
a.x / b.x,
|
||||||
|
a.y / b.y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Division mit einem Skalar -> mit V2 Pointer
|
||||||
|
inline V2 &operator /= (V2 &a, float b) {
|
||||||
|
a = a / b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
//Skalarprodukt
|
//Skalarprodukt
|
||||||
inline float dot(V2 a, V2 b) {
|
inline float dot(V2 a, V2 b) {
|
||||||
@ -222,6 +247,7 @@ inline V2 clamp01(V2 a) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Vektor mit den kleinsten Werten 2er Vektoren
|
||||||
inline V2 min(V2 a, V2 b) {
|
inline V2 min(V2 a, V2 b) {
|
||||||
return {
|
return {
|
||||||
min(a.x, b.x),
|
min(a.x, b.x),
|
||||||
@ -229,6 +255,7 @@ inline V2 min(V2 a, V2 b) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Vektor mit den groessten Werten 2er Vektoren
|
||||||
inline V2 max(V2 a, V2 b) {
|
inline V2 max(V2 a, V2 b) {
|
||||||
return {
|
return {
|
||||||
max(a.x, b.x),
|
max(a.x, b.x),
|
||||||
@ -236,14 +263,34 @@ inline V2 max(V2 a, V2 b) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//kleinster Vektor Wert
|
||||||
inline float min(V2 a) {
|
inline float min(V2 a) {
|
||||||
return min(a.x, a.y);
|
return min(a.x, a.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//groesster Vektor Wert
|
||||||
inline float max(V2 a) {
|
inline float max(V2 a) {
|
||||||
return max(a.x, a.y);
|
return max(a.x, a.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Lerp mit 2 Vektoren
|
||||||
|
inline V2 lerp(V2 a, V2 b, V2 t) {
|
||||||
|
return V2{
|
||||||
|
lerp(a.x, b.x, t.x),
|
||||||
|
lerp(a.y, b.y, t.y),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
V2 ilerp(V2 a, V2 b, V2 v) {
|
||||||
|
return (v - a) / (b - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
V2 remap(V2 in_a, V2 in_b, V2 out_a, V2 out_b, V2 v) {
|
||||||
|
V2 t = ilerp(in_a, in_b, v);
|
||||||
|
return lerp(out_a, out_b, t);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
//Vektorberechnung 3-dim
|
//Vektorberechnung 3-dim
|
||||||
@ -299,7 +346,6 @@ inline V3 operator -(V3 a) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Addition 2er 2-dim Vektoren
|
//Addition 2er 2-dim Vektoren
|
||||||
inline V3 operator +(V3 a, V3 b) {
|
inline V3 operator +(V3 a, V3 b) {
|
||||||
return {
|
return {
|
||||||
@ -423,13 +469,19 @@ union V4 {
|
|||||||
float t;
|
float t;
|
||||||
};
|
};
|
||||||
|
|
||||||
//von V3 zu V2 ohne z
|
//von V4 zu V2 ohne z
|
||||||
struct {
|
struct {
|
||||||
V2 xy;
|
V2 xy;
|
||||||
V2 zw;
|
V2 zw;
|
||||||
};
|
};
|
||||||
|
|
||||||
//von V3 zu V2 ohne x
|
//V2 fuer Teiltexturenausgabe
|
||||||
|
struct {
|
||||||
|
V2 uv0;
|
||||||
|
V2 uv1;
|
||||||
|
};
|
||||||
|
|
||||||
|
//von V4 zu V2 ohne x
|
||||||
struct {
|
struct {
|
||||||
float _x;
|
float _x;
|
||||||
V2 yz;
|
V2 yz;
|
||||||
|
|||||||
8000
src/stb_image.h
Normal file
8000
src/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
1708
src/stb_image_write.h
Normal file
1708
src/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load Diff
633
src/stb_rect_pack.h
Normal file
633
src/stb_rect_pack.h
Normal file
@ -0,0 +1,633 @@
|
|||||||
|
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
||||||
|
// Sean Barrett 2014
|
||||||
|
//
|
||||||
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||||||
|
// Does not do rotation.
|
||||||
|
//
|
||||||
|
// Not necessarily the awesomest packing method, but better than
|
||||||
|
// the totally naive one in stb_truetype (which is primarily what
|
||||||
|
// this is meant to replace).
|
||||||
|
//
|
||||||
|
// Has only had a few tests run, may have issues.
|
||||||
|
//
|
||||||
|
// More docs to come.
|
||||||
|
//
|
||||||
|
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||||
|
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||||
|
//
|
||||||
|
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||||
|
//
|
||||||
|
// Please note: better rectangle packers are welcome! Please
|
||||||
|
// implement them to the same API, but with a different init
|
||||||
|
// function.
|
||||||
|
//
|
||||||
|
// Credits
|
||||||
|
//
|
||||||
|
// Library
|
||||||
|
// Sean Barrett
|
||||||
|
// Minor features
|
||||||
|
// Martins Mozeiko
|
||||||
|
// github:IntellectualKitty
|
||||||
|
//
|
||||||
|
// Bugfixes / warning fixes
|
||||||
|
// Jeremy Jaussaud
|
||||||
|
// Fabian Giesen
|
||||||
|
//
|
||||||
|
// Version history:
|
||||||
|
//
|
||||||
|
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||||
|
// 0.99 (2019-02-07) warning fixes
|
||||||
|
// 0.11 (2017-03-03) return packing success/fail result
|
||||||
|
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||||
|
// 0.09 (2016-08-27) fix compiler warnings
|
||||||
|
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||||
|
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||||
|
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||||
|
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||||
|
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||||
|
// 0.01: initial release
|
||||||
|
//
|
||||||
|
// LICENSE
|
||||||
|
//
|
||||||
|
// See end of file for license information.
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// INCLUDE SECTION
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||||
|
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||||
|
|
||||||
|
#define STB_RECT_PACK_VERSION 1
|
||||||
|
|
||||||
|
#ifdef STBRP_STATIC
|
||||||
|
#define STBRP_DEF static
|
||||||
|
#else
|
||||||
|
#define STBRP_DEF extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct stbrp_context stbrp_context;
|
||||||
|
typedef struct stbrp_node stbrp_node;
|
||||||
|
typedef struct stbrp_rect stbrp_rect;
|
||||||
|
|
||||||
|
#ifdef STBRP_LARGE_RECTS
|
||||||
|
typedef int stbrp_coord;
|
||||||
|
#else
|
||||||
|
typedef unsigned short stbrp_coord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STBRP_DEF int stbrp_pack_rects(stbrp_context* context, stbrp_rect* rects, int num_rects);
|
||||||
|
// Assign packed locations to rectangles. The rectangles are of type
|
||||||
|
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||||
|
// are 'num_rects' many of them.
|
||||||
|
//
|
||||||
|
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||||
|
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||||
|
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||||
|
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||||
|
// have the 'was_packed' flag set to 0.
|
||||||
|
//
|
||||||
|
// You should not try to access the 'rects' array from another thread
|
||||||
|
// while this function is running, as the function temporarily reorders
|
||||||
|
// the array while it executes.
|
||||||
|
//
|
||||||
|
// To pack into another rectangle, you need to call stbrp_init_target
|
||||||
|
// again. To continue packing into the same rectangle, you can call
|
||||||
|
// this function again. Calling this multiple times with multiple rect
|
||||||
|
// arrays will probably produce worse packing results than calling it
|
||||||
|
// a single time with the full rectangle array, but the option is
|
||||||
|
// available.
|
||||||
|
//
|
||||||
|
// The function returns 1 if all of the rectangles were successfully
|
||||||
|
// packed and 0 otherwise.
|
||||||
|
|
||||||
|
struct stbrp_rect
|
||||||
|
{
|
||||||
|
// reserved for your use:
|
||||||
|
int id;
|
||||||
|
|
||||||
|
// input:
|
||||||
|
stbrp_coord w, h;
|
||||||
|
|
||||||
|
// output:
|
||||||
|
stbrp_coord x, y;
|
||||||
|
int was_packed; // non-zero if valid packing
|
||||||
|
|
||||||
|
}; // 16 bytes, nominally
|
||||||
|
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_init_target(stbrp_context* context, int width, int height, stbrp_node* nodes, int num_nodes);
|
||||||
|
// Initialize a rectangle packer to:
|
||||||
|
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||||
|
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||||
|
//
|
||||||
|
// You must call this function every time you start packing into a new target.
|
||||||
|
//
|
||||||
|
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||||
|
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||||
|
// the call (or calls) finish.
|
||||||
|
//
|
||||||
|
// Note: to guarantee best results, either:
|
||||||
|
// 1. make sure 'num_nodes' >= 'width'
|
||||||
|
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||||
|
//
|
||||||
|
// If you don't do either of the above things, widths will be quantized to multiples
|
||||||
|
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||||
|
//
|
||||||
|
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||||
|
// may run out of temporary storage and be unable to pack some rectangles.
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context* context, int allow_out_of_mem);
|
||||||
|
// Optionally call this function after init but before doing any packing to
|
||||||
|
// change the handling of the out-of-temp-memory scenario, described above.
|
||||||
|
// If you call init again, this will be reset to the default (false).
|
||||||
|
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_heuristic(stbrp_context* context, int heuristic);
|
||||||
|
// Optionally select which packing heuristic the library should use. Different
|
||||||
|
// heuristics will produce better/worse results for different data sets.
|
||||||
|
// If you call init again, this will be reset to the default.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STBRP_HEURISTIC_Skyline_default = 0,
|
||||||
|
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||||
|
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// the details of the following structures don't matter to you, but they must
|
||||||
|
// be visible so you can handle the memory allocations for them
|
||||||
|
|
||||||
|
struct stbrp_node
|
||||||
|
{
|
||||||
|
stbrp_coord x, y;
|
||||||
|
stbrp_node* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stbrp_context
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int align;
|
||||||
|
int init_mode;
|
||||||
|
int heuristic;
|
||||||
|
int num_nodes;
|
||||||
|
stbrp_node* active_head;
|
||||||
|
stbrp_node* free_head;
|
||||||
|
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// IMPLEMENTATION SECTION
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
#ifndef STBRP_SORT
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define STBRP_SORT qsort
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef STBRP_ASSERT
|
||||||
|
#include <assert.h>
|
||||||
|
#define STBRP_ASSERT assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define STBRP__NOTUSED(v) (void)(v)
|
||||||
|
#else
|
||||||
|
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STBRP__INIT_skyline = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_heuristic(stbrp_context* context, int heuristic)
|
||||||
|
{
|
||||||
|
switch (context->init_mode) {
|
||||||
|
case STBRP__INIT_skyline:
|
||||||
|
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||||
|
context->heuristic = heuristic;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
STBRP_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context* context, int allow_out_of_mem)
|
||||||
|
{
|
||||||
|
if (allow_out_of_mem)
|
||||||
|
// if it's ok to run out of memory, then don't bother aligning them;
|
||||||
|
// this gives better packing, but may fail due to OOM (even though
|
||||||
|
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||||
|
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||||
|
context->align = 1;
|
||||||
|
else {
|
||||||
|
// if it's not ok to run out of memory, then quantize the widths
|
||||||
|
// so that num_nodes is always enough nodes.
|
||||||
|
//
|
||||||
|
// I.e. num_nodes * align >= width
|
||||||
|
// align >= width / num_nodes
|
||||||
|
// align = ceil(width/num_nodes)
|
||||||
|
|
||||||
|
context->align = (context->width + context->num_nodes - 1) / context->num_nodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STBRP_DEF void stbrp_init_target(stbrp_context* context, int width, int height, stbrp_node* nodes, int num_nodes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
#ifndef STBRP_LARGE_RECTS
|
||||||
|
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < num_nodes - 1; ++i)
|
||||||
|
nodes[i].next = &nodes[i + 1];
|
||||||
|
nodes[i].next = NULL;
|
||||||
|
context->init_mode = STBRP__INIT_skyline;
|
||||||
|
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||||
|
context->free_head = &nodes[0];
|
||||||
|
context->active_head = &context->extra[0];
|
||||||
|
context->width = width;
|
||||||
|
context->height = height;
|
||||||
|
context->num_nodes = num_nodes;
|
||||||
|
stbrp_setup_allow_out_of_mem(context, 0);
|
||||||
|
|
||||||
|
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||||
|
context->extra[0].x = 0;
|
||||||
|
context->extra[0].y = 0;
|
||||||
|
context->extra[0].next = &context->extra[1];
|
||||||
|
context->extra[1].x = (stbrp_coord)width;
|
||||||
|
#ifdef STBRP_LARGE_RECTS
|
||||||
|
context->extra[1].y = (1 << 30);
|
||||||
|
#else
|
||||||
|
context->extra[1].y = 65535;
|
||||||
|
#endif
|
||||||
|
context->extra[1].next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find minimum y position if it starts at x1
|
||||||
|
static int stbrp__skyline_find_min_y(stbrp_context* c, stbrp_node* first, int x0, int width, int* pwaste)
|
||||||
|
{
|
||||||
|
stbrp_node* node = first;
|
||||||
|
int x1 = x0 + width;
|
||||||
|
int min_y, visited_width, waste_area;
|
||||||
|
|
||||||
|
STBRP__NOTUSED(c);
|
||||||
|
|
||||||
|
STBRP_ASSERT(first->x <= x0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// skip in case we're past the node
|
||||||
|
while (node->next->x <= x0)
|
||||||
|
++node;
|
||||||
|
#else
|
||||||
|
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STBRP_ASSERT(node->x <= x0);
|
||||||
|
|
||||||
|
min_y = 0;
|
||||||
|
waste_area = 0;
|
||||||
|
visited_width = 0;
|
||||||
|
while (node->x < x1) {
|
||||||
|
if (node->y > min_y) {
|
||||||
|
// raise min_y higher.
|
||||||
|
// we've accounted for all waste up to min_y,
|
||||||
|
// but we'll now add more waste for everything we've visted
|
||||||
|
waste_area += visited_width * (node->y - min_y);
|
||||||
|
min_y = node->y;
|
||||||
|
// the first time through, visited_width might be reduced
|
||||||
|
if (node->x < x0)
|
||||||
|
visited_width += node->next->x - x0;
|
||||||
|
else
|
||||||
|
visited_width += node->next->x - node->x;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// add waste area
|
||||||
|
int under_width = node->next->x - node->x;
|
||||||
|
if (under_width + visited_width > width)
|
||||||
|
under_width = width - visited_width;
|
||||||
|
waste_area += under_width * (min_y - node->y);
|
||||||
|
visited_width += under_width;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pwaste = waste_area;
|
||||||
|
return min_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
stbrp_node** prev_link;
|
||||||
|
} stbrp__findresult;
|
||||||
|
|
||||||
|
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context* c, int width, int height)
|
||||||
|
{
|
||||||
|
int best_waste = (1 << 30), best_x, best_y = (1 << 30);
|
||||||
|
stbrp__findresult fr;
|
||||||
|
stbrp_node** prev, * node, * tail, ** best = NULL;
|
||||||
|
|
||||||
|
// align to multiple of c->align
|
||||||
|
width = (width + c->align - 1);
|
||||||
|
width -= width % c->align;
|
||||||
|
STBRP_ASSERT(width % c->align == 0);
|
||||||
|
|
||||||
|
// if it can't possibly fit, bail immediately
|
||||||
|
if (width > c->width || height > c->height) {
|
||||||
|
fr.prev_link = NULL;
|
||||||
|
fr.x = fr.y = 0;
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = c->active_head;
|
||||||
|
prev = &c->active_head;
|
||||||
|
while (node->x + width <= c->width) {
|
||||||
|
int y, waste;
|
||||||
|
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||||
|
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||||
|
// bottom left
|
||||||
|
if (y < best_y) {
|
||||||
|
best_y = y;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// best-fit
|
||||||
|
if (y + height <= c->height) {
|
||||||
|
// can only use it if it first vertically
|
||||||
|
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||||
|
best_y = y;
|
||||||
|
best_waste = waste;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = &node->next;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||||
|
|
||||||
|
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||||
|
//
|
||||||
|
// e.g, if fitting
|
||||||
|
//
|
||||||
|
// ____________________
|
||||||
|
// |____________________|
|
||||||
|
//
|
||||||
|
// into
|
||||||
|
//
|
||||||
|
// | |
|
||||||
|
// | ____________|
|
||||||
|
// |____________|
|
||||||
|
//
|
||||||
|
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||||
|
//
|
||||||
|
// This makes BF take about 2x the time
|
||||||
|
|
||||||
|
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||||
|
tail = c->active_head;
|
||||||
|
node = c->active_head;
|
||||||
|
prev = &c->active_head;
|
||||||
|
// find first node that's admissible
|
||||||
|
while (tail->x < width)
|
||||||
|
tail = tail->next;
|
||||||
|
while (tail) {
|
||||||
|
int xpos = tail->x - width;
|
||||||
|
int y, waste;
|
||||||
|
STBRP_ASSERT(xpos >= 0);
|
||||||
|
// find the left position that matches this
|
||||||
|
while (node->next->x <= xpos) {
|
||||||
|
prev = &node->next;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||||
|
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||||
|
if (y + height <= c->height) {
|
||||||
|
if (y <= best_y) {
|
||||||
|
if (y < best_y || waste < best_waste || (waste == best_waste && xpos < best_x)) {
|
||||||
|
best_x = xpos;
|
||||||
|
STBRP_ASSERT(y <= best_y);
|
||||||
|
best_y = y;
|
||||||
|
best_waste = waste;
|
||||||
|
best = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tail = tail->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fr.prev_link = best;
|
||||||
|
fr.x = best_x;
|
||||||
|
fr.y = best_y;
|
||||||
|
return fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context* context, int width, int height)
|
||||||
|
{
|
||||||
|
// find best position according to heuristic
|
||||||
|
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||||
|
stbrp_node* node, * cur;
|
||||||
|
|
||||||
|
// bail if:
|
||||||
|
// 1. it failed
|
||||||
|
// 2. the best node doesn't fit (we don't always check this)
|
||||||
|
// 3. we're out of memory
|
||||||
|
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||||
|
res.prev_link = NULL;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// on success, create new node
|
||||||
|
node = context->free_head;
|
||||||
|
node->x = (stbrp_coord)res.x;
|
||||||
|
node->y = (stbrp_coord)(res.y + height);
|
||||||
|
|
||||||
|
context->free_head = node->next;
|
||||||
|
|
||||||
|
// insert the new node into the right starting point, and
|
||||||
|
// let 'cur' point to the remaining nodes needing to be
|
||||||
|
// stiched back in
|
||||||
|
|
||||||
|
cur = *res.prev_link;
|
||||||
|
if (cur->x < res.x) {
|
||||||
|
// preserve the existing one, so start testing with the next one
|
||||||
|
stbrp_node* next = cur->next;
|
||||||
|
cur->next = node;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*res.prev_link = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// from here, traverse cur and free the nodes, until we get to one
|
||||||
|
// that shouldn't be freed
|
||||||
|
while (cur->next && cur->next->x <= res.x + width) {
|
||||||
|
stbrp_node* next = cur->next;
|
||||||
|
// move the current node to the free list
|
||||||
|
cur->next = context->free_head;
|
||||||
|
context->free_head = cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stitch the list back in
|
||||||
|
node->next = cur;
|
||||||
|
|
||||||
|
if (cur->x < res.x + width)
|
||||||
|
cur->x = (stbrp_coord)(res.x + width);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
cur = context->active_head;
|
||||||
|
while (cur->x < context->width) {
|
||||||
|
STBRP_ASSERT(cur->x < cur->next->x);
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(cur->next == NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
cur = context->active_head;
|
||||||
|
while (cur) {
|
||||||
|
cur = cur->next;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
cur = context->free_head;
|
||||||
|
while (cur) {
|
||||||
|
cur = cur->next;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
STBRP_ASSERT(count == context->num_nodes + 2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rect_height_compare(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
const stbrp_rect* p = (const stbrp_rect*)a;
|
||||||
|
const stbrp_rect* q = (const stbrp_rect*)b;
|
||||||
|
if (p->h > q->h)
|
||||||
|
return -1;
|
||||||
|
if (p->h < q->h)
|
||||||
|
return 1;
|
||||||
|
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rect_original_order(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
const stbrp_rect* p = (const stbrp_rect*)a;
|
||||||
|
const stbrp_rect* q = (const stbrp_rect*)b;
|
||||||
|
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef STBRP_LARGE_RECTS
|
||||||
|
#define STBRP__MAXVAL 0xffffffff
|
||||||
|
#else
|
||||||
|
#define STBRP__MAXVAL 0xffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STBRP_DEF int stbrp_pack_rects(stbrp_context* context, stbrp_rect* rects, int num_rects)
|
||||||
|
{
|
||||||
|
int i, all_rects_packed = 1;
|
||||||
|
|
||||||
|
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||||
|
for (i = 0; i < num_rects; ++i) {
|
||||||
|
rects[i].was_packed = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort according to heuristic
|
||||||
|
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||||
|
|
||||||
|
for (i = 0; i < num_rects; ++i) {
|
||||||
|
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||||
|
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||||
|
if (fr.prev_link) {
|
||||||
|
rects[i].x = (stbrp_coord)fr.x;
|
||||||
|
rects[i].y = (stbrp_coord)fr.y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsort
|
||||||
|
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||||
|
|
||||||
|
// set was_packed flags and all_rects_packed status
|
||||||
|
for (i = 0; i < num_rects; ++i) {
|
||||||
|
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||||
|
if (!rects[i].was_packed)
|
||||||
|
all_rects_packed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the all_rects_packed status
|
||||||
|
return all_rects_packed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
This software is available under 2 licenses -- choose whichever you prefer.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE A - MIT License
|
||||||
|
Copyright (c) 2017 Sean Barrett
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and successors. We intend this dedication to be an
|
||||||
|
overt act of relinquishment in perpetuity of all present and future rights to
|
||||||
|
this software under copyright law.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
5082
src/stb_truetype.h
Normal file
5082
src/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user