Advertisement
Kitomas

main.cpp for vlktut as of 2023-12-29

Dec 29th, 2023
798
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.43 KB | None | 0 0
  1. #include <libxmp/xmp.h>
  2. #define SDL_MAIN_HANDLED
  3. #include <SDL2/SDL.h>
  4. #include <SDL2/SDL_vulkan.h> //why isn't this included inside SDL.h?
  5. #include <glm/glm.hpp>
  6. #include <vulkan/vulkan.h>
  7.  
  8. #include <iostream>
  9. #include <stdexcept>
  10. #include <cstdlib>
  11.  
  12. #include <vk/vk_all.hpp>
  13. #include <sfx.hpp>
  14. #include <file.hpp>
  15. #include <xmp.hpp>
  16.  
  17.  
  18. class HelloTriangleApplication {
  19. public:
  20.   void run(Uint32 winW = 640, Uint32 winH = 480){
  21.     _initWindow(winW, winH);
  22.     _initVulkan();
  23.     _mainLoop();
  24.     _cleanup();
  25.   }
  26.  
  27.  
  28. private:
  29.   SDL_Window* _window = nullptr;
  30.   Uint32 _windowID = 0;
  31.  
  32.   VkInstance _instance = nullptr;
  33.  
  34.  
  35.   void _createInstance(){
  36.     VkApplicationInfo appInfo{};
  37.     appInfo.sType              = VK_STRUCTURE_TYPE_APPLICATION_INFO;
  38.     appInfo.pApplicationName   = "cool triangle";
  39.     appInfo.applicationVersion = VK_MAKE_VERSION(1,0,0);
  40.     appInfo.pEngineName        = "No Engine";
  41.     appInfo.engineVersion      = VK_MAKE_VERSION(1,0,0);
  42.     appInfo.apiVersion         = VK_API_VERSION_1_0;
  43.  
  44.  
  45.     bool success;  VkResult result;
  46.  
  47.     Uint32 extensionsReq_len = 0; //# of required extensions
  48.     success = SDL_Vulkan_GetInstanceExtensions(_window, &extensionsReq_len, nullptr);
  49.     if(!success) throw SDL_GetError();
  50.     std::vector<const char*> extensionsReq(extensionsReq_len);
  51.     success = SDL_Vulkan_GetInstanceExtensions(_window, &extensionsReq_len, extensionsReq.data());
  52.     if(!success) throw SDL_GetError();
  53.  
  54.     Uint32 extensionsHas_len = 0; //# of available extensions
  55.     result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsHas_len, nullptr);
  56.     if(result != VK_SUCCESS) throw "vkEnumerateInstanceExtensionProperties() failed";
  57.     std::vector<VkExtensionProperties> extensionsHas(extensionsHas_len);
  58.     result = vkEnumerateInstanceExtensionProperties(nullptr, &extensionsHas_len, extensionsHas.data());
  59.     if(result != VK_SUCCESS) throw "vkEnumerateInstanceExtensionProperties() failed";
  60.  
  61.  
  62.     //make sure to account for # of desired extensions too when they're added
  63.     if(extensionsReq_len > extensionsHas_len)
  64.       throw "# of required extensions > # of available extensions";
  65.  
  66.     //copy everything from Req to Want
  67.     Uint32 extensionsWant_len = extensionsReq_len; //# of desired extensions
  68.     std::vector<std::string> extensionsWant;
  69.     extensionsWant.reserve(extensionsHas_len);
  70.  
  71.     for(const char* extReq : extensionsReq)
  72.       extensionsWant.emplace_back(extReq);
  73.     //then, append any desired extensions to extension
  74.     //extensionsWant.emplace_back("VK_EXT_swapchain_colorspace");
  75.     //...
  76.     //extensionsWant_len += 1; //+= <# of desired extensions>;
  77.  
  78.     //make sure extensionsWant is a superset of extensionsHas
  79.     for(std::string& extWant : extensionsWant){
  80.       bool foundAMatch = false;
  81.       for(VkExtensionProperties& extHas : extensionsHas){
  82.         if(extWant.compare(extHas.extensionName) == 0  ||  extWant == ""){
  83.           foundAMatch = true;  break;
  84.         }
  85.       }
  86.       if(!foundAMatch) throw "extensionsHas doesn't contain extensionsWant";
  87.     }
  88.  
  89.  
  90.     //translate extensionsWant to a C string array for use in vkCreateInstance
  91.     Uint32 extensions_len = extensionsWant_len; //for consistency
  92.     std::vector<const char*> extensions(extensionsWant_len);
  93.     for(Uint32 i=0; i<extensionsWant_len; ++i)
  94.       extensions[i] = extensionsWant[i].c_str();
  95.  
  96.  
  97.     VkInstanceCreateInfo createInfo{};
  98.     createInfo.sType                   = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
  99.     createInfo.pApplicationInfo        = &appInfo;
  100.     createInfo.enabledLayerCount       = 0; //TBD
  101.     createInfo.enabledExtensionCount   = extensions_len;
  102.     createInfo.ppEnabledExtensionNames = extensions.data();
  103.  
  104.     result = vkCreateInstance(&createInfo, nullptr, &_instance);
  105.     if(result == VK_ERROR_EXTENSION_NOT_PRESENT) throw "vkCreateInstance() = VK_ERROR_EXTENSION_NOT_PRESENT";
  106.     if(result != VK_SUCCESS) throw "vkCreateInstance() failed";
  107.  
  108.  
  109.     //debug print stuff
  110.     SDL_Log("# of required extensions = %u:",extensionsReq_len);
  111.     for(Uint32 i=0; i<extensionsReq_len; ++i) SDL_Log("  %u: \"%s\"",i,extensionsReq[i]);
  112.     SDL_Log("# of available extensions = %u:",extensionsHas_len);
  113.     for(Uint32 i=0; i<extensionsHas_len; ++i) SDL_Log("  %2u: \"%s\" (%u)",i,extensionsHas[i].extensionName,extensionsHas[i].specVersion);
  114.     SDL_Log("# of desired extensions = %u:",extensionsWant_len);
  115.     for(Uint32 i=0; i<extensionsWant_len; ++i) SDL_Log("  %2u: \"%s\"",i,extensionsWant[i].c_str());
  116.   }
  117.  
  118.  
  119.   void _initWindow(Uint32 winW = 640, Uint32 winH = 480){
  120.     _window = SDL_CreateWindow("a cool triangle",
  121.                                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  122.                                winW, winH, SDL_WINDOW_VULKAN);
  123.     if(_window == nullptr) throw SDL_GetError();
  124.     _windowID = SDL_GetWindowID(_window);
  125.     if(_windowID == 0) throw SDL_GetError();
  126.   }
  127.  
  128.  
  129.   void _initVulkan(){
  130.     _createInstance();
  131.   }
  132.  
  133.  
  134.   void _mainLoop(){
  135.     bool running = true;
  136.     SDL_Event event;
  137.  
  138.     while(running){
  139.       while(SDL_PollEvent(&event) && running){
  140.         switch(event.type){
  141.         case SDL_WINDOWEVENT:
  142.           //the window id isn't checked here, so it could theoretically
  143.            //be another window entirely lol
  144.           if(event.window.event == SDL_WINDOWEVENT_CLOSE) running = false;
  145.         }
  146.       }
  147.       SDL_Delay(16);
  148.     }
  149.   }
  150.  
  151.  
  152.   void _cleanup(){
  153.     vkDestroyInstance(_instance, nullptr);
  154.     _instance = nullptr;
  155.     if(_window != nullptr){
  156.       SDL_DestroyWindow(_window);
  157.       _window = nullptr;
  158.     }
  159.   }
  160. };
  161.  
  162.  
  163.  
  164. #define M_2PI (3.1415927f*2)
  165. float get_sin(float hertz = 440, int increment = 1){
  166.   static int index = 0;
  167.   float value = SDL_sinf( ((float)index/44100)*M_2PI*hertz );
  168.   index += increment;
  169.   return value;
  170. }
  171.  
  172. //(t>>4)*(t>>3)|t>>2
  173. float get_sample(){
  174.   static int _t = 0;
  175.   int t = _t * (8000.0f/44100);
  176.   t *= 106.0/117;
  177.  
  178.   Uint8 _value = t*(t&16384?6:5)*(4-(1&t>>8))>>(3&t>>9)|t>>(t&4096?3:4);
  179.   //Uint8 _value = t<<2^t>>4^t<<4&t>>8|t<<1&-t>>4;
  180.   float value = _sfx_u8conv(_value);
  181.  
  182.   ++_t;
  183.   return value;
  184. }
  185.  
  186.  
  187. void auxCallback(void* userdata, void* _stream, int size){
  188.   int       len = size/sizeof(float);
  189.   float* stream = (float*)_stream;
  190.   for(int i=0; i<len; ++i){
  191.     //stream[i] = get_sin()*0.25f;
  192.     stream[i] = get_sample()*0.2f;
  193.  
  194.   }
  195. }
  196.  
  197.  
  198.  
  199.  
  200. int main(int argc, char** argv){
  201.   if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)) return -1;
  202.  
  203.   //wip vulkan stuff; ignore
  204.   HelloTriangleApplication app;
  205.   try {
  206.     app.run();
  207.   } catch(const std::exception& e){
  208.     std::cerr << e.what() << std::endl;
  209.     return EXIT_FAILURE;
  210.   } catch(const char* e){
  211.     std::cout << "error = " << e << std::endl;
  212.     return EXIT_FAILURE;
  213.   }
  214.  
  215.  
  216. /*
  217.   try {
  218.  
  219.     sfx_class sfx(64); //a maximum of 64 sound effects tracks
  220.     sfx_pcm cow("dat/Cow.kpm",&sfx); //load sound effect of a cow moo
  221.     xmp_class xmp(&sfx); //create music thingy
  222.     xmp.loadModule("dat/rob_me_if_you_can.xm"); //load music
  223.  
  224.     sfx.pauseDeviceAndWait(false); //unpause device, and wait for fade-in
  225.  
  226.     //play cow moo and play music for about 10 seconds
  227.     xmp.startPlayer();
  228.     cow.play();
  229.     SDL_Delay(10000);
  230.  
  231.     sfx.pauseDeviceAndWait(true); //pause device, and wait for fade-out
  232.     xmp.endPlayer();
  233.  
  234.   } catch(const char* e){
  235.     std::cout << "error = " << e << std::endl;
  236.     return EXIT_FAILURE;
  237.   }
  238.  
  239. */
  240.  
  241.   SDL_Quit();
  242.   return EXIT_SUCCESS;
  243. }
  244.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement