Skip to content

Instantly share code, notes, and snippets.

@doomed-phobos
Last active March 3, 2024 16:59
Show Gist options
  • Save doomed-phobos/7979d35377f2975eefffcc209bd1f1c9 to your computer and use it in GitHub Desktop.
Save doomed-phobos/7979d35377f2975eefffcc209bd1f1c9 to your computer and use it in GitHub Desktop.
Explaining THE ALGORITHM in the Bisqwit's video about OpenGL
/// Sorry my bad english Dx
/// Original Source: https://www.youtube.com/watch?v=SktXhGElf7w
///
/// God bless Bisqwit
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <cmath>
#include <array>
static std::vector<GLfloat> tri;
/// ~0 reverses 0b0000000000... => 0b1111111111... = 0xFFFFFF...
/// With octal numbers, each group of 3 bits match their digit number.
///
/// 012345 (octal) = 5349 (decimal) =
/// 1010011100101 (binary)
///
/// "each group of 3 bits"
/// 1 010 011 100 101
/// "match their digit number"
/// 1 2 3 4 5
///
/// That's why we use ext(123341, 1, 3) => 4
void addcuboid(unsigned mask,
std::array<float,2> x /*min, max*/,
std::array<float,2> z /*min, max*/,
std::array<float,2> y /*min, max*/,
std::array<float,3> c, std::array<float,3> u, std::array<float,3> v) {
/// Extracts the 'n'-th group of 'b' bits.
auto ext = [](auto m,unsigned n,unsigned b=1) { return (m >> (n*b)) & ~(~0u << b); };
// Generates: For six vertices, color(rgb), coordinate(xyz) and texture coord(uv).
std::array p{&c[0],&c[0],&c[0], &x[0],&y[0],&z[0], &u[0],&v[0]};
// capflag(1 bit), mask(3 bits), X(4 bits), Y(4 bits), Z(4 bits), U(4 bits), V(4 bits)
for(unsigned m: std::array{0x960339,0xA9F339,0x436039,0x4C6F39,0x406C39,0x4F6339}) // bottom, top, four sides
/// This creates a pattern of 0b11'000'111
///
/// (~0llu/255) creates empty space to copy pattern. 255 = 0xFF is used because it selects 8 bits.
///
/// 0b11'000'111 (8 bits)
/*
7 << 20 111 0000 0000 0000 0000 0000
Bottom: 0x960339 1 001 0110 0000 0011 0011 1001
Top: 0xA9F339 1 010 1001 1111 0011 0011 1001
0x436039 0 100 0011 0110 0000 0011 1001
Sides: 0x4C6F39 0 100 1100 0110 1111 0011 1001
0x406C39 0 100 0000 0110 1100 0011 1001
0x4F6339 0 100 1111 0110 0011 0011 1001
'mask' indicates which side to build.
001 => Bottom
010 => Top
100 => Sides
*/
if(std::uint64_t s = (m>>23) * 0b11'000'111 * (~0llu/255); mask & m)
for(unsigned n = 0; n < 6*8 /*6 for 123341 8 for 8 items in p*/; ++n)
/// First, we'll focus in xyz: 012 >>>345<<< 444.
/// That becomes in 12, 16, 20 respectively, in the mask 0x960339 (bottom) corresponds to:
/// v v v
/// 1 001 0110 0000 0011 0011 1001 (initial index)
/// With the octal number 123341 (order) substracting creates as an array, i.e.
/// order or
/// index = 1 2 3 4
/// x = 0 1 1 0
///
/// 0b123341 x = {-10, 10}, y = {-10, 10}, z = {-10, 10}
/// 1:
/// v v v
/// 1 001 0110 0000 0011 0011 1001 (-10, -10, -10
///
/// 3:
/// v v v
/// 1 001 0110 0000 0011 0011 1001 ( 10, -10, 10)
///
/// ...
/// capflag (ext(s, n)) indicates if use the following paremeters:
///
/// capflag on:
/// color: {top, cap}
/// u, v: {min, max for horizontal}
/// capflag off:
/// color: {top, bottom}
/// u, v: {min, max}
tri.push_back( p[n%8][ext(m, ext(012345444u, n%8, 3)*4 - ext(0123341u, n/8, 3)) << ext(s,n)] );
// 123341 = order of vertices in two triangles; 12345444 = nibble indexes in "m" for each of 8 values
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment