Skip to content

Commit

Permalink
Add SDL2 example
Browse files Browse the repository at this point in the history
  • Loading branch information
LunaTheFoxgirl committed Feb 13, 2024
1 parent a7b5808 commit a7a0bba
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ d-metal-binding-test-*
*.o
*.obj
*.lst

libSDL2.dylib
out/
dub.selections.json
19 changes: 19 additions & 0 deletions examples/sdl-example/dub.sdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name "sdl-example"
description "SDL2 exmaple application"
authors "Luna"
copyright "Copyright © 2024, Luna"
license "proprietary"

dependency "d-metal-binding" path="../../"
dependency "bindbc-sdl" version="~>1.4.5"
dependency "inmath" version="~>1.0.5"

targetPath "out/"
workingDirectory "out/"

lflags "-framework" "CoreData" "-framework" "CoreGraphics" "-framework" "Foundation" "-all_load"
libs "objc"

// NOTE: Throw SDL2 in libs/
copyFiles "libs/*"
versions "SDL_2_28"
Empty file.
91 changes: 91 additions & 0 deletions examples/sdl-example/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import std.stdio;
import std.exception;
import bindbc.sdl;
import metal;
import metal.metalkit;
import objc.runtime;
import objc.meta;
import inmath;
import inmath.hsv;

// Time managment
ulong prevTime = 0;
ulong time = 0;

void main() {

// Init SDL2
auto load = loadSDL();
enforce(load != SDLSupport.noLibrary, "SDL2 not found!");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);

// Create window with Metal layer attached.
// NOTE: SDL_WINDOW_ALLOW_HIGHDPI should be passed in to make sure the layer size is correct.
SDL_Window* window = SDL_CreateWindow("SDL Metal Example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_METAL | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE);
SDL_MetalView view = SDL_Metal_CreateView(window);
CAMetalLayer layer = cast(CAMetalLayer)SDL_Metal_GetLayer(view);

// Create MTLDevice handle
auto device = MTLCreateSystemDefaultDevice();
enforce(cast(void*)device !is null, "Could not create metal device");

// Attach it to the layer, otherwise we can't render anything.
layer.device = device;
writeln("Created Metal context on ", device.name, " (", layer.drawableSize.width, ", ", layer.drawableSize.height, ")...");

// Prepare drawing primitives.
CAMetalDrawable drawable;
MTLCommandQueue queue = layer.device.newCommandQueue();
MTLRenderPassDescriptor pass = MTLRenderPassDescriptor.new_();
pass.colorAttachments[0].loadAction = MTLLoadAction.Clear;
pass.colorAttachments[0].storeAction = MTLStoreAction.Store;

// Event loop
bool closeRequested = false;
while(!closeRequested) {

// Delta time calculation
prevTime = time;
time = SDL_GetTicks64();
float deltaTime = (cast(float)time-cast(float)prevTime)*0.0001;

// SDL Event loop
SDL_PumpEvents();
SDL_Event ev;
while (SDL_PollEvent(&ev)) {
switch(ev.type) {

case SDL_QUIT:
closeRequested = true;
break;

case SDL_WINDOWEVENT:
if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {

// NOTE: The event data provided by ev.window.data1/data2 do not take DPI in to account
// macOS has fractional UI scaling, so to properly handle that we need to use this API.
int w, h;
SDL_Metal_GetDrawableSize(window, &w, &h);
layer.drawableSize = CGSize(w, h);
}
break;

default: break;
}
}

// Change clear color by scrolling through RGB
drawable = layer.nextDrawable();

auto rgb = hsv2rgb(vec3((sin(cast(float)time*0.0001)+1)*0.5, 1.0, 1.0));
pass.colorAttachments[0].clearColor = MTLClearColor(rgb.x, rgb.y, rgb.z, 0);
pass.colorAttachments[0].texture = drawable.texture;
MTLCommandBuffer cmdBuffer = queue.commandBuffer();

MTLRenderCommandEncoder encoder = cmdBuffer.renderCommandEncoderWithDescriptor(pass);
encoder.endEncoding();

cmdBuffer.presentDrawable(drawable);
cmdBuffer.commit();
}
}

0 comments on commit a7a0bba

Please sign in to comment.