Compare commits

...

4 Commits

20 changed files with 228 additions and 4626 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "src/VulkanRenderer"]
path = src/VulkanRenderer
url = https://git.sleepy.day/sleepy-day/VulkanRenderer.git

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -95,10 +95,3 @@ if ! [ -f build/libcglm.a ]; then
rm $obj
fi
if ! [ -f build/atlas.png ]; then
msdf-atlas-gen -font assets/fonts/NuberNextCondensed-DemiBold.otf -dimensions 256 256 -type softmask -imageout build/atlas.png -json build/atlas.json
fi
cp build/atlas.png assets/textures/atlas.png
mkdir -p assets/data
cp build/atlas.json assets/data/atlas.json

View File

@ -9,13 +9,13 @@
"targetPath": "build",
"sourceFiles-linux": ["build/libvma.a", "build/libstb_image.a", "build/libm3d.a", "build/libcglm.a"],
"sourceFiles-windows": [],
"importPaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"],
"sourcePaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"],
"importPaths": ["src/gears", "src/shared", "external/xxhash", "external/inteli", "src/VulkanRenderer"],
"sourcePaths": ["src/gears", "src/shared", "external/xxhash", "external/inteli", "src/VulkanRenderer"],
"libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes", "freetype"],
"libs-windows": [],
"preGenerateCommands-linux": ["./build.sh", "build/Packer"],
"preGenerateCommands-linux": ["./build.sh"],
"preGenerateCommands-windows": [],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2"],
"dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-vgc"],
"dflags-dmd": ["-P=-DSTBI_NO_SIMD"]
},
{

1
src/VulkanRenderer Submodule

@ -0,0 +1 @@
Subproject commit b6a93e91777f73445e50796324bd0737b0f3921f

View File

@ -1,825 +0,0 @@
import util;
static immutable FontAtlas FONT_ATLAS = {
type: AtlasType.SoftMask,
size: 58.531250,
width: 256,
height: 256,
y_origin: YOrigin.Bottom,
em_size: 1.000000,
line_height: 1.408000,
ascender: 1.105000,
descender: -0.303000,
underline_y: -0.100000,
underline_thickness: 0.050000,
glyphs: [
{
ch: ' ',
advance: 0.207000,
},
{
ch: ',',
advance: 0.216000,
plane_left: 0.033160,
plane_bottom: -0.179391,
plane_right: 0.169840,
plane_top: 0.145222,
atlas_left: 247.500000,
atlas_bottom: 19.500000,
atlas_right: 255.500000,
atlas_top: 0.500000,
},
{
ch: '-',
advance: 0.373000,
plane_left: 0.049821,
plane_bottom: 0.230646,
plane_right: 0.323179,
plane_top: 0.350240,
atlas_left: 40.500000,
atlas_bottom: 51.500000,
atlas_right: 56.500000,
atlas_top: 44.500000,
},
{
ch: '.',
advance: 0.216000,
plane_left: 0.048203,
plane_bottom: -0.008542,
plane_right: 0.167797,
plane_top: 0.145222,
atlas_left: 247.500000,
atlas_bottom: 28.500000,
atlas_right: 254.500000,
atlas_top: 19.500000,
},
{
ch: '0',
advance: 0.467000,
plane_left: 0.019939,
plane_bottom: -0.025627,
plane_right: 0.447061,
plane_top: 0.709023,
atlas_left: 149.500000,
atlas_bottom: 43.500000,
atlas_right: 174.500000,
atlas_top: 0.500000,
},
{
ch: '1',
advance: 0.282000,
plane_left: 0.003406,
plane_bottom: -0.008542,
plane_right: 0.242594,
plane_top: 0.691938,
atlas_left: 98.500000,
atlas_bottom: 220.500000,
atlas_right: 112.500000,
atlas_top: 179.500000,
},
{
ch: '2',
advance: 0.439000,
plane_left: 0.014481,
plane_bottom: -0.008542,
plane_right: 0.424519,
plane_top: 0.709023,
atlas_left: 0.500000,
atlas_bottom: 137.500000,
atlas_right: 24.500000,
atlas_top: 95.500000,
},
{
ch: '3',
advance: 0.456000,
plane_left: 0.009939,
plane_bottom: -0.025627,
plane_right: 0.437061,
plane_top: 0.709023,
atlas_left: 174.500000,
atlas_bottom: 43.500000,
atlas_right: 199.500000,
atlas_top: 0.500000,
},
{
ch: '4',
advance: 0.466000,
plane_left: 0.011396,
plane_bottom: -0.008542,
plane_right: 0.455604,
plane_top: 0.691938,
atlas_left: 112.500000,
atlas_bottom: 220.500000,
atlas_right: 138.500000,
atlas_top: 179.500000,
},
{
ch: '5',
advance: 0.454000,
plane_left: 0.015439,
plane_bottom: -0.025627,
plane_right: 0.442561,
plane_top: 0.691938,
atlas_left: 24.500000,
atlas_bottom: 137.500000,
atlas_right: 49.500000,
atlas_top: 95.500000,
},
{
ch: '6',
advance: 0.456000,
plane_left: 0.017939,
plane_bottom: -0.025627,
plane_right: 0.445061,
plane_top: 0.709023,
atlas_left: 199.500000,
atlas_bottom: 43.500000,
atlas_right: 224.500000,
atlas_top: 0.500000,
},
{
ch: '7',
advance: 0.386000,
plane_left: 0.004066,
plane_bottom: -0.008542,
plane_right: 0.379934,
plane_top: 0.691938,
atlas_left: 138.500000,
atlas_bottom: 220.500000,
atlas_right: 160.500000,
atlas_top: 179.500000,
},
{
ch: '8',
advance: 0.464000,
plane_left: 0.018439,
plane_bottom: -0.025627,
plane_right: 0.445561,
plane_top: 0.709023,
atlas_left: 23.500000,
atlas_bottom: 95.500000,
atlas_right: 48.500000,
atlas_top: 52.500000,
},
{
ch: '9',
advance: 0.456000,
plane_left: 0.010939,
plane_bottom: -0.025627,
plane_right: 0.438061,
plane_top: 0.709023,
atlas_left: 48.500000,
atlas_bottom: 95.500000,
atlas_right: 73.500000,
atlas_top: 52.500000,
},
{
ch: ':',
advance: 0.216000,
plane_left: 0.048203,
plane_bottom: -0.008542,
plane_right: 0.167797,
plane_top: 0.521089,
atlas_left: 137.500000,
atlas_bottom: 252.500000,
atlas_right: 144.500000,
atlas_top: 221.500000,
},
{
ch: ';',
advance: 0.216000,
plane_left: 0.033160,
plane_bottom: -0.179391,
plane_right: 0.169840,
plane_top: 0.521089,
atlas_left: 243.500000,
atlas_bottom: 136.500000,
atlas_right: 251.500000,
atlas_top: 95.500000,
},
{
ch: 'A',
advance: 0.535000,
plane_left: 0.011227,
plane_bottom: -0.008542,
plane_right: 0.523773,
plane_top: 0.709023,
atlas_left: 76.500000,
atlas_bottom: 179.500000,
atlas_right: 106.500000,
atlas_top: 137.500000,
},
{
ch: 'B',
advance: 0.495000,
plane_left: 0.047439,
plane_bottom: -0.008542,
plane_right: 0.474561,
plane_top: 0.709023,
atlas_left: 215.500000,
atlas_bottom: 179.500000,
atlas_right: 240.500000,
atlas_top: 137.500000,
},
{
ch: 'C',
advance: 0.508000,
plane_left: 0.030354,
plane_bottom: -0.025627,
plane_right: 0.491646,
plane_top: 0.726108,
atlas_left: 40.500000,
atlas_bottom: 44.500000,
atlas_right: 67.500000,
atlas_top: 0.500000,
},
{
ch: 'D',
advance: 0.535000,
plane_left: 0.046854,
plane_bottom: -0.008542,
plane_right: 0.508146,
plane_top: 0.709023,
atlas_left: 26.500000,
atlas_bottom: 221.500000,
atlas_right: 53.500000,
atlas_top: 179.500000,
},
{
ch: 'E',
advance: 0.454000,
plane_left: 0.047024,
plane_bottom: -0.008542,
plane_right: 0.439976,
plane_top: 0.709023,
atlas_left: 75.500000,
atlas_bottom: 221.500000,
atlas_right: 98.500000,
atlas_top: 179.500000,
},
{
ch: 'F',
advance: 0.431000,
plane_left: 0.044066,
plane_bottom: -0.008542,
plane_right: 0.419934,
plane_top: 0.709023,
atlas_left: 53.500000,
atlas_bottom: 221.500000,
atlas_right: 75.500000,
atlas_top: 179.500000,
},
{
ch: 'G',
advance: 0.535000,
plane_left: 0.025312,
plane_bottom: -0.025627,
plane_right: 0.503688,
plane_top: 0.726108,
atlas_left: 67.500000,
atlas_bottom: 44.500000,
atlas_right: 95.500000,
atlas_top: 0.500000,
},
{
ch: 'H',
advance: 0.541000,
plane_left: 0.048896,
plane_bottom: -0.008542,
plane_right: 0.493104,
plane_top: 0.709023,
atlas_left: 0.500000,
atlas_bottom: 221.500000,
atlas_right: 26.500000,
atlas_top: 179.500000,
},
{
ch: 'I',
advance: 0.211000,
plane_left: 0.045703,
plane_bottom: -0.008542,
plane_right: 0.165297,
plane_top: 0.709023,
atlas_left: 236.500000,
atlas_bottom: 137.500000,
atlas_right: 243.500000,
atlas_top: 95.500000,
},
{
ch: 'J',
advance: 0.438000,
plane_left: 0.007024,
plane_bottom: -0.025627,
plane_right: 0.399976,
plane_top: 0.709023,
atlas_left: 73.500000,
atlas_bottom: 95.500000,
atlas_right: 96.500000,
atlas_top: 52.500000,
},
{
ch: 'K',
advance: 0.507000,
plane_left: 0.051396,
plane_bottom: -0.008542,
plane_right: 0.495604,
plane_top: 0.709023,
atlas_left: 189.500000,
atlas_bottom: 179.500000,
atlas_right: 215.500000,
atlas_top: 137.500000,
},
{
ch: 'L',
advance: 0.430000,
plane_left: 0.047566,
plane_bottom: -0.008542,
plane_right: 0.423434,
plane_top: 0.709023,
atlas_left: 167.500000,
atlas_bottom: 179.500000,
atlas_right: 189.500000,
atlas_top: 137.500000,
},
{
ch: 'M',
advance: 0.682000,
plane_left: 0.050557,
plane_bottom: -0.008542,
plane_right: 0.631443,
plane_top: 0.709023,
atlas_left: 133.500000,
atlas_bottom: 179.500000,
atlas_right: 167.500000,
atlas_top: 137.500000,
},
{
ch: 'N',
advance: 0.560000,
plane_left: 0.048854,
plane_bottom: -0.008542,
plane_right: 0.510146,
plane_top: 0.709023,
atlas_left: 106.500000,
atlas_bottom: 179.500000,
atlas_right: 133.500000,
atlas_top: 137.500000,
},
{
ch: 'O',
advance: 0.535000,
plane_left: 0.028312,
plane_bottom: -0.025627,
plane_right: 0.506688,
plane_top: 0.726108,
atlas_left: 95.500000,
atlas_bottom: 44.500000,
atlas_right: 123.500000,
atlas_top: 0.500000,
},
{
ch: 'P',
advance: 0.475000,
plane_left: 0.047481,
plane_bottom: -0.008542,
plane_right: 0.457519,
plane_top: 0.709023,
atlas_left: 52.500000,
atlas_bottom: 179.500000,
atlas_right: 76.500000,
atlas_top: 137.500000,
},
{
ch: 'Q',
advance: 0.535000,
plane_left: 0.028312,
plane_bottom: -0.145222,
plane_right: 0.506688,
plane_top: 0.726108,
atlas_left: 12.500000,
atlas_bottom: 51.500000,
atlas_right: 40.500000,
atlas_top: 0.500000,
},
{
ch: 'R',
advance: 0.500000,
plane_left: 0.046396,
plane_bottom: -0.008542,
plane_right: 0.490604,
plane_top: 0.709023,
atlas_left: 26.500000,
atlas_bottom: 179.500000,
atlas_right: 52.500000,
atlas_top: 137.500000,
},
{
ch: 'S',
advance: 0.475000,
plane_left: 0.012396,
plane_bottom: -0.025627,
plane_right: 0.456604,
plane_top: 0.726108,
atlas_left: 123.500000,
atlas_bottom: 44.500000,
atlas_right: 149.500000,
atlas_top: 0.500000,
},
{
ch: 'T',
advance: 0.466000,
plane_left: 0.010896,
plane_bottom: -0.008542,
plane_right: 0.455104,
plane_top: 0.709023,
atlas_left: 0.500000,
atlas_bottom: 179.500000,
atlas_right: 26.500000,
atlas_top: 137.500000,
},
{
ch: 'U',
advance: 0.528000,
plane_left: 0.043396,
plane_bottom: -0.025627,
plane_right: 0.487604,
plane_top: 0.709023,
atlas_left: 121.500000,
atlas_bottom: 95.500000,
atlas_right: 147.500000,
atlas_top: 52.500000,
},
{
ch: 'V',
advance: 0.522000,
plane_left: 0.004727,
plane_bottom: -0.008542,
plane_right: 0.517273,
plane_top: 0.709023,
atlas_left: 184.500000,
atlas_bottom: 137.500000,
atlas_right: 214.500000,
atlas_top: 95.500000,
},
{
ch: 'W',
advance: 0.768000,
plane_left: 0.008132,
plane_bottom: -0.008542,
plane_right: 0.759868,
plane_top: 0.709023,
atlas_left: 140.500000,
atlas_bottom: 137.500000,
atlas_right: 184.500000,
atlas_top: 95.500000,
},
{
ch: 'X',
advance: 0.513000,
plane_left: 0.008769,
plane_bottom: -0.008542,
plane_right: 0.504231,
plane_top: 0.709023,
atlas_left: 111.500000,
atlas_bottom: 137.500000,
atlas_right: 140.500000,
atlas_top: 95.500000,
},
{
ch: 'Y',
advance: 0.524000,
plane_left: 0.005727,
plane_bottom: -0.008542,
plane_right: 0.518273,
plane_top: 0.709023,
atlas_left: 81.500000,
atlas_bottom: 137.500000,
atlas_right: 111.500000,
atlas_top: 95.500000,
},
{
ch: 'Z',
advance: 0.452000,
plane_left: 0.011439,
plane_bottom: -0.008542,
plane_right: 0.438561,
plane_top: 0.709023,
atlas_left: 56.500000,
atlas_bottom: 137.500000,
atlas_right: 81.500000,
atlas_top: 95.500000,
},
{
ch: 'a',
advance: 0.427000,
plane_left: 0.009024,
plane_bottom: -0.025627,
plane_right: 0.401976,
plane_top: 0.521089,
atlas_left: 114.500000,
atlas_bottom: 253.500000,
atlas_right: 137.500000,
atlas_top: 221.500000,
},
{
ch: 'b',
advance: 0.457000,
plane_left: 0.043024,
plane_bottom: -0.025627,
plane_right: 0.435976,
plane_top: 0.709023,
atlas_left: 147.500000,
atlas_bottom: 95.500000,
atlas_right: 170.500000,
atlas_top: 52.500000,
},
{
ch: 'c',
advance: 0.423000,
plane_left: 0.018024,
plane_bottom: -0.025627,
plane_right: 0.410976,
plane_top: 0.521089,
atlas_left: 24.500000,
atlas_bottom: 253.500000,
atlas_right: 47.500000,
atlas_top: 221.500000,
},
{
ch: 'd',
advance: 0.456000,
plane_left: 0.021024,
plane_bottom: -0.025627,
plane_right: 0.413976,
plane_top: 0.709023,
atlas_left: 209.500000,
atlas_bottom: 95.500000,
atlas_right: 232.500000,
atlas_top: 52.500000,
},
{
ch: 'e',
advance: 0.430000,
plane_left: 0.021024,
plane_bottom: -0.025627,
plane_right: 0.413976,
plane_top: 0.521089,
atlas_left: 69.500000,
atlas_bottom: 253.500000,
atlas_right: 92.500000,
atlas_top: 221.500000,
},
{
ch: 'f',
advance: 0.283000,
plane_left: 0.009321,
plane_bottom: -0.008542,
plane_right: 0.282679,
plane_top: 0.726108,
atlas_left: 193.500000,
atlas_bottom: 95.500000,
atlas_right: 209.500000,
atlas_top: 52.500000,
},
{
ch: 'g',
advance: 0.448000,
plane_left: 0.020524,
plane_bottom: -0.213561,
plane_right: 0.413476,
plane_top: 0.521089,
atlas_left: 170.500000,
atlas_bottom: 95.500000,
atlas_right: 193.500000,
atlas_top: 52.500000,
},
{
ch: 'h',
advance: 0.449000,
plane_left: 0.039566,
plane_bottom: -0.008542,
plane_right: 0.415434,
plane_top: 0.709023,
atlas_left: 214.500000,
atlas_bottom: 137.500000,
atlas_right: 236.500000,
atlas_top: 95.500000,
},
{
ch: 'i',
advance: 0.184000,
plane_left: 0.032203,
plane_bottom: -0.008542,
plane_right: 0.151797,
plane_top: 0.674853,
atlas_left: 176.500000,
atlas_bottom: 219.500000,
atlas_right: 183.500000,
atlas_top: 179.500000,
},
{
ch: 'j',
advance: 0.187000,
plane_left: -0.051009,
plane_bottom: -0.213561,
plane_right: 0.154009,
plane_top: 0.674853,
atlas_left: 0.500000,
atlas_bottom: 52.500000,
atlas_right: 12.500000,
atlas_top: 0.500000,
},
{
ch: 'k',
advance: 0.434000,
plane_left: 0.042024,
plane_bottom: -0.008542,
plane_right: 0.434976,
plane_top: 0.709023,
atlas_left: 232.500000,
atlas_bottom: 94.500000,
atlas_right: 255.500000,
atlas_top: 52.500000,
},
{
ch: 'l',
advance: 0.190000,
plane_left: 0.035703,
plane_bottom: -0.008542,
plane_right: 0.155297,
plane_top: 0.709023,
atlas_left: 49.500000,
atlas_bottom: 137.500000,
atlas_right: 56.500000,
atlas_top: 95.500000,
},
{
ch: 'm',
advance: 0.690000,
plane_left: 0.039472,
plane_bottom: -0.008542,
plane_right: 0.654528,
plane_top: 0.521089,
atlas_left: 169.500000,
atlas_bottom: 252.500000,
atlas_right: 205.500000,
atlas_top: 221.500000,
},
{
ch: 'n',
advance: 0.446000,
plane_left: 0.036566,
plane_bottom: -0.008542,
plane_right: 0.412434,
plane_top: 0.521089,
atlas_left: 183.500000,
atlas_bottom: 210.500000,
atlas_right: 205.500000,
atlas_top: 179.500000,
},
{
ch: 'o',
advance: 0.442000,
plane_left: 0.015981,
plane_bottom: -0.025627,
plane_right: 0.426019,
plane_top: 0.521089,
atlas_left: 0.500000,
atlas_bottom: 253.500000,
atlas_right: 24.500000,
atlas_top: 221.500000,
},
{
ch: 'p',
advance: 0.457000,
plane_left: 0.043024,
plane_bottom: -0.213561,
plane_right: 0.435976,
plane_top: 0.521089,
atlas_left: 0.500000,
atlas_bottom: 95.500000,
atlas_right: 23.500000,
atlas_top: 52.500000,
},
{
ch: 'q',
advance: 0.455000,
plane_left: 0.021024,
plane_bottom: -0.213561,
plane_right: 0.413976,
plane_top: 0.521089,
atlas_left: 224.500000,
atlas_bottom: 43.500000,
atlas_right: 247.500000,
atlas_top: 0.500000,
},
{
ch: 'r',
advance: 0.298000,
plane_left: 0.038363,
plane_bottom: -0.008542,
plane_right: 0.294637,
plane_top: 0.521089,
atlas_left: 240.500000,
atlas_bottom: 168.500000,
atlas_right: 255.500000,
atlas_top: 137.500000,
},
{
ch: 's',
advance: 0.400000,
plane_left: 0.011066,
plane_bottom: -0.025627,
plane_right: 0.386934,
plane_top: 0.521089,
atlas_left: 47.500000,
atlas_bottom: 253.500000,
atlas_right: 69.500000,
atlas_top: 221.500000,
},
{
ch: 't',
advance: 0.293000,
plane_left: 0.004321,
plane_bottom: -0.025627,
plane_right: 0.277679,
plane_top: 0.657768,
atlas_left: 160.500000,
atlas_bottom: 219.500000,
atlas_right: 176.500000,
atlas_top: 179.500000,
},
{
ch: 'u',
advance: 0.440000,
plane_left: 0.029566,
plane_bottom: -0.025627,
plane_right: 0.405434,
plane_top: 0.521089,
atlas_left: 92.500000,
atlas_bottom: 253.500000,
atlas_right: 114.500000,
atlas_top: 221.500000,
},
{
ch: 'v',
advance: 0.419000,
plane_left: -0.004061,
plane_bottom: -0.008542,
plane_right: 0.423061,
plane_top: 0.521089,
atlas_left: 144.500000,
atlas_bottom: 252.500000,
atlas_right: 169.500000,
atlas_top: 221.500000,
},
{
ch: 'w',
advance: 0.658000,
plane_left: 0.004387,
plane_bottom: -0.008542,
plane_right: 0.653613,
plane_top: 0.521089,
atlas_left: 205.500000,
atlas_bottom: 210.500000,
atlas_right: 243.500000,
atlas_top: 179.500000,
},
{
ch: 'x',
advance: 0.412000,
plane_left: 0.000981,
plane_bottom: -0.008542,
plane_right: 0.411019,
plane_top: 0.521089,
atlas_left: 205.500000,
atlas_bottom: 252.500000,
atlas_right: 229.500000,
atlas_top: 221.500000,
},
{
ch: 'y',
advance: 0.421000,
plane_left: -0.002561,
plane_bottom: -0.213561,
plane_right: 0.424561,
plane_top: 0.521089,
atlas_left: 96.500000,
atlas_bottom: 95.500000,
atlas_right: 121.500000,
atlas_top: 52.500000,
},
{
ch: 'z',
advance: 0.383000,
plane_left: 0.002066,
plane_bottom: -0.008542,
plane_right: 0.377934,
plane_top: 0.521089,
atlas_left: 229.500000,
atlas_bottom: 252.500000,
atlas_right: 251.500000,
atlas_top: 221.500000,
},
],
};

View File

@ -10,6 +10,7 @@ import math;
import core.stdc.math : cosf, sinf;
import std.algorithm.sorting;
import fonts;
import main;
f32 g_DELTA;
@ -82,6 +83,12 @@ struct Game
UIPushConst ui_pc;
u8[] font_data;
FontAtlasBuf atlas_buf;
FontFace font;
Buffer temp_buffer;
Timer timer;
}
@ -98,8 +105,9 @@ InitGame(PlatformWindow* window)
UVec2 ext = GetExtent(&g.rd);
DescLayoutBinding[] layout_bindings = [
DescLayoutBinding[2] layout_bindings = [
{ binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
{ binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_ALL },
];
g.ui_desc_layout = CreateDescSetLayout(&g.rd, layout_bindings);
@ -109,17 +117,13 @@ InitGame(PlatformWindow* window)
u8[16*16*4] white_tex;
white_tex[] = u8.max;
u8[] atlas = LoadAssetData(&g.frame_arena, "textures/atlas.png");
int width, height, has_ch;
auto img = stbi_load_from_memory(atlas.ptr, cast(int)atlas.length, &width, &height, &has_ch, 4);
assert(width == FONT_ATLAS.width && height == FONT_ATLAS.height && has_ch == 1, "atlas height and width do not match");
u8[] img_slice = img[0 .. width * height * 4];
CreateImageView(&g.rd, &g.font_tex, FONT_ATLAS.width, FONT_ATLAS.height, 4, img_slice);
// TODO: fix buffer overflow between two textures
//CreateImageView(&g.rd, &g.default_tex, 16, 16, 4, white_tex);
WriteGUI(&g.rd, g.ui_desc_set, &g.font_tex);
Attribute[5] attributes = [
{ binding: 0, location: 0, format: FMT.RG_F32, offset: UIVertex.dst_start.offsetof },
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.dst_end.offsetof },
{ binding: 0, location: 2, format: FMT.RG_F32, offset: UIVertex.src_start.offsetof },
{ binding: 0, location: 3, format: FMT.RG_F32, offset: UIVertex.src_end.offsetof },
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
];
GfxPipelineInfo ui_info = {
vertex_shader: "shaders/gui.vert.spv",
@ -127,13 +131,7 @@ InitGame(PlatformWindow* window)
input_rate: IR.Instance,
input_rate_stride: UIVertex.sizeof,
layout: g.ui_layout,
vertex_attributes: [
{ binding: 0, location: 0, format: FMT.RG_F32, offset: UIVertex.dst_start.offsetof },
{ binding: 0, location: 1, format: FMT.RG_F32, offset: UIVertex.dst_end.offsetof },
{ binding: 0, location: 2, format: FMT.RG_F32, offset: UIVertex.src_start.offsetof },
{ binding: 0, location: 3, format: FMT.RG_F32, offset: UIVertex.src_end.offsetof },
{ binding: 0, location: 4, format: FMT.RGBA_F32, offset: UIVertex.col.offsetof },
],
vertex_attributes: attributes,
};
g.ui_pipeline = CreateGraphicsPipeline(&g.rd, &ui_info);
@ -144,7 +142,16 @@ InitGame(PlatformWindow* window)
g.ui_vertex_buf = GetUIVertexBuffer(&g.rd);
g.ui_index_buf = GetUIIndexBuffer(&g.rd);
WaitForTransfers(&g.rd);
u8[] font_data = LoadAssetData(&g.arena, "fonts/NuberNextCondensed-DemiBold.otf");
g.font = OpenFont(font_data);
g.atlas_buf = CreateAtlas(&g.arena, g.font, 32, 256);
CreateImageView(&g.rd, &g.font_tex, g.atlas_buf.atlas.width, g.atlas_buf.atlas.height, 4, g.atlas_buf.data);
CreateImageView(&g.rd, &g.default_tex, 16, 16, 4, white_tex);
CreateBuffer(&g.rd, &g.temp_buffer, BT.Uniform, f32.sizeof*2, false, false);
WriteGUI(&g.rd, g.ui_desc_set, &g.font_tex, &g.temp_buffer);
Reset(&g.frame_arena);
@ -176,8 +183,22 @@ Cycle(Game* g)
Reset(&g.frame_arena);
static bool alt = false;
if (alt)
{
f32[2] scale = [2.0, 2.0];
assert(Transfer(&g.rd, &g.temp_buffer, scale), "Cycle Transfer failed");
}
else
{
f32[2] scale = [1.0, 1.0];
assert(Transfer(&g.rd, &g.temp_buffer, scale), "Cycle Transfer failed");
}
alt = !alt;
DrawRect(g, 500.0, 500.0, 800.0, 800.0, Vec4(0.2, 0.3, 0.7, 1.0));
DrawText(g, 200.0, 200.0, FONT_ATLAS.size, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
DrawText(g, 200.0, 200.0, 16.0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
BeginFrame(&g.rd);
@ -323,19 +344,20 @@ void
DrawText(Game* g, f32 x, f32 y, f32 px, string str)
{
f32 x_pos = x;
f32 scale = px / g.atlas_buf.atlas.size;
foreach(ch; str)
{
foreach(glyph; FONT_ATLAS.glyphs)
foreach(glyph; g.atlas_buf.atlas.glyphs)
{
if (ch == glyph.ch)
{
UIVertex* v = g.ui_vertex_buf.ptr + g.ui_count;
f32 r = px * glyph.plane_right;
f32 l = px * glyph.plane_left;
f32 r = glyph.plane_right * scale;
f32 l = glyph.plane_left * scale;
f32 w = r - l;
f32 h = px * (glyph.plane_bottom - glyph.plane_top);
f32 y_pos = px * glyph.plane_bottom;
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
f32 y_pos = glyph.plane_top * scale;
v.dst_start.x = x_pos + l;
v.dst_start.y = y + h - y_pos;
@ -349,9 +371,11 @@ DrawText(Game* g, f32 x, f32 y, f32 px, string str)
v.col = Vec4(1.0, 1.0, 1.0, 1.0);
x_pos += px * glyph.advance;
x_pos += glyph.advance * scale;
AddUIIndices(g);
break;
}
}
}

View File

@ -1,4 +1,4 @@
public import includes;
import includes;
import std.stdio;
import aliases;
import core.memory;
@ -8,10 +8,7 @@ import util;
import core.simd;
import math;
import core.stdc.string : memcpy;
import font;
import alloc;
import assets;
import fonts;
// TODO:
// 1. Determine how to better handle inputs
@ -20,15 +17,11 @@ import assets;
void main(string[] argv)
{
InitFreeType();
PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
Game g = InitGame(&window);
Arena arena = CreateArena(MB(8));
InitFreeType();
u8[] font_data = LoadAssetData(&arena, "fonts/NuberNextCondensed-DemiBold.otf");
FontFace font = OpenFont(font_data);
FontAtlasBuf atlas = CreateAtlas(&arena, font, 32.0, 256);
while (true)
{
HandleEvents(&window);

View File

@ -5,6 +5,8 @@ import core.memory;
import core.thread.osthread;
import core.time;
@nogc:
const WINDOW_EDGE_BUFFER = 50;
enum Input
@ -40,6 +42,7 @@ alias KBI = Input;
version(linux)
{
import core.sys.posix.dlfcn;
import core.sys.posix.sys.mman;
struct InputEvent
{
@ -130,7 +133,7 @@ CreateWindow(string name, u16 width, u16 height)
XCB_EVENT_MASK_POINTER_MOTION |
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
i32[] val_win = [window.screen.black_pixel, event_mask];
i32[2] val_win = [window.screen.black_pixel, event_mask];
i32 val_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
window.window = xcb_generate_id(window.conn);
@ -599,6 +602,18 @@ case XK_g:
}
}
void*
MemAlloc(u64 size)
{
return mmap(null, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
}
void
MemFree(void* ptr, u64 size)
{
assert(munmap(ptr, size) == 0, "MemFree failure");
}
}
version(Windows)

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +0,0 @@
public import includes;
import platform;
import vulkan : Vulkan, VULKAN_LIBS;
// Global Functions
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = null;
PFN_vkCreateInstance vkCreateInstance = null;
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = null;
// Instance Functions
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = null;
PFN_vkCreateDevice vkCreateDevice = null;
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties = null;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = null;
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = null;
PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 = null;
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = null;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR = null;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = null;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = null;
PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties = null;
PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = null;
PFN_vkDestroyInstance vkDestroyInstance = null;
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = null;
debug
{
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = null;
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = null;
}
// Platform Functions
version(linux)
{
PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR = null;
};
version(Windows)
{
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = null;
};
version(AMD_GPU)
{
debug
{
PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD = null;
}
}
// Device Functions
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = null;
PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass = null;
PFN_vkCmdEndRenderPass vkCmdEndRenderPass = null;
PFN_vkCreateFramebuffer vkCreateFramebuffer = null;
PFN_vkDestroyFramebuffer vkDestroyFramebuffer = null;
PFN_vkCreateRenderPass vkCreateRenderPass = null;
PFN_vkDestroyRenderPass vkDestroyRenderPass = null;
PFN_vkCreateImage vkCreateImage = null;
PFN_vkCreateImageView vkCreateImageView = null;
PFN_vkCreateBufferView vkCreateBufferView = null;
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = null;
PFN_vkGetDeviceQueue vkGetDeviceQueue = null;
PFN_vkCreateSemaphore vkCreateSemaphore = null;
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = null;
PFN_vkCreateCommandPool vkCreateCommandPool = null;
PFN_vkCreateFence vkCreateFence = null;
PFN_vkCreateDescriptorPool vkCreateDescriptorPool = null;
PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout = null;
PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets = null;
PFN_vkCreatePipelineLayout vkCreatePipelineLayout = null;
PFN_vkResetDescriptorPool vkResetDescriptorPool = null;
PFN_vkCreateShaderModule vkCreateShaderModule = null;
PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines = null;
PFN_vkCreateComputePipelines vkCreateComputePipelines = null;
PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = null;
PFN_vkDestroyDevice vkDestroyDevice = null;
PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = null;
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = null;
PFN_vkQueueSubmit2 vkQueueSubmit2 = null;
PFN_vkDestroyImage vkDestroyImage = null;
PFN_vkCmdBlitImage vkCmdBlitImage = null;
PFN_vkDestroyImageView vkDestroyImageView = null;
PFN_vkDestroyCommandPool vkDestroyCommandPool = null;
PFN_vkDestroySemaphore vkDestroySemaphore = null;
PFN_vkDestroyFence vkDestroyFence = null;
PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = null;
PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = null;
PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2 = null;
PFN_vkDestroyPipeline vkDestroyPipeline = null;
PFN_vkWaitForFences vkWaitForFences = null;
PFN_vkBeginCommandBuffer vkBeginCommandBuffer = null;
PFN_vkEndCommandBuffer vkEndCommandBuffer = null;
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = null;
PFN_vkCmdBindPipeline vkCmdBindPipeline = null;
PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets = null;
PFN_vkCmdDispatch vkCmdDispatch = null;
PFN_vkCmdSetViewport vkCmdSetViewport = null;
PFN_vkCmdSetScissor vkCmdSetScissor = null;
PFN_vkCmdPushConstants vkCmdPushConstants = null;
PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer = null;
PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers = null;
PFN_vkCmdDrawIndexed vkCmdDrawIndexed = null;
PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage = null;
PFN_vkCmdCopyBuffer vkCmdCopyBuffer = null;
PFN_vkResetFences vkResetFences = null;
PFN_vkResetCommandBuffer vkResetCommandBuffer = null;
PFN_vkFreeCommandBuffers vkFreeCommandBuffers = null;
PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout = null;
PFN_vkDestroyShaderModule vkDestroyShaderModule = null;
PFN_vkQueuePresentKHR vkQueuePresentKHR = null;
PFN_vkCmdDraw vkCmdDraw = null;
PFN_vkDeviceWaitIdle vkDeviceWaitIdle = null;
PFN_vkCmdClearColorImage vkCmdClearColorImage = null;
PFN_vkCreateSampler vkCreateSampler = null;
PFN_vkDestroySampler vkDestroySampler = null;
PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress = null;
PFN_vkWaitSemaphores vkWaitSemaphores = null;
PFN_vkQueueWaitIdle vkQueueWaitIdle = null;
bool
LoadGlobalFunctions()
{
Library lib;
Function fn;
foreach(name; VULKAN_LIBS)
{
lib = LoadLibrary(name);
if (lib.ptr)
{
fn = LoadFunction(lib, "vkGetInstanceProcAddr");
vkGetInstanceProcAddr = cast(PFN_vkGetInstanceProcAddr)fn.ptr;
}
}
if (fn.ptr)
{
vkGetInstanceProcAddr = cast(PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr(null, "vkGetInstanceProcAddr");
assert(vkGetInstanceProcAddr != null, "LoadGlobalFunctions failure: Unable to load vkGetInstanceProcAddr");
vkCreateInstance = cast(PFN_vkCreateInstance)vkGetInstanceProcAddr(null, "vkCreateInstance");
assert(vkCreateInstance != null, "LoadGlobalFunctions failure: Unable to load VkCreateInstance");
vkEnumerateInstanceLayerProperties = cast(PFN_vkEnumerateInstanceLayerProperties)vkGetInstanceProcAddr(null, "vkEnumerateInstanceLayerProperties");
assert(vkEnumerateInstanceLayerProperties != null, "LoadGlobalFunctions failure: Unable to load vkEnumerateInstanceLayerProperties");
}
return fn.ptr != null;
}
void
LoadDeviceFunctions(Vulkan* vk)
{
vkCreateSwapchainKHR = cast(PFN_vkCreateSwapchainKHR)vkGetDeviceProcAddr(vk.device, "vkCreateSwapchainKHR");
vkCmdBeginRenderPass = cast(PFN_vkCmdBeginRenderPass)vkGetDeviceProcAddr(vk.device, "vkCmdBeginRenderPass");
vkCmdEndRenderPass = cast(PFN_vkCmdEndRenderPass)vkGetDeviceProcAddr(vk.device, "vkCmdEndRenderPass");
vkCreateFramebuffer = cast(PFN_vkCreateFramebuffer)vkGetDeviceProcAddr(vk.device, "vkCreateFramebuffer");
vkDestroyFramebuffer = cast(PFN_vkDestroyFramebuffer)vkGetDeviceProcAddr(vk.device, "vkDestroyFramebuffer");
vkCreateRenderPass = cast(PFN_vkCreateRenderPass)vkGetDeviceProcAddr(vk.device, "vkCreateRenderPass");
vkDestroyRenderPass = cast(PFN_vkDestroyRenderPass)vkGetDeviceProcAddr(vk.device, "vkDestroyRenderPass");
vkCreateImage = cast(PFN_vkCreateImage)vkGetDeviceProcAddr(vk.device, "vkCreateImage");
vkCreateImageView = cast(PFN_vkCreateImageView)vkGetDeviceProcAddr(vk.device, "vkCreateImageView");
vkQueueSubmit2 = cast(PFN_vkQueueSubmit2KHR)vkGetDeviceProcAddr(vk.device, "vkQueueSubmit2KHR");
vkCreateBufferView = cast(PFN_vkCreateBufferView)vkGetDeviceProcAddr(vk.device, "vkCreateBufferView");
vkGetSwapchainImagesKHR = cast(PFN_vkGetSwapchainImagesKHR)vkGetDeviceProcAddr(vk.device, "vkGetSwapchainImagesKHR");
vkGetDeviceQueue = cast(PFN_vkGetDeviceQueue)vkGetDeviceProcAddr(vk.device, "vkGetDeviceQueue");
vkCreateSemaphore = cast(PFN_vkCreateSemaphore)vkGetDeviceProcAddr(vk.device, "vkCreateSemaphore");
vkAllocateCommandBuffers = cast(PFN_vkAllocateCommandBuffers)vkGetDeviceProcAddr(vk.device, "vkAllocateCommandBuffers");
vkCreateCommandPool = cast(PFN_vkCreateCommandPool)vkGetDeviceProcAddr(vk.device, "vkCreateCommandPool");
vkCmdPipelineBarrier = cast(PFN_vkCmdPipelineBarrier)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier");
vkCmdPipelineBarrier2 = cast(PFN_vkCmdPipelineBarrier2KHR)vkGetDeviceProcAddr(vk.device, "vkCmdPipelineBarrier2KHR");
vkCreateFence = cast(PFN_vkCreateFence)vkGetDeviceProcAddr(vk.device, "vkCreateFence");
vkCreateDescriptorPool = cast(PFN_vkCreateDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorPool");
vkCreateDescriptorSetLayout = cast(PFN_vkCreateDescriptorSetLayout)vkGetDeviceProcAddr(vk.device, "vkCreateDescriptorSetLayout");
vkAllocateDescriptorSets = cast(PFN_vkAllocateDescriptorSets)vkGetDeviceProcAddr(vk.device, "vkAllocateDescriptorSets");
vkCreatePipelineLayout = cast(PFN_vkCreatePipelineLayout)vkGetDeviceProcAddr(vk.device, "vkCreatePipelineLayout");
vkResetDescriptorPool = cast(PFN_vkResetDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkResetDescriptorPool");
vkCreateShaderModule = cast(PFN_vkCreateShaderModule)vkGetDeviceProcAddr(vk.device, "vkCreateShaderModule");
vkCreateGraphicsPipelines = cast(PFN_vkCreateGraphicsPipelines)vkGetDeviceProcAddr(vk.device, "vkCreateGraphicsPipelines");
vkCreateComputePipelines = cast(PFN_vkCreateComputePipelines)vkGetDeviceProcAddr(vk.device, "vkCreateComputePipelines");
vkUpdateDescriptorSets = cast(PFN_vkUpdateDescriptorSets)vkGetDeviceProcAddr(vk.device, "vkUpdateDescriptorSets");
vkDestroyDevice = cast(PFN_vkDestroyDevice)vkGetDeviceProcAddr(vk.device, "vkDestroyDevice");
vkDestroyDescriptorPool = cast(PFN_vkDestroyDescriptorPool)vkGetDeviceProcAddr(vk.device, "vkDestroyDescriptorPool");
vkDestroySwapchainKHR = cast(PFN_vkDestroySwapchainKHR)vkGetDeviceProcAddr(vk.device, "vkDestroySwapchainKHR");
vkDestroyImage = cast(PFN_vkDestroyImage)vkGetDeviceProcAddr(vk.device, "vkDestroyImage");
vkDestroyImageView = cast(PFN_vkDestroyImageView)vkGetDeviceProcAddr(vk.device, "vkDestroyImageView");
vkDestroyCommandPool = cast(PFN_vkDestroyCommandPool)vkGetDeviceProcAddr(vk.device, "vkDestroyCommandPool");
vkDestroySemaphore = cast(PFN_vkDestroySemaphore)vkGetDeviceProcAddr(vk.device, "vkDestroySemaphore");
vkDestroyFence = cast(PFN_vkDestroyFence)vkGetDeviceProcAddr(vk.device, "vkDestroyFence");
vkDestroyPipelineLayout = cast(PFN_vkDestroyPipelineLayout)vkGetDeviceProcAddr(vk.device, "vkDestroyPipelineLayout");
vkDestroyPipeline = cast(PFN_vkDestroyPipeline)vkGetDeviceProcAddr(vk.device, "vkDestroyPipeline");
vkWaitForFences = cast(PFN_vkWaitForFences)vkGetDeviceProcAddr(vk.device, "vkWaitForFences");
vkBeginCommandBuffer = cast(PFN_vkBeginCommandBuffer)vkGetDeviceProcAddr(vk.device, "vkBeginCommandBuffer");
vkEndCommandBuffer = cast(PFN_vkEndCommandBuffer)vkGetDeviceProcAddr(vk.device, "vkEndCommandBuffer");
vkAcquireNextImageKHR = cast(PFN_vkAcquireNextImageKHR)vkGetDeviceProcAddr(vk.device, "vkAcquireNextImageKHR");
vkCmdBindPipeline = cast(PFN_vkCmdBindPipeline)vkGetDeviceProcAddr(vk.device, "vkCmdBindPipeline");
vkCmdBindDescriptorSets = cast(PFN_vkCmdBindDescriptorSets)vkGetDeviceProcAddr(vk.device, "vkCmdBindDescriptorSets");
vkCmdDispatch = cast(PFN_vkCmdDispatch)vkGetDeviceProcAddr(vk.device, "vkCmdDispatch");
vkCmdSetViewport = cast(PFN_vkCmdSetViewport)vkGetDeviceProcAddr(vk.device, "vkCmdSetViewport");
vkCmdSetScissor = cast(PFN_vkCmdSetScissor)vkGetDeviceProcAddr(vk.device, "vkCmdSetScissor");
vkCmdPushConstants = cast(PFN_vkCmdPushConstants)vkGetDeviceProcAddr(vk.device, "vkCmdPushConstants");
vkCmdBindIndexBuffer = cast(PFN_vkCmdBindIndexBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdBindIndexBuffer");
vkCmdBindVertexBuffers = cast(PFN_vkCmdBindVertexBuffers)vkGetDeviceProcAddr(vk.device, "vkCmdBindVertexBuffers");
vkCmdDrawIndexed = cast(PFN_vkCmdDrawIndexed)vkGetDeviceProcAddr(vk.device, "vkCmdDrawIndexed");
vkCmdBlitImage = cast(PFN_vkCmdBlitImage)vkGetDeviceProcAddr(vk.device, "vkCmdBlitImage");
vkCmdCopyBufferToImage = cast(PFN_vkCmdCopyBufferToImage)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBufferToImage");
vkCmdCopyBuffer = cast(PFN_vkCmdCopyBuffer)vkGetDeviceProcAddr(vk.device, "vkCmdCopyBuffer");
vkResetFences = cast(PFN_vkResetFences)vkGetDeviceProcAddr(vk.device, "vkResetFences");
vkResetCommandBuffer = cast(PFN_vkResetCommandBuffer)vkGetDeviceProcAddr(vk.device, "vkResetCommandBuffer");
vkFreeCommandBuffers = cast(PFN_vkFreeCommandBuffers)vkGetDeviceProcAddr(vk.device, "vkFreeCommandBuffers");
vkDestroyDescriptorSetLayout = cast(PFN_vkDestroyDescriptorSetLayout)vkGetDeviceProcAddr(vk.device, "vkDestroyDescriptorSetLayout");
vkDestroyShaderModule = cast(PFN_vkDestroyShaderModule)vkGetDeviceProcAddr(vk.device, "vkDestroyShaderModule");
vkQueuePresentKHR = cast(PFN_vkQueuePresentKHR)vkGetDeviceProcAddr(vk.device, "vkQueuePresentKHR");
vkCmdDraw = cast(PFN_vkCmdDraw)vkGetDeviceProcAddr(vk.device, "vkCmdDraw");
vkDeviceWaitIdle = cast(PFN_vkDeviceWaitIdle)vkGetDeviceProcAddr(vk.device, "vkDeviceWaitIdle");
vkCmdClearColorImage = cast(PFN_vkCmdClearColorImage)vkGetDeviceProcAddr(vk.device, "vkCmdClearColorImage");
vkCreateSampler = cast(PFN_vkCreateSampler)vkGetDeviceProcAddr(vk.device, "vkCreateSampler");
vkDestroySampler = cast(PFN_vkDestroySampler)vkGetDeviceProcAddr(vk.device, "vkDestroySampler");
vkGetBufferDeviceAddress = cast(PFN_vkGetBufferDeviceAddress)vkGetDeviceProcAddr(vk.device, "vkGetBufferDeviceAddress");
vkWaitSemaphores = cast(PFN_vkWaitSemaphores)vkGetDeviceProcAddr(vk.device, "vkWaitSemaphores");
vkQueueWaitIdle = cast(PFN_vkQueueWaitIdle)vkGetDeviceProcAddr(vk.device, "vkQueueWaitIdle");
version(AMD_GPU)
{
debug
{
vkGetShaderInfoAMD = cast(PFN_vkGetShaderInfoAMD)vkGetDeviceProcAddr(vk.device, "vkGetShaderInfoAMD");
assert(vkGetShaderInfoAMD != null, "vkGetShaderInfoAMD pointer is null");
}
}
assert(vkCreateSwapchainKHR != null, "LoadDeviceFunctions failure: function pointer is null");
}
void
LoadInstanceFunctions(Vulkan* vk)
{
vkEnumeratePhysicalDevices = cast(PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr(vk.instance, "vkEnumeratePhysicalDevices");
vkDestroySurfaceKHR = cast(PFN_vkDestroySurfaceKHR)vkGetInstanceProcAddr(vk.instance, "vkDestroySurfaceKHR");
vkDestroyInstance = cast(PFN_vkDestroyInstance)vkGetInstanceProcAddr(vk.instance, "vkDestroyInstance");
vkCreateDevice = cast(PFN_vkCreateDevice)vkGetInstanceProcAddr(vk.instance, "vkCreateDevice");
vkGetPhysicalDeviceQueueFamilyProperties = cast(PFN_vkGetPhysicalDeviceQueueFamilyProperties)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceQueueFamilyProperties");
vkGetPhysicalDeviceSurfaceSupportKHR = cast(PFN_vkGetPhysicalDeviceSurfaceSupportKHR)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
vkGetPhysicalDeviceProperties = cast(PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceProperties");
vkGetPhysicalDeviceFeatures2 = cast(PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceFeatures2");
vkEnumerateDeviceExtensionProperties = cast(PFN_vkEnumerateDeviceExtensionProperties)vkGetInstanceProcAddr(vk.instance, "vkEnumerateDeviceExtensionProperties");
vkGetPhysicalDeviceSurfacePresentModesKHR = cast(PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
vkGetPhysicalDeviceSurfaceFormatsKHR = cast(PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = cast(PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
vkGetPhysicalDeviceImageFormatProperties = cast(PFN_vkGetPhysicalDeviceImageFormatProperties)vkGetInstanceProcAddr(vk.instance, "vkGetPhysicalDeviceImageFormatProperties");
vkGetDeviceProcAddr = cast(PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(vk.instance, "vkGetDeviceProcAddr");
version(linux)
{
vkCreateXcbSurfaceKHR = cast(PFN_vkCreateXcbSurfaceKHR)vkGetInstanceProcAddr(vk.instance, "vkCreateXcbSurfaceKHR");
}
version(Windows)
{
vkCreateWin32SurfaceKHR = cast(PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(vk.instance, "vkCreateWin32SurfaceKHR");
}
debug
{
vkCreateDebugUtilsMessengerEXT = cast(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(vk.instance, "vkCreateDebugUtilsMessengerEXT");
vkDestroyDebugUtilsMessengerEXT = cast(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(vk.instance, "vkDestroyDebugUtilsMessengerEXT");
}
assert(vkEnumeratePhysicalDevices != null, "LoadInstanceFunctions failure: failed to load function");
}

View File

@ -1,166 +0,0 @@
public import includes;
import std.stdio;
import vulkan : Vulkan;
import std.conv;
import std.string;
import core.stdc.string : strlen, strcmp;
extern(System) VkBool32
DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
VkDebugUtilsMessageTypeFlagsEXT message_type,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
void* user_data
)
{
string ms, mt;
const(char)[] msg = callback_data.pMessage[0 .. strlen(callback_data.pMessage)];
bool debug_printf = strcmp(callback_data.pMessageIdName, "WARNING-DEBUG-PRINTF") == 0;
switch (message_severity) {
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
ms = "VERBOSE";
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
ms = "INFO";
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
ms = "WARNING";
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
ms = "ERROR";
break;
default:
ms = "UNKNOWN";
break;
}
switch (message_type) {
case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
mt = "General";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
mt = "Validation";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
mt = "Validation | General";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
mt = "Performance";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
mt = "General | Performance";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
mt = "Validation | Performance";
break;
case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
mt = "General | Validation | Performance";
break;
default:
mt = "Unknown";
break;
}
if (debug_printf)
{
writefln("SHADER PRINT: %s", msg);
}
else
{
writefln("[%s: %s]\n%r\n", ms, mt, msg);
}
return VK_FALSE;
}
string
VkResultStr(VkResult result)
{
switch (result)
{
case VK_SUCCESS:
return "VK_SUCCESS";
case VK_NOT_READY:
return "VK_NOT_READY";
case VK_TIMEOUT:
return "VK_TIMEOUT";
case VK_EVENT_SET:
return "VK_EVENT_SET";
case VK_EVENT_RESET:
return "VK_EVENT_RESET";
case VK_INCOMPLETE:
return "VK_INCOMPLETE";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_INITIALIZATION_FAILED:
return "VK_ERROR_INITIALIZATION_FAILED";
case VK_ERROR_DEVICE_LOST:
return "VK_ERROR_DEVICE_LOST";
case VK_ERROR_MEMORY_MAP_FAILED:
return "VK_ERROR_MEMORY_MAP_FAILED";
case VK_ERROR_LAYER_NOT_PRESENT:
return "VK_ERROR_LAYER_NOT_PRESENT";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "VK_ERROR_EXTENSION_NOT_PRESENT";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "VK_ERROR_FEATURE_NOT_PRESENT";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "VK_ERROR_INCOMPATIBLE_DRIVER";
case VK_ERROR_TOO_MANY_OBJECTS:
return "VK_ERROR_TOO_MANY_OBJECTS";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
case VK_ERROR_FRAGMENTED_POOL:
return "VK_ERROR_FRAGMENTED_POOL";
case VK_ERROR_UNKNOWN:
return "VK_ERROR_UNKNOWN";
case VK_ERROR_OUT_OF_POOL_MEMORY:
return "VK_ERROR_OUT_OF_POOL_MEMORY";
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
case VK_ERROR_FRAGMENTATION:
return "VK_ERROR_FRAGMENTATION";
case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS:
return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
case VK_PIPELINE_COMPILE_REQUIRED:
return "VK_PIPELINE_COMPILE_REQUIRED";
case VK_ERROR_SURFACE_LOST_KHR:
return "VK_ERROR_SURFACE_LOST_KHR";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
case VK_SUBOPTIMAL_KHR:
return "VK_SUBOPTIMAL_KHR";
case VK_ERROR_OUT_OF_DATE_KHR:
return "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "VK_ERROR_VALIDATION_FAILED_EXT";
case VK_ERROR_INVALID_SHADER_NV:
return "VK_ERROR_INVALID_SHADER_NV";
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
case VK_ERROR_NOT_PERMITTED_KHR:
return "VK_ERROR_NOT_PERMITTED_KHR";
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
case VK_THREAD_IDLE_KHR:
return "VK_THREAD_IDLE_KHR";
case VK_THREAD_DONE_KHR:
return "VK_THREAD_DONE_KHR";
case VK_OPERATION_DEFERRED_KHR:
return "VK_OPERATION_DEFERRED_KHR";
case VK_OPERATION_NOT_DEFERRED_KHR:
return "VK_OPERATION_NOT_DEFERRED_KHR";
case VK_ERROR_COMPRESSION_EXHAUSTED_EXT:
return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT";
case VK_RESULT_MAX_ENUM:
return "VK_RESULT_MAX_ENUM";
default:
return "UNKNOWN";
}
}

View File

@ -1,5 +1,9 @@
layout (set = 1, binding = 0) uniform texture2D SpriteAtlas;
layout (set = 1, binding = 1) uniform Scale {
vec2 factor;
} S;
layout (push_constant) uniform Constants {
vec2 res;
} PC;

View File

@ -41,17 +41,17 @@ void main()
vec2 src_pos = (Vertices[gl_VertexIndex] * src_half_size + src_center);
vec2 uvs[4] = vec2[4](
vec2(in_src_start.x, in_src_end.y),
vec2(in_src_start.x, in_src_start.y),
vec2(in_src_end.x, in_src_end.y),
vec2(in_src_end.x, in_src_start.y)
vec2(in_src_start.x, in_src_end.y),
vec2(in_src_end.x, in_src_start.y),
vec2(in_src_end.x, in_src_end.y)
);
FragData.color = in_col;
FragData.uv = uvs[gl_VertexIndex] / tex_size;
gl_Position = vec4(2 * dst_pos.x / PC.res.x - 1,
2 * dst_pos.y / PC.res.y - 1,
gl_Position = vec4((2 * dst_pos.x / PC.res.x - 1) * S.factor.x,
(2 * dst_pos.y / PC.res.y - 1) * S.factor.y,
0,
1);
}

View File

@ -3,6 +3,7 @@ import math;
import std.stdio;
import core.stdc.string : memset;
import core.memory;
import platform;
const DEFAULT_ALIGNMENT = (void *).sizeof * 2;
@ -13,6 +14,32 @@ struct Arena
u64 pos;
};
T*
MAlloc(T)()
{
void* mem = MemAlloc(T.sizeof);
return cast(T*)mem;
}
T[]
MAllocArray(T)(u64 count)
{
void* mem = MemAlloc(T.sizeof * count);
return cast(T*)(mem)[0 .. count];
}
void
MFree(T)(T* ptr)
{
MemFree(cast(void*)ptr, T.sizeof);
}
void
MFreeArray(T)(T[] slice)
{
MemFree(cast(void*)slice.ptr, cast(u64)slice.length);
}
T*
Alloc(T)()
{

View File

@ -3,6 +3,48 @@ import includes;
import util;
import alloc;
enum AtlasType
{
None = 0,
SoftMask,
}
enum YOrigin
{
None = 0,
Bottom,
}
struct FontAtlas
{
AtlasType type;
f32 size;
u32 width;
u32 height;
YOrigin y_origin;
f32 em_size;
f32 line_height;
f32 ascender;
f32 descender;
f32 underline_y;
f32 underline_thickness;
Glyph[] glyphs;
}
struct Glyph
{
dchar ch;
f32 advance;
f32 plane_left;
f32 plane_bottom;
f32 plane_right;
f32 plane_top;
f32 atlas_left;
f32 atlas_bottom;
f32 atlas_right;
f32 atlas_top;
}
FT_Library FT_LIB;
alias FontFace = FT_Face;
@ -18,6 +60,15 @@ InitFreeType()
FT_Init_FreeType(&FT_LIB);
}
void
CloseFreeType()
{
if (FT_LIB)
{
FT_Done_FreeType(FT_LIB);
}
}
FontFace
OpenFont(u8[] data)
{
@ -36,12 +87,17 @@ CloseFont(FontFace font)
}
FontAtlasBuf
CreateAtlas(Arena* arena, FontFace font, f32 size, u64 dimension)
CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
{
assert(dimension >= 128, "Dimension must be at least 128");
FontAtlasBuf atlas = {
data: AllocArray!(u8)(arena, dimension * dimension * 4),
atlas: {
size: size,
width: dimension,
height: dimension,
},
};
// TODO: proper packing algorithm
@ -88,11 +144,15 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u64 dimension)
current_h = 0;
count = 0;
u32 font_w = font.size.metrics.x_ppem;
u32 font_h = font.size.metrics.y_ppem;
char_code = FT_Get_First_Char(font, &index);
while (index != 0)
{
FT_Load_Char(font, char_code, cast(FT_Int32)FT_LOAD_RENDER);
FT_GlyphSlot glyph = font.glyph;
FT_Bitmap* bmp = &font.glyph.bitmap;
i32 top = font.glyph.bitmap_top;
i32 left = font.glyph.bitmap_left;
@ -103,29 +163,48 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u64 dimension)
max_w = 0;
}
i32 x, y;
foreach(r; 0 .. bmp.rows)
{
i32 y = cast(i32)(max_h + r);
y = cast(i32)(max_h + r);
foreach(c; 0 .. bmp.width)
{
i32 x = max_w + left + c;
x = max_w + c;
u64 offset = (y*dimension + x) * 4;
atlas.data[offset+0] = 255;
atlas.data[offset+1] = 255;
atlas.data[offset+2] = 255;
atlas.data[offset+3] = bmp.buffer[r*bmp.pitch + c];
atlas.data[offset+0] = bmp.buffer[r*bmp.pitch + c];
atlas.data[offset+1] = bmp.buffer[r*bmp.pitch + c];
atlas.data[offset+2] = bmp.buffer[r*bmp.pitch + c];
atlas.data[offset+3] = 255;
}
}
Glyph* g = atlas.atlas.glyphs.ptr + count;
g.ch = cast(dchar)char_code;
g.advance = cast(f32)(glyph.advance.x >> 6);
g.plane_left = cast(f32)left;
g.plane_right = g.plane_left + bmp.width;
g.plane_top = cast(f32)top;
g.plane_bottom = g.plane_top + bmp.rows;
g.atlas_top = max_h;
g.atlas_left = max_w;
g.atlas_bottom = max_h + bmp.rows;
g.atlas_right = max_w + bmp.width;
max_w += bmp.width;
current_h = bmp.rows > current_h ? bmp.rows : current_h;
char_code = FT_Get_Next_Char(font, char_code, &index);
count += 1;
}
}
return atlas;
}

View File

@ -1,3 +1,5 @@
#pragma attribute(push, nogc, nothrow)
#ifdef __linux__
# include <xcb/xcb.h>
# include <xcb/xfixes.h>

View File

@ -7,64 +7,39 @@ import alloc;
import core.simd;
import std.conv;
import std.string;
enum AtlasType
j
struct DynSlice(T)
{
None = 0,
SoftMask,
T[][] slices;
u32 length;
u32 capacity;
u32 grow_size;
}
enum YOrigin
DynSlice!(T)
CreateDynSlice(T)(u32 size)
{
None = 0,
Bottom,
DynSlice!(T) dslice = {
slices: MAllocArray!(T[])(size),
length: 0,
capacity: size,
grow_size: size,
};
dslice.slices[0] = MAllocArray!(T)(size);
return dslice;
}
struct FontAtlas
u32
Next(T)(DynSlice!(T)* slice)
{
AtlasType type;
f32 size;
u32 width;
u32 height;
YOrigin y_origin;
f32 em_size;
f32 line_height;
f32 ascender;
f32 descender;
f32 underline_y;
f32 underline_thickness;
Glyph[] glyphs;
}
if (slice.length < slice.capacity)
{
}
struct Glyph
{
dchar ch;
f32 advance;
f32 plane_left;
f32 plane_bottom;
f32 plane_right;
f32 plane_top;
f32 atlas_left;
f32 atlas_bottom;
f32 atlas_right;
f32 atlas_top;
}
struct TrackedSlice(T)
{
T[] slice;
u32 free_index;
}
alias TSlice = TrackedSlice;
TSlice!(T)
InitTrackedSlice(T)(u32 length)
{
TSlice!(T) tslice;
tslice.slice = AllocArray!(T[])(length);
return tslice;
return 0;
}
void