Created
October 2, 2021 05:54
-
-
Save treeform/9382773692f7a4871c876e1d9ac9db6c to your computer and use it in GitHub Desktop.
glfw metal example
This file contains 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
#define GLFW_INCLUDE_NONE | |
#import <GLFW/glfw3.h> | |
#define GLFW_EXPOSE_NATIVE_COCOA | |
#import <GLFW/glfw3native.h> | |
#import <Metal/Metal.h> | |
#import <QuartzCore/QuartzCore.h> | |
#import <simd/simd.h> | |
#include <assert.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
static void error_callback(int error, const char* description) | |
{ | |
fputs(description, stderr); | |
} | |
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) | |
{ | |
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) | |
glfwSetWindowShouldClose(window, GLFW_TRUE); | |
} | |
int main2(void) | |
{ | |
id<MTLDevice> device = MTLCreateSystemDefaultDevice(); | |
if (!device) | |
exit(EXIT_FAILURE); | |
glfwSetErrorCallback(error_callback); | |
if (!glfwInit()) | |
exit(EXIT_FAILURE); | |
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | |
GLFWwindow* window = glfwCreateWindow(640, 480, "Metal Example", NULL, NULL); | |
if (!window) | |
{ | |
glfwTerminate(); | |
exit(EXIT_FAILURE); | |
} | |
NSWindow* nswin = glfwGetCocoaWindow(window); | |
CAMetalLayer* layer = [CAMetalLayer layer]; | |
layer.device = device; | |
layer.pixelFormat = MTLPixelFormatBGRA8Unorm; | |
nswin.contentView.layer = layer; | |
nswin.contentView.wantsLayer = YES; | |
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(0, 1, 0, 1);\n" | |
"}\n" | |
options:compileOptions error:&compileError]; | |
if (!lib) | |
{ | |
NSLog(@"can't create library: %@", compileError); | |
glfwTerminate(); | |
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); | |
glfwSetKeyCallback(window, key_callback); | |
while (!glfwWindowShouldClose(window)) | |
{ | |
float ratio; | |
int width, height; | |
glfwGetFramebufferSize(window, &width, &height); | |
ratio = width / (float) height; | |
layer.drawableSize = CGSizeMake(width, height); | |
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]; | |
glfwPollEvents(); | |
} | |
glfwDestroyWindow(window); | |
glfwTerminate(); | |
exit(EXIT_SUCCESS); | |
} |
This file contains 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
{. | |
passC: "-D_GLFW_COCOA", | |
passL: "-framework Cocoa -framework OpenGL -framework Metal -framework QuartzCore", | |
compile: "metal.m", | |
.} | |
import staticglfw | |
proc main2(): cint {.importc.} | |
echo "here" | |
discard main2() | |
echo "bye" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment