51 if (!strcmp(
"Renderer.frag.dxil", name)) {
52 data = $(alloc(Data), initWithConstMemory, Renderer_frag_dxil, Renderer_frag_dxil_len);
53 }
else if (!strcmp(
"Renderer.frag.metal", name)) {
54 data = $(alloc(Data), initWithConstMemory, Renderer_frag_metal, Renderer_frag_metal_len);
55 }
else if (!strcmp(
"Renderer.frag.spv", name)) {
56 data = $(alloc(Data), initWithConstMemory, Renderer_frag_spv, Renderer_frag_spv_len);
57 }
else if (!strcmp(
"Renderer.vert.dxil", name)) {
58 data = $(alloc(Data), initWithConstMemory, Renderer_vert_dxil, Renderer_vert_dxil_len);
59 }
else if (!strcmp(
"Renderer.vert.metal", name)) {
60 data = $(alloc(Data), initWithConstMemory, Renderer_vert_metal, Renderer_vert_metal_len);
61 }
else if (!strcmp(
"Renderer.vert.spv", name)) {
62 data = $(alloc(Data), initWithConstMemory, Renderer_vert_spv, Renderer_vert_spv_len);
137static void drawLines(
const Renderer *self,
const SDL_Point *points,
size_t count,
const SDL_Color *color) {
146 const size_t segCount = count - 1;
150 for (
size_t i = 0; i < segCount; i++) {
151 const float ax = (float) points[i].x, ay = (
float) points[i].y;
152 const float bx = (float) points[i+1].x, by = (
float) points[i+1].y;
154 const float dx = bx - ax, dy = by - ay;
155 const float len = sqrtf(dx * dx + dy * dy);
157 float nx = 0.0f, ny = 0.0f;
159 nx = (-dy / len) * 0.5f;
160 ny = ( dx / len) * 0.5f;
164 v[0] = (
MVC_Vertex) { { { ax - nx, ay - ny } }, { { 0.0f, 0.0f } }, { 0 } };
165 v[1] = (
MVC_Vertex) { { { ax + nx, ay + ny } }, { { 0.0f, 0.0f } }, { 0 } };
166 v[2] = (
MVC_Vertex) { { { bx - nx, by - ny } }, { { 0.0f, 0.0f } }, { 0 } };
167 v[3] = (
MVC_Vertex) { { { ax + nx, ay + ny } }, { { 0.0f, 0.0f } }, { 0 } };
168 v[4] = (
MVC_Vertex) { { { bx + nx, by + ny } }, { { 0.0f, 0.0f } }, { 0 } };
169 v[5] = (
MVC_Vertex) { { { bx - nx, by - ny } }, { { 0.0f, 0.0f } }, { 0 } };
204 const float x1 = (float) rect->x, y1 = (
float) rect->y;
205 const float x2 = (float) rect->x + rect->w, y2 = (
float) rect->y + rect->h;
208 { { { x1, y1 } }, { { 0.0f, 0.0f } }, { 0 } },
209 { { { x2, y1 } }, { { 0.0f, 0.0f } }, { 0 } },
210 { { { x1, y2 } }, { { 0.0f, 0.0f } }, { 0 } },
211 { { { x2, y1 } }, { { 0.0f, 0.0f } }, { 0 } },
212 { { { x2, y2 } }, { { 0.0f, 0.0f } }, { 0 } },
213 { { { x1, y2 } }, { { 0.0f, 0.0f } }, { 0 } },
223static void drawTexture(
const Renderer *self, Texture *texture,
const SDL_Rect *rect,
const SDL_Color *color) {
227 const float x1 = (float) rect->x, y1 = (
float) rect->y;
228 const float x2 = (float) rect->x + rect->w, y2 = (
float) rect->y + rect->h;
231 { { { x1, y1 } }, { { 0.0f, 0.0f } }, { 0 } },
232 { { { x2, y1 } }, { { 1.0f, 0.0f } }, { 0 } },
233 { { { x1, y2 } }, { { 0.0f, 1.0f } }, { 0 } },
234 { { { x2, y1 } }, { { 1.0f, 0.0f } }, { 0 } },
235 { { { x2, y2 } }, { { 1.0f, 1.0f } }, { 0 } },
236 { { { x1, y2 } }, { { 0.0f, 1.0f } }, { 0 } },
263 Framebuffer *framebuffer = self->framebuffer;
266 const SDL_GPUColorTargetInfo colorTarget = $(framebuffer, colorTargetInfo, 0, SDL_GPU_LOADOP_LOAD, SDL_GPU_STOREOP_STORE);
268 const size_t vertexCount = self->vertices->count;
270 CopyPass *copyPass = $(self->commands, beginCopyPass);
272 if (vertexCount > 0) {
273 const Uint32 vertexSize = (Uint32) (vertexCount *
sizeof(
MVC_Vertex));
275 if (vertexCount > self->vertexBufferCapacity) {
276 release(self->vertexBuffer);
277 self->vertexBuffer = $(self->
device, createBuffer, &(SDL_GPUBufferCreateInfo) {
278 .usage = SDL_GPU_BUFFERUSAGE_VERTEX,
282 release(self->transferBuffer);
283 self->transferBuffer = $(self->
device, createTransferBuffer, &(SDL_GPUTransferBufferCreateInfo) {
284 .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
288 self->vertexBufferCapacity = (Uint32) vertexCount;
291 $(self->transferBuffer, write, self->vertices->elements, vertexSize,
true);
293 $(copyPass, uploadBuffer,
294 &(SDL_GPUTransferBufferLocation) { .transfer_buffer = self->transferBuffer->buffer },
295 &(SDL_GPUBufferRegion) { .buffer = self->vertexBuffer->buffer, .size = vertexSize },
301 RenderPass *renderPass = $(self->commands, beginRenderPass, &colorTarget, 1, NULL);
303 $(renderPass, setViewport, &(SDL_GPUViewport){
304 .x = 0.0f, .y = 0.0f,
305 .w = (float) framebuffer->size.w, .h = (
float) framebuffer->size.h,
306 .min_depth = 0.0f, .max_depth = 1.0f,
310 SDL_GetWindowSize(self->
device->window, &winW, &winH);
311 const mat4 projection = mat4_ortho(0.f, (
float) winW, (
float) winH, 0.f, -1.f, 1.f);
312 $(self->commands, pushVertexUniformData, 0, projection.f,
sizeof(projection));
314 $(renderPass, bindPipeline, self->pipeline);
315 $(renderPass, bindVertexBuffers, 0, &(SDL_GPUBufferBinding) { .buffer = self->vertexBuffer->buffer }, 1);
317 for (
size_t i = 0; i < self->drawArrays->count; i++) {
318 const MVC_DrawArrays *
draw = VectorElement(self->drawArrays, MVC_DrawArrays, i);
320 $(renderPass, setScissor, &
draw->scissor);
322 $(renderPass, bindFragmentSamplers, 0, &(SDL_GPUTextureSamplerBinding) {
323 .texture =
draw->texture->texture, .sampler = self->sampler->sampler,
326 $(renderPass, drawPrimitives,
draw->vertexCount, 1,
draw->firstVertex, 0);
331 self->commands = NULL;
332 self->framebuffer = NULL;
387 Shader *vertexShader = $(self->
device, loadShader,
"Renderer.vert", &(SDL_GPUShaderCreateInfo) {
388 .stage = SDL_GPU_SHADERSTAGE_VERTEX,
389 .num_uniform_buffers = 1,
392 Shader *fragmentShader = $(self->
device, loadShader,
"Renderer.frag", &(SDL_GPUShaderCreateInfo) {
393 .stage = SDL_GPU_SHADERSTAGE_FRAGMENT,
397 const SDL_GPUVertexBufferDescription vertexBufferInfo = {
400 .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX,
401 .instance_step_rate = 0,
404 const SDL_GPUColorTargetDescription colorTarget = {
405 .format = $(self->
device, getSwapchainTextureFormat),
407 .enable_blend =
true,
408 .color_blend_op = SDL_GPU_BLENDOP_ADD,
409 .alpha_blend_op = SDL_GPU_BLENDOP_ADD,
410 .src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA,
411 .dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
412 .src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE,
413 .dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
417 const SDL_GPUGraphicsPipelineCreateInfo pipelineInfo = {
418 .vertex_shader = vertexShader->shader,
419 .fragment_shader = fragmentShader->shader,
420 .vertex_input_state = {
421 .vertex_buffer_descriptions = &vertexBufferInfo,
422 .num_vertex_buffers = 1,
423 .vertex_attributes = (SDL_GPUVertexAttribute[]) {
427 .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
433 .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2,
439 .format = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM,
443 .num_vertex_attributes = 3,
445 .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST,
446 .rasterizer_state = {
447 .fill_mode = SDL_GPU_FILLMODE_FILL,
448 .cull_mode = SDL_GPU_CULLMODE_NONE,
449 .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
452 .color_target_descriptions = &colorTarget,
453 .num_color_targets = 1,
457 self->pipeline = $(self->
device, createGraphicsPipeline, &pipelineInfo);
459 release(vertexShader);
460 release(fragmentShader);
462 self->sampler = $(self->
device, createSampler, &(
const SDL_GPUSamplerCreateInfo) {
463 .min_filter = SDL_GPU_FILTER_LINEAR,
464 .mag_filter = SDL_GPU_FILTER_LINEAR,
465 .mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR,
466 .address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
467 .address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
468 .address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
471 const Uint8 white[4] = { 255, 255, 255, 255 };
473 self->white = $(self->
device, createTexture, &(
const SDL_GPUTextureCreateInfo) {
474 .type = SDL_GPU_TEXTURETYPE_2D,
475 .format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
476 .usage = SDL_GPU_TEXTUREUSAGE_SAMPLER,
479 .layer_count_or_depth = 1,
525 ((ObjectInterface *) clazz->interface)->dealloc =
dealloc;
527 ((RendererInterface *) clazz->interface)->beginFrame =
beginFrame;
528 ((RendererInterface *) clazz->interface)->beginFrameWith =
beginFrameWith;
529 ((RendererInterface *) clazz->interface)->drawLine =
drawLine;
530 ((RendererInterface *) clazz->interface)->drawLines =
drawLines;
531 ((RendererInterface *) clazz->interface)->drawRect =
drawRect;
532 ((RendererInterface *) clazz->interface)->drawRectFilled =
drawRectFilled;
533 ((RendererInterface *) clazz->interface)->drawTexture =
drawTexture;
534 ((RendererInterface *) clazz->interface)->drawView =
drawView;
535 ((RendererInterface *) clazz->interface)->endFrame =
endFrame;
536 ((RendererInterface *) clazz->interface)->initWithDevice =
initWithDevice;
540 ((RendererInterface *) clazz->interface)->setClippingFrame =
setClippingFrame;