.
This commit is contained in:
1 parent
6883d103ff
commit
e43edc67bd
10 files changed
+74
-62
No files matched your search
@@ -39,6 +39,8 @@ void upload_texture(
|
||||
const void *pixels,
|
||||
Texture *texture)
|
||||
{
|
||||
texture->p_texture = new PlatformTexture{};
|
||||
|
||||
MTL::TextureDescriptor *td = MTL::TextureDescriptor::alloc()->init();
|
||||
td->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
||||
td->setWidth(w);
|
||||
@@ -73,13 +75,15 @@ void create_metal_layer(GLFWwindow *window) {
|
||||
SEL setLayerSel = sel_registerName("setLayer:");
|
||||
((void (*)(id, SEL, id))objc_msgSend)(content_view, setLayerSel, (id)metal_layer);
|
||||
|
||||
metal_layer->retain();
|
||||
metal_layer->setDevice(metal_device.device);
|
||||
metal_layer->setPixelFormat(MTL::PixelFormatRGBA16Float);
|
||||
metal_layer->setFramebufferOnly(true);
|
||||
metal_layer->setDrawableSize(CGSizeMake(800, 600));
|
||||
int fb_w, fb_h;
|
||||
glfwGetFramebufferSize(window, &fb_w, &fb_h);
|
||||
metal_layer->setDrawableSize(CGSizeMake(fb_w, fb_h));
|
||||
CGColorSpaceRef p3Space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
metal_layer->setColorspace(p3Space);
|
||||
CGColorSpaceRelease(p3Space);
|
||||
}
|
||||
|
||||
void load_metal_shader(const std::string &shader_path,
|
||||
@@ -201,6 +205,10 @@ void end_frame(GLFWwindow *window) {
|
||||
pPool->release();
|
||||
}
|
||||
|
||||
void submit_quad(glm::vec2 pos, glm::vec2 scale) {
|
||||
renderer.submit_quad({pos.x, pos.y}, {scale.x, scale.y});
|
||||
}
|
||||
|
||||
void submit_sprite(glm::vec2 pos, const sprite_t &sprite) {
|
||||
renderer.submit_sprite({pos.x, pos.y}, sprite);
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#import <GLFW/glfw3native.h>
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
#include <Metal/Metal.hpp>
|
||||
#include <QuartzCore/CAMetalLayer.hpp>
|
||||
|
||||
+37
-49
@@ -65,7 +65,7 @@ void Renderer::submit_quad(simd::float2 pos, simd::float2 scale) {
|
||||
RenderCommand cmd {};
|
||||
cmd.pipeline = PipelineType::ColoredQuad;
|
||||
cmd.key = {
|
||||
(uint16_t) pos.y,
|
||||
(uint16_t) pos[1],
|
||||
0,
|
||||
(uint8_t) PipelineType::ColoredQuad
|
||||
};
|
||||
@@ -83,7 +83,7 @@ void Renderer::submit_sprite(simd::float2 pos, const sprite_t &sprite) {
|
||||
RenderCommand cmd {};
|
||||
cmd.pipeline = PipelineType::TexturedQuad;
|
||||
cmd.key = {
|
||||
(uint16_t) pos.y,
|
||||
(uint16_t) pos[1],
|
||||
0,
|
||||
(uint8_t) PipelineType::TexturedQuad
|
||||
};
|
||||
@@ -247,6 +247,14 @@ void Renderer::create_render_pipeline() {
|
||||
}
|
||||
renderPipelineDescriptor->release();
|
||||
vd->release();
|
||||
vertex_shader->release();
|
||||
fragment_shader->release();
|
||||
|
||||
MTL::SamplerDescriptor *sampler_desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
sampler_desc->setMinFilter(MTL::SamplerMinMagFilterLinear);
|
||||
sampler_desc->setMagFilter(MTL::SamplerMinMagFilterLinear);
|
||||
sampler_state = metal_device.device->newSamplerState(sampler_desc);
|
||||
sampler_desc->release();
|
||||
}
|
||||
|
||||
float4x4 make_ortho(float left, float right, float bottom, float top, float near, float far) {
|
||||
@@ -267,46 +275,34 @@ float4x4 make_ortho(float left, float right, float bottom, float top, float near
|
||||
}
|
||||
|
||||
void Renderer::encode_render_command(GLFWwindow *window, MTL::RenderCommandEncoder *render_command_encoder) {
|
||||
struct DrawGroup {
|
||||
MTL::Texture *texture;
|
||||
NS::UInteger vertex_start;
|
||||
NS::UInteger vertex_count;
|
||||
};
|
||||
|
||||
std::vector<vertex_p2_s2_uv2_c4_a1> vertices;
|
||||
std::vector<DrawGroup> groups;
|
||||
|
||||
for (auto& cmd : commands) {
|
||||
|
||||
switch (cmd.pipeline) {
|
||||
case PipelineType::ColoredQuad: {
|
||||
const auto &q = cmd.colored_quad;
|
||||
|
||||
vertex_p2_s2_uv2_c4_a1 vTL = { q.pos, q.scale, {}, q.colour };
|
||||
vertex_p2_s2_uv2_c4_a1 vTR = { q.pos, q.scale, {}, q.colour };
|
||||
vertex_p2_s2_uv2_c4_a1 vBL = { q.pos, q.scale, {}, q.colour };
|
||||
vertex_p2_s2_uv2_c4_a1 vBR = { q.pos, q.scale, {}, q.colour };
|
||||
|
||||
vertices.push_back(vTL);
|
||||
vertices.push_back(vBL);
|
||||
vertices.push_back(vTR);
|
||||
|
||||
vertices.push_back(vTR);
|
||||
vertices.push_back(vBL);
|
||||
vertices.push_back(vBR);
|
||||
|
||||
break;
|
||||
}
|
||||
case PipelineType::TexturedQuad: {
|
||||
const auto &q = cmd.textured_quad;
|
||||
if (!q.texture) break;
|
||||
|
||||
vertex_p2_s2_uv2_c4_a1 vTL = { q.pos, q.scale, q.uv0, q.colour, 1.0 };
|
||||
vertex_p2_s2_uv2_c4_a1 vTR = { q.pos, q.scale, {q.uv1.x, q.uv0.y}, q.colour, 1.0 };
|
||||
vertex_p2_s2_uv2_c4_a1 vBL = { q.pos, q.scale, {q.uv0.x, q.uv1.y}, q.colour, 1.0 };
|
||||
vertex_p2_s2_uv2_c4_a1 vBR = { q.pos, q.scale, q.uv1, q.colour, 1.0};
|
||||
if (groups.empty() || groups.back().texture != q.texture)
|
||||
groups.push_back({q.texture, (NS::UInteger)vertices.size(), 0});
|
||||
|
||||
vertices.push_back(vTL);
|
||||
vertices.push_back(vBL);
|
||||
vertices.push_back(vTR);
|
||||
|
||||
vertices.push_back(vTR);
|
||||
vertices.push_back(vBL);
|
||||
vertices.push_back(vBR);
|
||||
simd::float2 uv_tr = {q.uv1[0], q.uv0[1]};
|
||||
simd::float2 uv_bl = {q.uv0[0], q.uv1[1]};
|
||||
|
||||
vertices.push_back({ q.pos, q.scale, q.uv0, q.colour, 1.0f });
|
||||
vertices.push_back({ q.pos, q.scale, uv_bl, q.colour, 1.0f });
|
||||
vertices.push_back({ q.pos, q.scale, uv_tr, q.colour, 1.0f });
|
||||
vertices.push_back({ q.pos, q.scale, uv_tr, q.colour, 1.0f });
|
||||
vertices.push_back({ q.pos, q.scale, uv_bl, q.colour, 1.0f });
|
||||
vertices.push_back({ q.pos, q.scale, q.uv1, q.colour, 1.0f });
|
||||
groups.back().vertex_count += 6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -314,33 +310,26 @@ void Renderer::encode_render_command(GLFWwindow *window, MTL::RenderCommandEncod
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices.empty()) return;
|
||||
|
||||
const Frame &frame = frames[current_frame];
|
||||
|
||||
memcpy(frame.vertex_buffer->contents(), vertices.data(), vertices.size() * sizeof(vertex_p2_s2_uv2_c4_a1));
|
||||
|
||||
MTL::SamplerDescriptor* sampler_desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
|
||||
sampler_desc->setMinFilter(MTL::SamplerMinMagFilterLinear);
|
||||
sampler_desc->setMagFilter(MTL::SamplerMinMagFilterLinear);
|
||||
MTL::SamplerState* sampler = metal_device.device->newSamplerState(sampler_desc);
|
||||
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
simd::float4x4 ortho = make_ortho(0.0, window_width, window_height, 0.0, 1.0, 0.0);
|
||||
simd::float4x4 ortho = make_ortho(0.0f, (float)width, (float)height, 0.0f, 1.0f, 0.0f);
|
||||
auto tm = simd::transpose(ortho);
|
||||
memcpy(frame.uniform_buffer->contents(), &tm, sizeof(ortho));
|
||||
|
||||
render_command_encoder->setRenderPipelineState(textured_quad_pipeline);
|
||||
render_command_encoder->setVertexBuffer(frame.vertex_buffer, 0, 0);
|
||||
render_command_encoder->setVertexBuffer(frame.uniform_buffer, 0, 1);
|
||||
render_command_encoder->setFragmentSamplerState(sampler, 0);
|
||||
MTL::PrimitiveType type_triangle = MTL::PrimitiveTypeTriangle;
|
||||
NS::UInteger vertexStart = 0;
|
||||
NS::UInteger vertexCount = vertices.size();
|
||||
const Texture &texture = texture_manager.textures["assets/boy.png"];
|
||||
render_command_encoder->setFragmentTexture(texture.p_texture->texture, 0);
|
||||
render_command_encoder->drawPrimitives(type_triangle, vertexStart, vertexCount);
|
||||
render_command_encoder->setFragmentSamplerState(sampler_state, 0);
|
||||
|
||||
sampler_desc->release();
|
||||
for (const auto &group : groups) {
|
||||
render_command_encoder->setFragmentTexture(group.texture, 0);
|
||||
render_command_encoder->drawPrimitives(MTL::PrimitiveTypeTriangle, group.vertex_start, group.vertex_count);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::send_render_command(GLFWwindow *window) {
|
||||
@@ -371,7 +360,6 @@ void Renderer::send_render_command(GLFWwindow *window) {
|
||||
|
||||
command_buffer->presentDrawable(metal_drawable);
|
||||
command_buffer->commit();
|
||||
command_buffer->waitUntilCompleted();
|
||||
|
||||
current_frame = (current_frame + 1) % kMaxFramesInFlight;
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ struct Renderer {
|
||||
|
||||
uint32_t nextTextureSlot = 0;
|
||||
|
||||
MTL::SamplerState *sampler_state{};
|
||||
MTL::CommandBuffer *command_buffer{};
|
||||
|
||||
struct Frame {
|
||||
|
||||
Reference in new issue
Block a user