Adds example 49-hextile (#2922)

* First commit - tested with dx11 on windows

* Minor changes & adding some comments.

* Update hextile.cpp

* update some bin files

* rename texture

* minor comment update

* Added support to configure tile rate as well as tile rotation strength, update bin files & screenshot

* use texture from polyhaven, updated screenshot, updated bin files & minor changes to shader.

* missed pushing texture

* update license

* Update hextile.cpp

* Fix regular tiling

* use ktx with mipmaps

* minor change to ensure that regular tiling & hextile matches with default tile rate.

* minor c

Co-authored-by: Бранимир Караџић <branimirkaradzic@gmail.com>
This commit is contained in:
blackhole 2022-09-15 19:03:07 -07:00 committed by GitHub
parent a88c7629c3
commit a8a10b0b89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 637 additions and 18 deletions

View File

@ -689,3 +689,18 @@ Reference(s):
.. figure:: https://github.com/bkaradzic/bgfx/raw/master/examples/48-drawindirect/screenshot.png
:alt: example-48-drawindirect
`49-hextile <https://github.com/bkaradzic/bgfx/tree/master/examples/49-hextile>`__
---------------------------------------------------------------------------------------------
Realtime Hex-Tiling
Simple example of how to use Hex-tiling in real time, ported from https://github.com/mmikk/hextile-demo
Reference(s):
- `Hex-Tiling demo <https://github.com/mmikk/hextile-demo>`__.
- `Paper explaining concepts - <https://github.com/mmikk/mmikk.github.io/blob/master/papers3d/mm_hex_compressed.pdf>`__.
.. figure:: https://github.com/bkaradzic/bgfx/raw/master/examples/49-hextile/screenshot.png
:alt: example-49-hextile

View File

@ -126,3 +126,8 @@ Normal map texture (GFDL License)
- `Julian Herzog <https://julianherzog.com/>`__
- https://commons.wikimedia.org/wiki/File:Normal_map_example_with_scene_and_result.png
Hextile example-49 texture (CC0 License)
- `Rob Tuytel`__
- https://polyhaven.com/a/aerial_rocks_04

View File

@ -0,0 +1,226 @@
$input v_position, v_texcoord0
/*
* Copyright 2022 Preetish Kakkar. All rights reserved.
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
*/
/*
Most of the code is inspired/ported from https://github.com/mmikk/hextile-demo/blob/main/hextile-demo/shader_lighting.hlsl
The basic idea behind the algorithm is to use tiling & blending schema but instead of regular linear blending, the algorithm uses blending operator that prevents visual artifacts caused by linear blending
We partition the uv-space on a triangle grid and compute the local triangle and the barycentric coordinates inside the triangle. We use a hash function to associate a random offset with each vertex of the triangle
grid and use this random offset to fetch the example texture.
Finally, we blend the result using the barycentric coordinates as blending weights.
*/
#include "../common/common.sh"
#define M_PI 3.1415926535897932384626433832795
SAMPLER2D(s_trx_d, 0);
uniform vec4 u_params;
#ifndef fmod
#define fmod(x, y) (x - y * trunc(x / y))
#endif
#define moduleOper(a, b) a - (float(b) * floor(a/float(b)))
#define u_showWeights u_params.x
#define u_tileRate u_params.y
#define u_tileRotStrength u_params.z
#define u_useRegularTiling u_params.w
vec3 Gain3(vec3 x, float r)
{
// increase contrast when r>0.5 and
// reduce contrast if less
float k = log(1.0 - r) / log(0.5);
vec3 s = 2.0 * step(0.5, x);
vec3 m = 2.0 * (1.0 - s);
vec3 res = 0.5 * s + 0.25 * m * pow(max(vec3_splat(0.0), s + x * m), vec3_splat(k));
return res.xyz / (res.x + res.y + res.z);
}
mat2 LoadRot2x2(vec2 idx, float rotStrength)
{
float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + M_PI;
// remap to +/-pi
//angle = fmod(angle, 2.0*M_PI);
if (angle < 0.0) angle += 2.0 * M_PI;
if (angle > M_PI) angle -= 2.0 * M_PI;
angle *= rotStrength;
float cs = cos(angle);
float si = sin(angle);
return mat2(cs, -si, si, cs);
}
vec2 MakeCenST(vec2 Vertex)
{
mat2 invSkewMat = mat2(1.0, 0.5, 0.0, 1.0 / 1.15470054);
return mul(invSkewMat, Vertex) / (2.0 * sqrt(3.0));
}
vec3 ProduceHexWeights(vec3 W, vec2 vertex1, vec2 vertex2, vec2 vertex3)
{
vec3 res = vec3_splat(0.0);
float v1 = moduleOper(((vertex1.x - vertex1.y)), 3.0);
if (v1 < 0.0) v1 += 3.0;
float vh = v1 < 2.0 ? (v1 + 1.0) : 0.0;
float vl = v1 > 0.0 ? (v1 - 1.0) : 2.0;
float v2 = vertex1.x < vertex3.x ? vl : vh;
float v3 = vertex1.x < vertex3.x ? vh : vl;
res.x = v3 == 0.0 ? W.z : (v2 == 0.0 ? W.y : W.x);
res.y = v3 == 1.0 ? W.z : (v2 == 1.0 ? W.y : W.x);
res.z = v3 == 2.0 ? W.z : (v2 == 2.0 ? W.y : W.x);
return res;
}
vec2 hash(vec2 p)
{
vec2 r = mul(mat2(127.1, 311.7, 269.5, 183.3), p);
return fract(sin(r) * 43758.5453);
}
// Given a point in UV, compute local triangle barycentric coordinates and vertex IDs
void TriangleGrid(out float w1, out float w2, out float w3,
out vec2 vertex1, out vec2 vertex2, out vec2 vertex3,
vec2 uv)
{
// Scaling of the input
uv *= 2.0 * sqrt(3.0); // controls the size of the input with respect to the size of the tiles.
// Skew input space into simplex triangle grid
const mat2 gridToSkewedGrid =
mat2(1.0, -0.57735027, 0.0, 1.15470054);
vec2 skewedCoord = mul(gridToSkewedGrid, uv);
vec2 baseId = floor(skewedCoord);
vec3 temp = vec3(fract(skewedCoord), 0.0);
temp.z = 1.0 - temp.x - temp.y;
float s = step(0.0, -temp.z);
float s2 = 2.0 * s - 1.0;
w1 = -temp.z * s2;
w2 = s - temp.y * s2;
w3 = s - temp.x * s2;
vertex1 = baseId + vec2(s, s);
vertex2 = baseId + vec2(s, 1.0 - s);
vertex3 = baseId + vec2(1.0 - s, s);
}
void hex2colTex(out vec4 color, out vec3 weights, vec2 uv,
float rotStrength, float r)
{
// compute uv derivatives
vec2 dSTdx = dFdx(uv), dSTdy = dFdy(uv);
// Get triangle info
float w1, w2, w3;
vec2 vertex1, vertex2, vertex3;
TriangleGrid(w1, w2, w3, vertex1, vertex2, vertex3, uv);
mat2 rot1 = LoadRot2x2(vertex1, rotStrength);
mat2 rot2 = LoadRot2x2(vertex2, rotStrength);
mat2 rot3 = LoadRot2x2(vertex3, rotStrength);
vec2 cen1 = MakeCenST(vertex1);
vec2 cen2 = MakeCenST(vertex2);
vec2 cen3 = MakeCenST(vertex3);
// assign random offset to each triangle vertex
// this is used later to fetch from texture
vec2 uv1 = mul(uv - cen1, rot1) + cen1 + hash(vertex1);
vec2 uv2 = mul(uv - cen2, rot2) + cen2 + hash(vertex2);
vec2 uv3 = mul(uv - cen3, rot3) + cen3 + hash(vertex3);
// Fetch input
// We could simply use texture2D function, however, the sreen space derivatives could be broken
// since we are using random offsets, we use texture2DGrad to make sure that we pass correct derivatives explicitly.
vec4 c1 = texture2DGrad(s_trx_d, uv1,
mul(dSTdx, rot1), mul(dSTdy, rot1));
vec4 c2 = texture2DGrad(s_trx_d, uv2,
mul(dSTdx, rot2), mul(dSTdy, rot2));
vec4 c3 = texture2DGrad(s_trx_d, uv3,
mul(dSTdx, rot3), mul(dSTdy, rot3));
// use luminance as weight
vec3 Lw = vec3(0.299, 0.587, 0.114);
vec3 Dw = vec3(dot(c1.xyz, Lw), dot(c2.xyz, Lw), dot(c3.xyz, Lw));
Dw = mix(vec3_splat(1.0), Dw, 0.6); // 0.6 is fall off constant
vec3 W = Dw * pow(vec3(w1, w2, w3), vec3_splat(7.0)); // 7 is g_exp
W /= (W.x + W.y + W.z);
if (r != 0.5) W = Gain3(W, r);
// blend weights with color linearly
// histogram preserving blending will be better but requires precompution step to create histogram texture
color = W.x * c1 + W.y * c2 + W.z * c3;
weights = ProduceHexWeights(W.xyz, vertex1, vertex2, vertex3);
}
float GetTileRate()
{
return 0.05 * u_tileRate;
}
void FetchColorAndWeight(out vec3 color, out vec3 weights, vec2 uv)
{
vec4 col4;
hex2colTex(col4, weights, uv, u_tileRotStrength, 0.7);
color = col4.xyz;
}
void main()
{
if(u_useRegularTiling > 0.0)
{
gl_FragColor = vec4(texture2D(s_trx_d, v_texcoord0.xy));
}
else
{
// actual world space position
vec3 surfPosInWorld = v_position.xyz;
vec3 sp = GetTileRate() * surfPosInWorld;
vec2 uv0 = vec2(sp.x, sp.z);
vec3 color, weights;
FetchColorAndWeight(color, weights, uv0);
if (u_showWeights > 0.0)
{
gl_FragColor = vec4(weights, 1.0);
}
else
{
gl_FragColor = vec4(color, 1.0);
}
}
}

View File

@ -0,0 +1,327 @@
/*
* Copyright 2022-2022 Preetish Kakkar. All rights reserved.
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
*/
#include <bx/allocator.h>
#include <bx/debug.h>
#include <bx/math.h>
#include "common.h"
#include "bgfx_utils.h"
#include "imgui/imgui.h"
namespace
{
struct PosTextCoord0Vertex
{
float m_x;
float m_y;
float m_z;
float m_u;
float m_v;
static void init()
{
ms_layout
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.end();
}
static bgfx::VertexLayout ms_layout;
};
bgfx::VertexLayout PosTextCoord0Vertex::ms_layout;
static PosTextCoord0Vertex s_screenSpaceQuadVertices[] =
{
{-1.0f, 0.0f, -1.0f, 0.0, 0.0 },
{-1.0f, 0.0f, 1.0f, 0.0, 1.0 },
{ 1.0f, 0.0f, -1.0f, 1.0, 0.0 },
{ 1.0f, 0.0f, 1.0f, 1.0, 1.0 },
};
static const uint16_t s_screenSpaceQuadIndices[] =
{
2, 3, 1,
0, 2, 1,
};
struct HextileData
{
bool m_showWeights = false;
int m_tileRate = 10;
float m_tileRotationStrength = 0.0f;
bool m_useRegularTiling = false;
bool m_pauseAnimation;
};
class ExampleHextile : public entry::AppI
{
public:
ExampleHextile(const char* _name, const char* _description, const char* _url)
: entry::AppI(_name, _description, _url)
, m_width(0)
, m_height(0)
, m_debug(BGFX_DEBUG_NONE)
, m_reset()
{
}
void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
{
Args args(_argc, _argv);
m_width = _width;
m_height = _height;
m_debug = BGFX_DEBUG_NONE;
m_reset = BGFX_RESET_VSYNC;
bgfx::Init init;
init.type = args.m_type;
init.vendorId = args.m_pciId;
init.platformData.nwh = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
init.platformData.ndt = entry::getNativeDisplayHandle();
init.resolution.width = m_width;
init.resolution.height = m_height;
init.resolution.reset = m_reset;
bgfx::init(init);
// Enable m_debug text.
bgfx::setDebug(m_debug);
// Set view 0 clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff
, 1.0f
, 0
);
m_hexTileData.m_showWeights = false;
m_hexTileData.m_pauseAnimation = false;
// Create vertex stream declaration.
PosTextCoord0Vertex::init();
// Create static vertex buffer.
m_vbh = bgfx::createVertexBuffer(
// Static data can be passed with bgfx::makeRef
bgfx::makeRef(s_screenSpaceQuadVertices, sizeof(s_screenSpaceQuadVertices))
, PosTextCoord0Vertex::ms_layout
);
// Create static index buffer
m_ibh = bgfx::createIndexBuffer(
// Static data can be passed with bgfx::makeRef
bgfx::makeRef(s_screenSpaceQuadIndices, sizeof(s_screenSpaceQuadIndices))
);
// Create program from shaders.
m_hextileProgram = loadProgram("vs_hextile", "fs_hextile");
// load texture to hextile
m_tileTexture = loadTexture("textures/aerial_rocks_04_diff_2k.ktx");
// Imgui.
imguiCreate();
m_timeOffset = bx::getHPCounter();
s_tileSampler = bgfx::createUniform("s_trx_d", bgfx::UniformType::Sampler);
u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 3);
}
virtual int shutdown() override
{
// Cleanup.
imguiDestroy();
if (bgfx::isValid(m_ibh))
{
bgfx::destroy(m_ibh);
}
if (bgfx::isValid(m_vbh))
{
bgfx::destroy(m_vbh);
}
if (bgfx::isValid(m_tileTexture))
{
bgfx::destroy(m_tileTexture);
}
if (bgfx::isValid(s_tileSampler))
{
bgfx::destroy(s_tileSampler);
}
if (bgfx::isValid(u_params))
{
bgfx::destroy(u_params);
}
bgfx::destroy(m_hextileProgram);
/// When data is passed to bgfx via makeRef we need to make
/// sure library is done with it before freeing memory blocks.
bgfx::frame();
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}
bool update() override
{
if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
{
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
last = now;
const double freq = double(bx::getHPFrequency());
const float deltaTime = float(frameTime / freq);
imguiBeginFrame(m_mouseState.m_mx
, m_mouseState.m_my
, (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
| (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
, m_mouseState.m_mz
, uint16_t(m_width)
, uint16_t(m_height)
);
showExampleDialog(this);
ImGui::SetNextWindowPos(
ImVec2(m_width - m_width / 4.5f - 5.0f, 10.0f)
, ImGuiCond_FirstUseEver
);
ImGui::SetNextWindowSize(
ImVec2(m_width / 4.5f, m_height / 4.0f)
, ImGuiCond_FirstUseEver
);
ImGui::Begin("Settings"
, NULL
, 0
);
ImGui::Separator();
ImGui::Checkbox("Use Regular Tiling", &m_hexTileData.m_useRegularTiling);
ImGui::Checkbox("Show Weights", &m_hexTileData.m_showWeights);
ImGui::Checkbox("Pause Animation", &m_hexTileData.m_pauseAnimation);
ImGui::SliderInt("Tile Rate", &m_hexTileData.m_tileRate, 2, 25);
ImGui::SliderFloat("Tile Rotation", &m_hexTileData.m_tileRotationStrength, 0.0f, 20.0f);
ImGui::Separator();
ImGui::End();
imguiEndFrame();
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
if (!m_hexTileData.m_pauseAnimation)
{
m_eye.z = bx::abs(m_eye.z) + (deltaTime / 4.0f);
if (m_eye.z < 10.0f)
{
m_eye.z *= -1;
}
else
{
m_eye.z = -0.01f;
}
}
float viewMtx[16];
bx::mtxLookAt(viewMtx, m_eye, at);
float projMtx[16];
bx::mtxProj(projMtx, 30.0f, float(m_width) / float(m_height), 0.1f, 1000.0f, bgfx::getCaps()->homogeneousDepth);
bgfx::setViewTransform(0, viewMtx, projMtx);
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
float modelTransform[16];
bx::mtxSRT(modelTransform, 30.0f, 30.0f, 30.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
bgfx::setTransform(modelTransform);
bgfx::setVertexBuffer(0, m_vbh);
bgfx::setIndexBuffer(m_ibh);
bgfx::setTexture(0, s_tileSampler, m_tileTexture);
const float data[4] = { float(m_hexTileData.m_showWeights), float(m_hexTileData.m_tileRate),
float(m_hexTileData.m_tileRotationStrength), float(m_hexTileData.m_useRegularTiling) };
bgfx::setUniform(u_params, data);
bgfx::setState(0
| BGFX_STATE_WRITE_RGB
| BGFX_STATE_WRITE_A
| BGFX_STATE_WRITE_Z
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_MSAA
);
bgfx::submit(0, m_hextileProgram);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
return true;
}
return false;
}
bgfx::VertexBufferHandle m_vbh;
bgfx::IndexBufferHandle m_ibh;
bgfx::ProgramHandle m_hextileProgram;
bgfx::UniformHandle s_tileSampler;
bgfx::TextureHandle m_tileTexture;
uint32_t m_width;
uint32_t m_height;
uint32_t m_debug;
uint32_t m_reset;
HextileData m_hexTileData;
entry::MouseState m_mouseState;
bgfx::UniformHandle u_params;
int64_t m_timeOffset;
bx::Vec3 m_eye = { 0.0f, 2.0f, -0.01f };
};
} // namespace
ENTRY_IMPLEMENT_MAIN(
ExampleHextile
, "49-hextile"
, "Hextile example."
, "https://bkaradzic.github.io/bgfx/examples.html#hextile"
);

View File

@ -0,0 +1,10 @@
#
# Copyright 2011-2022 Branimir Karadzic. All rights reserved.
# License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
BUILD_DIR=../../.build
include $(BGFX_DIR)/scripts/shader.mk

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

@ -0,0 +1,13 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 v_position : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 v_view : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0);
vec3 v_tangent : TANGENT = vec3(1.0, 0.0, 0.0);
vec3 v_bitangent : BINORMAL = vec3(0.0, 1.0, 0.0);
vec4 v_color0 : COLOR = vec4(1.0, 0.0, 0.0, 1.0);
vec3 a_position : POSITION;
vec4 a_normal : NORMAL;
vec4 a_tangent : TANGENT;
vec2 a_texcoord0 : TEXCOORD0;
vec4 a_color0 : COLOR0;

View File

@ -0,0 +1,18 @@
$input a_position, a_texcoord0
$output v_position, v_texcoord0
/*
* Copyright 2015 Andrew Mac. All rights reserved.
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
*/
#include "../common/common.sh"
void main()
{
vec3 vp = mul(u_model[0], vec4(a_position.xyz, 1.0)).xyz;
v_position = vp;
v_texcoord0 = mul(u_model[0], vec4(a_texcoord0.xy, 1.0, 1.0)).xy;
gl_Position = mul(u_viewProj, vec4(vp.xyz, 1.0));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

@ -1,18 +1,20 @@
textures = $pwd/../../runtime/textures
build $textures/texture_compression_bc1.ktx: texturec_bc1 $pwd/texture-compression-test.png
build $textures/texture_compression_bc2.ktx: texturec_bc2 $pwd/texture-compression-test.png
build $textures/texture_compression_bc3.ktx: texturec_bc3 $pwd/texture-compression-test.png
build $textures/texture_compression_bc7.ktx: texturec_bc7 $pwd/texture-compression-test.png
build $textures/texture_compression_etc1.ktx: texturec_etc1 $pwd/texture-compression-test.png
build $textures/texture_compression_etc2.ktx: texturec_etc2 $pwd/texture-compression-test.png
build $textures/parallax-d.ktx: texturec_diffuse $pwd/parallax-d.png
build $textures/parallax-n.ktx: texturec_normal $pwd/parallax-n.png
build $textures/parallax-h.ktx: texturec_height $pwd/parallax-h.png
build $textures/lightmap.ktx: texturec_height $pwd/../sky/lightmap.png
build $textures/uffizi.ktx: texturec_equirect $pwd/uffizi-large.exr
build $textures/texture_compression_rgba8.dds: texturec_rgba8 $pwd/texture-compression-test.png
build $textures/pf_alpha_test.dds: texturec_rgba8 $pwd/texture-alpha-test.png
build $textures/pf_uv_filtering_test.dds: texturec_rgba8 $pwd/texture-uv-filtering-test.png
textures = $pwd/../../runtime/textures
build $textures/texture_compression_bc1.ktx: texturec_bc1 $pwd/texture-compression-test.png
build $textures/texture_compression_bc2.ktx: texturec_bc2 $pwd/texture-compression-test.png
build $textures/texture_compression_bc3.ktx: texturec_bc3 $pwd/texture-compression-test.png
build $textures/texture_compression_bc7.ktx: texturec_bc7 $pwd/texture-compression-test.png
build $textures/texture_compression_etc1.ktx: texturec_etc1 $pwd/texture-compression-test.png
build $textures/texture_compression_etc2.ktx: texturec_etc2 $pwd/texture-compression-test.png
build $textures/parallax-d.ktx: texturec_diffuse $pwd/parallax-d.png
build $textures/parallax-n.ktx: texturec_normal $pwd/parallax-n.png
build $textures/parallax-h.ktx: texturec_height $pwd/parallax-h.png
build $textures/lightmap.ktx: texturec_height $pwd/../sky/lightmap.png
build $textures/uffizi.ktx: texturec_equirect $pwd/uffizi-large.exr
build $textures/texture_compression_rgba8.dds: texturec_rgba8 $pwd/texture-compression-test.png
build $textures/pf_alpha_test.dds: texturec_rgba8 $pwd/texture-alpha-test.png
build $textures/pf_uv_filtering_test.dds: texturec_rgba8 $pwd/texture-uv-filtering-test.png
build $textures/aerial_rocks_04_diff_2k.ktx: texturec_bc7 $pwd/aerial_rocks_04_diff_2k.jpg

View File

@ -52,6 +52,7 @@ all:
@make -s --no-print-directory build -C 46-fsr
@make -s --no-print-directory build -C 47-pixelformats
@make -s --no-print-directory build -C 48-drawindirect
@make -s --no-print-directory build -C 49-hextile
rebuild:
@make -s --no-print-directory rebuild -C 01-cubes
@ -102,6 +103,7 @@ rebuild:
@make -s --no-print-directory rebuild -C 46-fsr
@make -s --no-print-directory rebuild -C 47-pixelformats
@make -s --no-print-directory rebuild -C 48-drawindirect
@make -s --no-print-directory rebuild -C 49-hextile
rebuild-embedded:
@make -s --no-print-directory rebuild -C 02-metaballs

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -592,6 +592,7 @@ or _OPTIONS["with-combined-examples"] then
, "46-fsr"
, "47-pixelformats"
, "48-drawindirect"
, "49-hextile"
)
-- 17-drawstress requires multithreading, does not compile for singlethreaded wasm