Something went wrong. Try again.
art software for the rest of us
drawing paint image sdl art
Something went wrong. Try again.
5.0 kB · 122 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123#include "PaintLayerNode.h"#include "../GPU.h"#include <stdexcept>
SDL_GPUSampler* PaintLayerNode::sampler = nullptr;GPUBuffer* PaintLayerNode::vertexBuffer = nullptr;
void PaintLayerNode::setupPipeline(){ // TODO: abstract this too, but not as important as the Graphics plr_pipeline SDL_GPUSamplerCreateInfo samplerInfo = {}; samplerInfo.min_filter = SDL_GPU_FILTER_LINEAR; samplerInfo.mag_filter = SDL_GPU_FILTER_LINEAR; samplerInfo.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR; samplerInfo.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; samplerInfo.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; samplerInfo.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; samplerInfo.mip_lod_bias = 0.0f; samplerInfo.max_anisotropy = 1.0f; samplerInfo.compare_op = SDL_GPU_COMPAREOP_NEVER; samplerInfo.min_lod = 0.0f; samplerInfo.max_lod = 1000.0f;
sampler = SDL_CreateGPUSampler(GPU::GetDevice(), &samplerInfo); if (!sampler) { throw std::runtime_error(SDL_GetError()); }
// diabolical copypaste from CanvasAppLayer float previewVertices[16];
SDL_FRect fullRect = { 0.0f, 0.0f, 1.0f, 1.0f }; SDL_FRect previewRect = { 0.0f, 0.0f, 1.0f, 1.0f };
#define NDC_TO_SCREEN * 2.0f - 1.0f // parameters are using screen space // bottom left previewVertices[0] = (previewRect.x - fullRect.x) / fullRect.w NDC_TO_SCREEN; previewVertices[1] = (previewRect.y - fullRect.y) / fullRect.h NDC_TO_SCREEN; previewVertices[2] = (previewRect.x - fullRect.x) / fullRect.w; // match 0 previewVertices[3] = (previewRect.y - fullRect.y) / fullRect.h; // match 13 // bottom right previewVertices[4] = (previewRect.x + previewRect.w - fullRect.x) / fullRect.w NDC_TO_SCREEN; previewVertices[5] = (previewRect.y - fullRect.y) / fullRect.h NDC_TO_SCREEN; previewVertices[6] = (previewRect.x + previewRect.w - fullRect.x) / fullRect.w; // match 4 previewVertices[7] = (previewRect.y - fullRect.y) / fullRect.h; // match 13 // top left previewVertices[8] = (previewRect.x - fullRect.x) / fullRect.w NDC_TO_SCREEN; previewVertices[9] = (previewRect.y + previewRect.h - fullRect.y) / fullRect.h NDC_TO_SCREEN; previewVertices[10] = (previewRect.x - fullRect.x) / fullRect.w; // match 8 previewVertices[11] = (previewRect.y + previewRect.h - fullRect.y) / fullRect.h; // match 1 // top right previewVertices[12] = (previewRect.x + previewRect.w - fullRect.x) / fullRect.w NDC_TO_SCREEN; previewVertices[13] = (previewRect.y + previewRect.h - fullRect.y) / fullRect.h NDC_TO_SCREEN; previewVertices[14] = (previewRect.x + previewRect.w - fullRect.x) / fullRect.w; // match 12 previewVertices[15] = (previewRect.y + previewRect.h - fullRect.y) / fullRect.h; // match 1
// invert y for (int i = 1; i < 16; i += 4) { previewVertices[i] = -1.0f * previewVertices[i]; }#undef NDC_TO_SCREEN
SDL_GPUBufferCreateInfo buf_info = { .usage = SDL_GPU_BUFFERUSAGE_VERTEX, .size = sizeof(previewVertices), .props = {} }; vertexBuffer = new GPUBuffer(&buf_info); if (!vertexBuffer) { throw std::runtime_error(SDL_GetError()); }
vertexBuffer->Transfer(previewVertices);}
PaintLayerNode::PaintLayerNode() { if (!vertexBuffer) { setupPipeline(); }}
PaintLayerNode::~PaintLayerNode(){ delete Target;}
void PaintLayerNode::Composite(Texture* target){ GPU::AquirePushCommandBuffer(); GraphicsPipeline* pipeline = BlendingPipelineManagementContext::GetPipeline(BlendMode); GPU::SubmitCommandsPopCommandBuffer(); SDL_GPUViewport viewport = {}; viewport.x = 0; viewport.y = 0; viewport.w = (float)target->GetWidth(); viewport.h = (float)target->GetHeight(); SDL_GPUColorTargetInfo colorTarget = {}; colorTarget.texture = target->Get(); colorTarget.clear_color = { 0.0f, 0.0f, 0.0f, 0.0f }; colorTarget.load_op = SDL_GPU_LOADOP_LOAD; colorTarget.store_op = SDL_GPU_STOREOP_STORE; colorTarget.mip_level = 0; colorTarget.layer_or_depth_plane = 0; colorTarget.cycle = false; GPU::AquirePushCommandBuffer(); GPU::BeginRendering({ &colorTarget }, nullptr); SDL_SetGPUViewport(GPU::GetRenderPass(), &viewport); pipeline->Bind(); SDL_GPUBufferBinding vertexBufferBinding = { .buffer = vertexBuffer->Get(), .offset = 0 }; SDL_BindGPUVertexBuffers(GPU::GetRenderPass(), 0, &vertexBufferBinding, 1); SDL_GPUTextureSamplerBinding textureSamplerBinding = { .texture = Target->Get(), .sampler = sampler }; SDL_BindGPUFragmentSamplers(GPU::GetRenderPass(), 0, &textureSamplerBinding, 1); float pushConstants[1] = { (float)Opacity }; SDL_PushGPUFragmentUniformData(GPU::GetCommandBuffer(), 0, pushConstants, sizeof(pushConstants)); SDL_DrawGPUPrimitives(GPU::GetRenderPass(), 4, 1, 0, 0); // draw canvas GPU::EndRendering(); GPU::SubmitCommandsPopCommandBuffer();}