it works somewhat, but not really

This commit is contained in:
Dynamitos
2025-02-28 10:41:29 +09:00
parent 7f83894d39
commit 4976e3bdcd
3 changed files with 92 additions and 24 deletions
+1
View File
@@ -45,6 +45,7 @@ int main()
ImGui::InputInt("Samples", (int*)&render.numSamples); ImGui::InputInt("Samples", (int*)&render.numSamples);
if (ImGui::Button("Render")) if (ImGui::Button("Render"))
{ {
std::cout << "Test" << std::endl;
renderer->startRender(camera, render); renderer->startRender(camera, render);
} }
ImGui::Text("Render Stats"); ImGui::Text("Render Stats");
+44
View File
@@ -272,3 +272,47 @@ kernel void computeKernel(
accumulator.write(result, threadId); accumulator.write(result, threadId);
image.write(pow(max(result * resolver, 0), float4(0.45f)), threadId); image.write(pow(max(result * resolver, 0), float4(0.45f)), threadId);
} }
// Screen filling quad in normalized device coordinates.
constant float2 quadVertices[] = {
float2(-1, -1),
float2(-1, 1),
float2( 1, 1),
float2(-1, -1),
float2( 1, 1),
float2( 1, -1)
};
struct CopyVertexOut {
float4 position [[position]];
float2 uv;
};
// Simple vertex shader that passes through NDC quad positions.
vertex CopyVertexOut copyVertex(unsigned short vid [[vertex_id]]) {
float2 position = quadVertices[vid];
CopyVertexOut out;
out.position = float4(position, 0, 1);
out.uv = position * 0.5f + 0.5f;
return out;
}
// Simple fragment shader that copies a texture and applies a simple tonemapping function.
fragment float4 copyFragment(CopyVertexOut in [[stage_in]],
texture2d<float> tex)
{
constexpr sampler sam(min_filter::nearest, mag_filter::nearest, mip_filter::none);
float3 color = tex.sample(sam, in.uv).xyz;
// Apply a simple tonemapping function to reduce the dynamic range of the
// input image into a range which the screen can display.
color = color / (1.0f + color);
return float4(color, 1.0f);
}
+47 -24
View File
@@ -14,6 +14,7 @@ id<CAMetalDrawable> drawable;
id<MTLDevice> device; id<MTLDevice> device;
id<MTLLibrary> library; id<MTLLibrary> library;
id<MTLCommandQueue> queue; id<MTLCommandQueue> queue;
id<MTLCommandQueue> renderQueue;
id<MTLFunction> function; id<MTLFunction> function;
id<MTLComputePipelineState> computePipeline; id<MTLComputePipelineState> computePipeline;
id<MTLTexture> accumulator; id<MTLTexture> accumulator;
@@ -22,15 +23,14 @@ id<MTLTexture> resultTexture;
MTLRenderPassDescriptor* renderPass; MTLRenderPassDescriptor* renderPass;
id<MTLRenderCommandEncoder> renderEncoder; id<MTLRenderCommandEncoder> renderEncoder;
id<MTLCommandBuffer> renderCmd; id<MTLCommandBuffer> renderCmd;
id<MTLRenderPipelineState> pipelineState;
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
MetalRenderer::MetalRenderer() MetalRenderer::MetalRenderer()
{ {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
width = 1920; width = 1920;
height = 1080; height = 1080;
device = MTLCreateSystemDefaultDevice(); device = MTLCreateSystemDefaultDevice();
@@ -38,6 +38,7 @@ MetalRenderer::MetalRenderer()
library = [device newDefaultLibrary]; library = [device newDefaultLibrary];
queue = [device newCommandQueue]; queue = [device newCommandQueue];
renderQueue = [device newCommandQueue];
scene = new MetalScene(device, queue); scene = new MetalScene(device, queue);
@@ -45,32 +46,39 @@ MetalRenderer::MetalRenderer()
NSError* error; NSError* error;
computePipeline = [device newComputePipelineStateWithFunction:function error:&error]; computePipeline = [device newComputePipelineStateWithFunction:function error:&error];
glfwInit(); IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
glfwSetErrorCallback(glfw_error_callback);
glfwInit();
float xscale = 1, yscale = 1; float xscale = 1, yscale = 1;
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale); glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
handle = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr); handle = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr);
int w, h;
glfwGetFramebufferSize(handle, &w, &h);
framebufferWidth = width;
framebufferHeight = height;
ImGui_ImplGlfw_InitForOpenGL(handle, false); ImGui_ImplGlfw_InitForOpenGL(handle, false);
ImGui_ImplMetal_Init((__bridge id)device); ImGui_ImplMetal_Init(device);
NSWindow* cocoaWindow = glfwGetCocoaWindow(handle);
metalLayer = [CAMetalLayer layer]; metalLayer = [CAMetalLayer layer];
metalLayer.device = device; metalLayer.device = device;
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
metalLayer.drawableSize = CGSizeMake(w, h);
metalLayer.framebufferOnly = true;
NSWindow* cocoaWindow = glfwGetCocoaWindow(handle);
[[cocoaWindow contentView] setLayer:metalLayer]; [[cocoaWindow contentView] setLayer:metalLayer];
[[cocoaWindow contentView] setWantsLayer:YES]; [[cocoaWindow contentView] setWantsLayer:true];
[[cocoaWindow contentView] setNeedsLayout:YES];
renderPass = [[MTLRenderPassDescriptor alloc] init]; renderPass = [[MTLRenderPassDescriptor alloc] init];
MTLRenderPipelineDescriptor *renderDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
renderDescriptor.vertexFunction = [library newFunctionWithName:@"copyVertex"];
renderDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"];
renderDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm;
pipelineState = [device newRenderPipelineStateWithDescriptor:renderDescriptor error:&error];
} }
MetalRenderer::~MetalRenderer() {} MetalRenderer::~MetalRenderer() {}
@@ -83,16 +91,28 @@ void MetalRenderer::generate() { scene->generate(); }
void MetalRenderer::beginFrame() void MetalRenderer::beginFrame()
{ {
drawable = [metalLayer nextDrawable]; glfwPollEvents();
renderCmd = [queue commandBuffer]; int w, h;
glfwGetFramebufferSize(handle, &w, &h);
framebufferWidth = width;
framebufferHeight = height;
metalLayer.drawableSize = CGSizeMake(framebufferWidth, framebufferHeight);
drawable = [metalLayer nextDrawable];
renderCmd = [renderQueue commandBuffer];
renderPass.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); renderPass.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0);
renderPass.colorAttachments[0].texture = drawable.texture; renderPass.colorAttachments[0].texture = drawable.texture;
renderPass.colorAttachments[0].loadAction = MTLLoadActionClear; renderPass.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPass.colorAttachments[0].storeAction = MTLStoreActionStore; renderPass.colorAttachments[0].storeAction = MTLStoreActionStore;
renderEncoder = [renderCmd renderCommandEncoderWithDescriptor:renderPass];
ImGui_ImplMetal_NewFrame(renderPass); ImGui_ImplMetal_NewFrame(renderPass);
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
renderEncoder = [renderCmd renderCommandEncoderWithDescriptor:renderPass];
[renderEncoder setRenderPipelineState:pipelineState];
[renderEncoder setFragmentTexture:resultTexture atIndex:0];
// Draw a quad which fills the screen.
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6];
} }
void MetalRenderer::update() void MetalRenderer::update()
@@ -102,6 +122,9 @@ void MetalRenderer::update()
[renderEncoder endEncoding]; [renderEncoder endEncoding];
[renderCmd presentDrawable:drawable]; [renderCmd presentDrawable:drawable];
[renderCmd commit]; [renderCmd commit];
[renderCmd release];
[renderEncoder release];
[drawable release];
} }
void MetalRenderer::render(Camera camera, RenderParameter parameter) void MetalRenderer::render(Camera camera, RenderParameter parameter)
@@ -176,6 +199,6 @@ void MetalRenderer::render(Camera camera, RenderParameter parameter)
[encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup]; [encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup];
[encoder endEncoding]; [encoder endEncoding];
[cmdBuffer commit]; [cmdBuffer commit];
[cmdBuffer waitUntilCompleted]; sampleTimes.push_back(0);
} }
} }