Advertisement
Guest User

D WebGPU example

a guest
Sep 20th, 2019
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 7.30 KB | None | 0 0
  1. module main;
  2.  
  3. import core.stdc.stdlib;
  4. import std.stdio;
  5. import std.file;
  6. import std.conv;
  7. import std.string;
  8. import std.process;
  9. import bindbc.sdl;
  10. import bindbc.wgpu;
  11.  
  12. void quit(string message)
  13. {
  14.     writeln(message);
  15.     core.stdc.stdlib.exit(1);
  16. }
  17.  
  18. void main()
  19. {
  20.     auto sdlSupport = loadSDL();
  21.     writeln("sdlSupport: ", sdlSupport);
  22.    
  23.     auto wgpuSupport = loadWGPU();
  24.     writeln("wgpuSupport: ", wgpuSupport);
  25.    
  26.     if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
  27.         quit("Error: failed to init SDL: " ~ to!string(SDL_GetError()));
  28.        
  29.     uint windowWidth = 800;
  30.     uint windowHeight = 600;
  31.    
  32.     auto window = SDL_CreateWindow(toStringz("wgpu-native"), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
  33.     SDL_SysWMinfo winInfo;
  34.     SDL_GetWindowWMInfo(window, &winInfo);
  35.     auto hwnd = winInfo.info.win.window;
  36.     auto hinstance = winInfo.info.win.hinstance;
  37.    
  38.     WGPURequestAdapterOptions reqAdaptersOptions =
  39.     {
  40.         power_preference: WGPUPowerPreference.LowPower,
  41.         backends: 2 | 4 | 8
  42.     };
  43.     WGPUAdapterId adapter = wgpu_request_adapter(&reqAdaptersOptions);
  44.    
  45.     WGPUDeviceDescriptor deviceDescriptor =
  46.     {
  47.         extensions:
  48.         {
  49.             anisotropic_filtering: false
  50.         },
  51.         limits:
  52.         {
  53.             max_bind_groups: 0
  54.         }
  55.     };
  56.     WGPUDeviceId device = wgpu_adapter_request_device(adapter, &deviceDescriptor);
  57.    
  58.     uint[] vs = cast(uint[])std.file.read("shaders/triangle.vert.spv");
  59.     uint[] fs = cast(uint[])std.file.read("shaders/triangle.frag.spv");
  60.    
  61.     WGPUShaderModuleDescriptor vsDescriptor = WGPUShaderModuleDescriptor(WGPUU32Array(vs.ptr, vs.length));
  62.     WGPUShaderModuleId vertexShader = wgpu_device_create_shader_module(device, &vsDescriptor);
  63.    
  64.     WGPUShaderModuleDescriptor fsDescriptor = WGPUShaderModuleDescriptor(WGPUU32Array(fs.ptr, fs.length));
  65.     WGPUShaderModuleId fragmentShader = wgpu_device_create_shader_module(device, &fsDescriptor);
  66.    
  67.     WGPUBindGroupLayoutDescriptor bindGroupLayoutDescriptor = WGPUBindGroupLayoutDescriptor(null, 0);
  68.     WGPUBindGroupLayoutId bindGroupLayout = wgpu_device_create_bind_group_layout(device, &bindGroupLayoutDescriptor);
  69.    
  70.     WGPUBindGroupDescriptor bindGroupDescriptor = WGPUBindGroupDescriptor(bindGroupLayout, null, 0);
  71.     WGPUBindGroupId bindGroup = wgpu_device_create_bind_group(device, &bindGroupDescriptor);
  72.    
  73.     WGPUBindGroupLayoutId[1] bindGroupLayouts = [bindGroupLayout];
  74.    
  75.     WGPUPipelineLayoutDescriptor pipelineLayoutDescriptor = WGPUPipelineLayoutDescriptor(bindGroupLayouts.ptr, bindGroupLayouts.length);
  76.     WGPUPipelineLayoutId pipelineLayout = wgpu_device_create_pipeline_layout(device, &pipelineLayoutDescriptor);
  77.    
  78.     WGPUProgrammableStageDescriptor vsStageDescriptor =
  79.     {
  80.         _module: vertexShader,
  81.         entry_point: "main".ptr
  82.     };
  83.    
  84.     WGPUProgrammableStageDescriptor fsStageDescriptor =
  85.     {
  86.         _module: fragmentShader,
  87.         entry_point: "main".ptr
  88.     };
  89.    
  90.     WGPURasterizationStateDescriptor rastStateDescriptor =
  91.     {
  92.         front_face: WGPUFrontFace.Ccw,
  93.         cull_mode: WGPUCullMode.None,
  94.         depth_bias: 0,
  95.         depth_bias_slope_scale: 0.0,
  96.         depth_bias_clamp: 0.0
  97.     };
  98.    
  99.     WGPUColorStateDescriptor colorStateDescriptor =
  100.     {
  101.         format: WGPUTextureFormat.Bgra8Unorm,
  102.         alpha_blend:
  103.         {
  104.             src_factor: WGPUBlendFactor.One,
  105.             dst_factor: WGPUBlendFactor.Zero,
  106.             operation: WGPUBlendOperation.Add
  107.         },
  108.         color_blend:
  109.         {
  110.             src_factor: WGPUBlendFactor.One,
  111.             dst_factor: WGPUBlendFactor.Zero,
  112.             operation: WGPUBlendOperation.Add
  113.         },
  114.         write_mask: WGPUColorWrite_ALL
  115.     };
  116.    
  117.     WGPURenderPipelineDescriptor renderPipelineDescriptor =
  118.     {
  119.         layout: pipelineLayout,
  120.         vertex_stage: vsStageDescriptor,
  121.         fragment_stage: &fsStageDescriptor,
  122.         primitive_topology: WGPUPrimitiveTopology.TriangleList,
  123.         rasterization_state: &rastStateDescriptor,
  124.         color_states: &colorStateDescriptor,
  125.         color_states_length: 1,
  126.         depth_stencil_state: null,
  127.         vertex_input:
  128.         {
  129.             index_format: WGPUIndexFormat.Uint16,
  130.             vertex_buffers: null,
  131.             vertex_buffers_length: 0,
  132.         },
  133.         sample_count: 1
  134.     };
  135.    
  136.     WGPURenderPipelineId renderPipeline = wgpu_device_create_render_pipeline(device, &renderPipelineDescriptor);
  137.    
  138.     WGPUSurfaceId surface = wgpu_create_surface_from_windows_hwnd(hinstance, hwnd);
  139.    
  140.     WGPUSwapChainId createSwapchain(uint w, uint h)
  141.     {
  142.         WGPUSwapChainDescriptor sd = {
  143.             usage: WGPUTextureUsage_OUTPUT_ATTACHMENT,
  144.             format: WGPUTextureFormat.Bgra8Unorm,
  145.             width: w,
  146.             height: h,
  147.             present_mode: WGPUPresentMode.Vsync
  148.         };
  149.         return wgpu_device_create_swap_chain(device, surface, &sd);
  150.     }
  151.    
  152.     WGPUSwapChainId swapchain = createSwapchain(windowWidth, windowHeight);
  153.    
  154.     WGPUSwapChainOutput nextTexture;
  155.     WGPURenderPassColorAttachmentDescriptor[1] colorAttachments =
  156.     [
  157.         {
  158.             attachment: nextTexture.view_id,
  159.             load_op: WGPULoadOp.Clear,
  160.             store_op: WGPUStoreOp.Store,
  161.             clear_color: WGPUColor(0.5, 0.5, 0.5, 1.0)
  162.         }
  163.     ];
  164.    
  165.     bool running = true;
  166.     SDL_Event event;
  167.     while(running)
  168.     {
  169.         if (SDL_PollEvent(&event))
  170.         {
  171.             if (event.type == SDL_QUIT)
  172.                 running = false;
  173.             else if (event.type == SDL_WINDOWEVENT)
  174.             {
  175.                 if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
  176.                 {
  177.                     windowWidth = event.window.data1;
  178.                     windowHeight = event.window.data2;
  179.                     writeln(windowWidth, "x", windowHeight);
  180.                     swapchain = createSwapchain(windowWidth, windowHeight);
  181.                 }
  182.             }
  183.         }
  184.        
  185.         nextTexture = wgpu_swap_chain_get_next_texture(swapchain);
  186.         WGPUCommandEncoderDescriptor commandEncDescriptor = WGPUCommandEncoderDescriptor(0);
  187.         WGPUCommandEncoderId cmdEncoder = wgpu_device_create_command_encoder(device, &commandEncDescriptor);
  188.         colorAttachments[0].attachment = nextTexture.view_id;
  189.        
  190.         WGPURenderPassDescriptor renderPassDescriptor =
  191.         {
  192.             color_attachments: colorAttachments.ptr,
  193.             color_attachments_length: 1,
  194.             depth_stencil_attachment: null
  195.         };
  196.         WGPURenderPassId rpass = wgpu_command_encoder_begin_render_pass(cmdEncoder, &renderPassDescriptor);
  197.        
  198.         wgpu_render_pass_set_pipeline(rpass, renderPipeline);
  199.         wgpu_render_pass_set_bind_group(rpass, 0, bindGroup, null, 0);
  200.         wgpu_render_pass_draw(rpass, 3, 1, 0, 0);
  201.        
  202.         WGPUQueueId queue = wgpu_device_get_queue(device);
  203.         wgpu_render_pass_end_pass(rpass);
  204.        
  205.         WGPUCommandBufferId cmdBuf = wgpu_command_encoder_finish(cmdEncoder, null);
  206.         wgpu_queue_submit(queue, &cmdBuf, 1);
  207.         wgpu_swap_chain_present(swapchain);
  208.     }
  209.    
  210.     SDL_Quit();
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement