Last active
August 24, 2016 22:02
-
-
Save TheBuzzSaw/ff1799d705f6b2ce78b212ba92e96536 to your computer and use it in GitHub Desktop.
Morton order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <iomanip> | |
| #include <cstdint> | |
| #include <SDL.h> | |
| using namespace std; | |
| constexpr uint32_t MortonXMask = 0x55555555; | |
| constexpr uint32_t MortonYMask = MortonXMask << 1; | |
| uint32_t OldPacked(uint32_t value) | |
| { | |
| uint32_t result = 0; | |
| for (int i = 0; i < 16; ++i) | |
| { | |
| uint32_t mask = 1 << (i * 2); | |
| result |= (value & mask) >> i; | |
| } | |
| return result; | |
| } | |
| constexpr uint32_t Packed(uint32_t value) | |
| { | |
| return | |
| ((value & (1 << 0)) >> 0) | | |
| ((value & (1 << 2)) >> 1) | | |
| ((value & (1 << 4)) >> 2) | | |
| ((value & (1 << 6)) >> 3) | | |
| ((value & (1 << 8)) >> 4) | | |
| ((value & (1 << 10)) >> 5) | | |
| ((value & (1 << 12)) >> 6) | | |
| ((value & (1 << 14)) >> 7) | | |
| ((value & (1 << 16)) >> 8) | | |
| ((value & (1 << 18)) >> 9) | | |
| ((value & (1 << 20)) >> 10) | | |
| ((value & (1 << 22)) >> 11) | | |
| ((value & (1 << 24)) >> 12) | | |
| ((value & (1 << 26)) >> 13) | | |
| ((value & (1 << 28)) >> 14) | | |
| ((value & (1 << 30)) >> 15); | |
| } | |
| constexpr uint32_t MortonX(uint32_t mortonIndex) | |
| { | |
| return Packed(mortonIndex & MortonXMask); | |
| } | |
| constexpr uint32_t MortonY(uint32_t mortonIndex) | |
| { | |
| return Packed((mortonIndex & MortonYMask) >> 1); | |
| } | |
| constexpr uint32_t Spread(uint32_t value) | |
| { | |
| return | |
| ((value & (1 << 0)) << 0) | | |
| ((value & (1 << 1)) << 1) | | |
| ((value & (1 << 2)) << 2) | | |
| ((value & (1 << 3)) << 3) | | |
| ((value & (1 << 4)) << 4) | | |
| ((value & (1 << 5)) << 5) | | |
| ((value & (1 << 6)) << 6) | | |
| ((value & (1 << 7)) << 7) | | |
| ((value & (1 << 8)) << 8) | | |
| ((value & (1 << 9)) << 9) | | |
| ((value & (1 << 10)) << 10) | | |
| ((value & (1 << 11)) << 11) | | |
| ((value & (1 << 12)) << 12) | | |
| ((value & (1 << 13)) << 13) | | |
| ((value & (1 << 14)) << 14) | | |
| ((value & (1 << 15)) << 15); | |
| } | |
| uint32_t OldSpread(uint32_t value) | |
| { | |
| uint32_t result = 0; | |
| for (int i = 0; i < 16; ++i) | |
| { | |
| uint32_t bit = value & (1 << i); | |
| result |= bit << i; | |
| } | |
| return result; | |
| } | |
| constexpr uint32_t MortonIndex(uint32_t x, uint32_t y) | |
| { | |
| return Spread(x) | (Spread(y) << 1); | |
| } | |
| int TestMorton() | |
| { | |
| int p4 = 1; | |
| for (int i = 0; i < 8; ++i) | |
| cout << ' ' << (p4 *= 4); | |
| cout << endl; | |
| int p2 = 1; | |
| for (int i = 0; i < 8; ++i) | |
| { | |
| p2 *= 2; | |
| cout << ' ' << p2 << '(' << (p2 * p2) << ')'; | |
| } | |
| cout << endl; | |
| //return 0; | |
| //cout << hex << MortonXMask << '\n' << MortonYMask << endl; | |
| for (uint32_t i = 0; i < 8; ++i) | |
| { | |
| for (uint32_t j = 0; j < 8; ++j) | |
| { | |
| cout << " [" << MortonIndex(j, i) << ']'; | |
| } | |
| cout << '\n'; | |
| } | |
| for (uint32_t i = 0; i <= 64; ++i) | |
| { | |
| cout << " [" << MortonX(i) << ", " << MortonY(i) << ']'; | |
| } | |
| cout << endl; | |
| return 0; | |
| } | |
| void CreateWindow() | |
| { | |
| SDL_Init(SDL_INIT_VIDEO); | |
| auto window = SDL_CreateWindow( | |
| "Morton", | |
| SDL_WINDOWPOS_CENTERED, | |
| SDL_WINDOWPOS_CENTERED, | |
| 1024, | |
| 768, | |
| SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); | |
| bool running = true; | |
| uint8_t color = 0x7f; | |
| { | |
| auto surface = SDL_GetWindowSurface(window); | |
| cout << "bytes per pixel: " << (int)surface->format->BytesPerPixel << endl; | |
| } | |
| while (running) | |
| { | |
| auto surface = SDL_GetWindowSurface(window); | |
| size_t byteCount = surface->w * surface->h * surface->format->BytesPerPixel; | |
| auto pixels = (uint32_t*)surface->pixels; | |
| memset(pixels, ++color, byteCount); | |
| if (surface->h > 5) | |
| { | |
| auto w = surface->w; | |
| auto row = pixels + w * 5; | |
| w /= 2; | |
| for (int i = 0; i < w; ++i) | |
| { | |
| // ARGB | |
| row[i] = 0x00ff0000; | |
| } | |
| } | |
| SDL_UpdateWindowSurface(window); | |
| SDL_Event event; | |
| if (SDL_WaitEvent(&event)) | |
| { | |
| switch (event.type) | |
| { | |
| case SDL_WINDOWEVENT: | |
| { | |
| switch (event.window.event) | |
| { | |
| case SDL_WINDOWEVENT_EXPOSED: cout << "SDL_WINDOWEVENT_EXPOSED" << endl; break; | |
| default: break; | |
| } | |
| break; | |
| } | |
| case SDL_KEYDOWN: cout << "SDL_KEYDOWN" << endl; break; | |
| case SDL_QUIT: cout << "SDL_QUIT" << endl; running = false; break; | |
| default: break; | |
| } | |
| } | |
| else | |
| { | |
| running = false; | |
| cerr << "Error on SDL_WaitEvent: " << SDL_GetError() << '\n'; | |
| } | |
| } | |
| SDL_Quit(); | |
| } | |
| int main(int argc, char** argv) | |
| { | |
| //return TestMorton(); | |
| CreateWindow(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment