it works somewhat, but not really
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+44
-21
@@ -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);
|
||||||
|
|
||||||
@@ -46,31 +47,38 @@ MetalRenderer::MetalRenderer()
|
|||||||
NSError* error;
|
NSError* error;
|
||||||
computePipeline = [device newComputePipelineStateWithFunction:function error:&error];
|
computePipeline = [device newComputePipelineStateWithFunction:function error:&error];
|
||||||
|
|
||||||
|
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();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user