Skip to content

Commit

Permalink
Merge pull request #38 from meshula/main
Browse files Browse the repository at this point in the history
add the metal example
  • Loading branch information
ColleagueRiley authored Oct 20, 2024
2 parents 1e93171 + 9646033 commit f00d54a
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 2 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LIB_EXT = .dll

LIBS += -D _WIN32_WINNT="0x0501"

WARNINGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wstrict-prototypes -Wold-style-definition -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-missing-braces -Wno-missing-variable-declarations -Wno-redundant-decls -Wno-unused-function -Wno-unused-label -Wno-unused-result -Wno-incompatible-pointer-types -Wno-format -Wno-format-extra-args -Wno-implicit-function-declaration -Wno-implicit-int -Wno-pointer-sign -Wno-switch -Wno-switch-default -Wno-switch-enum -Wno-unused-value -Wno-type-limits
WARNINGS = -Wall -Wstrict-prototypes -Wextra -Wstrict-prototypes -Wold-style-definition -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-missing-braces -Wno-missing-variable-declarations -Wno-redundant-decls -Wno-unused-function -Wno-unused-label -Wno-unused-result -Wno-incompatible-pointer-types -Wno-format -Wno-format-extra-args -Wno-implicit-function-declaration -Wno-implicit-int -Wno-pointer-sign -Wno-switch -Wno-switch-default -Wno-switch-enum -Wno-unused-value -Wno-type-limits
OS_DIR = \\

NO_GLES = 1
Expand Down Expand Up @@ -84,7 +84,8 @@ EXAMPLE_OUTPUTS = \
examples/silk/silk \
examples/events/events \
examples/callbacks/callbacks \
examples/first-person-camera/camera
examples/first-person-camera/camera \
examples/metal

EXAMPLE_OUTPUTS_CUSTOM = \
examples/microui_demo/microui_demo \
Expand Down Expand Up @@ -130,6 +131,16 @@ else
@echo directX is not supported on $(detected_OS)
endif


examples/metal/metal: examples/metal/metal.m RGFW.h
ifeq ($(detected_OS),Darwin) # Mac OS X
gcc $(CUSTOM_CFLAGS) -x c -c RGFW.h -D RGFW_NO_API -D RGFW_EXPORT -D RGFW_IMPLEMENTATION -o RGFW.o
gcc $(CUSTOM_CFLAGS) examples/metal/metal.m RGFW.o -I. -lm -framework Metal -framework Foundation -framework AppKit -framework Cocoa -framework CoreVideo -framework QuartzCore -o $@
else
@echo metal is not supported on $(detected_OS)
endif


examples/microui_demo/microui_demo: examples/microui_demo/microui_demo.c RGFW.h
ifneq ($(CC), emcc)
$(CC) $(CFLAGS) -I. $< $(LIBS) $(LINK_GL1) -o $@$(EXT)
Expand Down
Binary file added examples/metal/metal
Binary file not shown.
144 changes: 144 additions & 0 deletions examples/metal/metal.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//========================================================================
// Simple RGFW+Metal example
//
//
// made using a modifed version of the GLFW+metal example
// https://github.com/glfw/glfw/blob/metal-guide/examples/metal.m
//
// Copyright (c) Camilla Berglund <[email protected]>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================

/* RGFW will have to be linked/compiled outside of this file
because this file uses objective-c and RGFW uses work arounds
*/
//#define RGFW_IMPLEMENTATION
#define RGFW_NO_API
#define RGFWDEF
#import "RGFW.h"

#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#import <simd/simd.h>

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
if (!device)
exit(EXIT_FAILURE);

RGFW_window* window = RGFW_createWindow("RGFW Metal example", RGFW_RECT(0, 0, 640, 480), RGFW_CENTER);

CAMetalLayer* layer = [CAMetalLayer layer];
layer.device = device;
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;

NSView* view = (NSView*)window->src.view;
[view setLayer: layer];
// [view setWantsLayer: YES]; (I think RGFW already sets this)

MTLCompileOptions* compileOptions = [MTLCompileOptions new];
compileOptions.languageVersion = MTLLanguageVersion1_1;
NSError* compileError;
id<MTLLibrary> lib = [device newLibraryWithSource:
@"#include <metal_stdlib>\n"
"using namespace metal;\n"
"vertex float4 v_simple(\n"
" constant float4* in [[buffer(0)]],\n"
" uint vid [[vertex_id]])\n"
"{\n"
" return in[vid];\n"
"}\n"
"fragment float4 f_simple(\n"
" float4 in [[stage_in]])\n"
"{\n"
" return float4(1, 0, 0, 1);\n"
"}\n"
options:compileOptions error:&compileError];
if (!lib)
{
NSLog(@"can't create library: %@", compileError);
exit(EXIT_FAILURE);
}

id<MTLFunction> vs = [lib newFunctionWithName:@"v_simple"];
assert(vs);
id<MTLFunction> fs = [lib newFunctionWithName:@"f_simple"];
assert(fs);

id<MTLCommandQueue> cq = [device newCommandQueue];
assert(cq);

MTLRenderPipelineDescriptor* rpd = [MTLRenderPipelineDescriptor new];
rpd.vertexFunction = vs;
rpd.fragmentFunction = fs;
rpd.colorAttachments[0].pixelFormat = layer.pixelFormat;
id<MTLRenderPipelineState> rps = [device newRenderPipelineStateWithDescriptor:rpd error:NULL];
assert(rps);

while (!RGFW_window_shouldClose(window)) {
while (RGFW_window_checkEvent(window) != NULL) {
if (window->event.type == RGFW_quit)
break;
}

float ratio;

ratio = window->r.w / (float) window->r.h;

layer.drawableSize = CGSizeMake(window->r.w, window->r.h);
id<CAMetalDrawable> drawable = [layer nextDrawable];
assert(drawable);

id<MTLCommandBuffer> cb = [cq commandBuffer];

MTLRenderPassDescriptor* rpd = [MTLRenderPassDescriptor new];
MTLRenderPassColorAttachmentDescriptor* cd = rpd.colorAttachments[0];
cd.texture = drawable.texture;
cd.loadAction = MTLLoadActionClear;
cd.clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);
cd.storeAction = MTLStoreActionStore;
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:rpd];

[rce setRenderPipelineState:rps];
[rce setVertexBytes:(vector_float4[]){
{ 0, 0, 0, 1 },
{ -1, 1, 0, 1 },
{ 1, 1, 0, 1 },
} length:3 * sizeof(vector_float4) atIndex:0];
[rce drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];

[rce endEncoding];
[cb presentDrawable:drawable];
[cb commit];
}


RGFW_window_close(window);
}



0 comments on commit f00d54a

Please sign in to comment.