#include "editor_2d.h" #include #include int editor2d_init(Editor2D* e, ID3D11Device* dev) { memset(e, 0, sizeof(*e)); e->shader = shader_create(); if (!shader_compile(e->shader, dev, NULL, NULL, 0, 0)) return 0; D3D11_BUFFER_DESC bd = {0}; bd.ByteWidth = ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert); bd.Usage = D3D11_USAGE_DYNAMIC; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; if (FAILED(dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &e->vb))) return 0; bd.ByteWidth = ED2D_MAX_QUADS * 6 * sizeof(uint32_t); bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; uint32_t* idx = (uint32_t*)malloc(ED2D_MAX_QUADS * 6 * sizeof(uint32_t)); for (int i = 0; i < ED2D_MAX_QUADS; i++) { uint32_t b2 = i * 4; idx[i*6]=b2; idx[i*6+1]=b2+1; idx[i*6+2]=b2+2; idx[i*6+3]=b2; idx[i*6+4]=b2+2; idx[i*6+5]=b2+3; } D3D11_SUBRESOURCE_DATA sd = {0}; sd.pSysMem = idx; dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &e->ib); free(idx); e->verts = (Ed2DVert*)malloc(ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert)); D3D11_BLEND_DESC bdesc = {0}; bdesc.RenderTarget[0].BlendEnable = TRUE; bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; dev->lpVtbl->CreateBlendState(dev, &bdesc, &e->blend); D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; dsdesc.DepthEnable = FALSE; dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &e->ds_no_depth); return 1; } void editor2d_destroy(Editor2D* e) { if (!e) return; if (e->ds_no_depth) e->ds_no_depth->lpVtbl->Release(e->ds_no_depth); if (e->blend) e->blend->lpVtbl->Release(e->blend); if (e->ib) e->ib->lpVtbl->Release(e->ib); if (e->vb) e->vb->lpVtbl->Release(e->vb); shader_destroy(e->shader); free(e->verts); memset(e, 0, sizeof(*e)); } void editor2d_begin(Editor2D* e, float sw, float sh) { e->quad_count = 0; e->screen_w = sw; e->screen_h = sh; memset(e->wvp, 0, sizeof(e->wvp)); e->wvp[0] = 2.0f / sw; e->wvp[5] = -2.0f / sh; e->wvp[12] = -1.0f; e->wvp[13] = 1.0f; e->wvp[15] = 1.0f; } void editor2d_rect(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a) { if (e->quad_count >= ED2D_MAX_QUADS) return; int vi = e->quad_count * 4; e->verts[vi+0] = (Ed2DVert){x, y, 0, 0,0,-1, 0,1, r,g,b,a}; e->verts[vi+1] = (Ed2DVert){x+w, y, 0, 0,0,-1, 1,1, r,g,b,a}; e->verts[vi+2] = (Ed2DVert){x+w, y+h, 0, 0,0,-1, 1,0, r,g,b,a}; e->verts[vi+3] = (Ed2DVert){x, y+h, 0, 0,0,-1, 0,0, r,g,b,a}; e->quad_count++; } void editor2d_rect_border(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a, float t) { editor2d_rect(e, x, y, w, t, r, g, b, a); editor2d_rect(e, x, y+h-t, w, t, r, g, b, a); editor2d_rect(e, x, y, t, h, r, g, b, a); editor2d_rect(e, x+w-t, y, t, h, r, g, b, a); } void editor2d_end(Editor2D* e, ID3D11DeviceContext* ctx) { if (e->quad_count == 0) return; D3D11_MAPPED_SUBRESOURCE mapped; if (FAILED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)e->vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) return; memcpy(mapped.pData, e->verts, (size_t)e->quad_count * 4 * sizeof(Ed2DVert)); ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)e->vb, 0); if (e->rtv) { ctx->lpVtbl->OMSetRenderTargets(ctx, 1, &e->rtv, NULL); } D3D11_VIEWPORT vp = {0}; vp.Width = e->screen_w; vp.Height = e->screen_h; vp.MaxDepth = 1.0f; ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); shader_bind(e->shader, ctx); shader_set_matrix(e->shader, ctx, e->wvp); UINT stride = sizeof(Ed2DVert), offset = 0; ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &e->vb, &stride, &offset); ctx->lpVtbl->IASetIndexBuffer(ctx, e->ib, DXGI_FORMAT_R32_UINT, 0); ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); float bf[4] = {0}; ctx->lpVtbl->OMSetBlendState(ctx, e->blend, bf, 0xFFFFFFFF); ctx->lpVtbl->OMSetDepthStencilState(ctx, e->ds_no_depth, 0); ctx->lpVtbl->DrawIndexed(ctx, (UINT)(e->quad_count * 6), 0, 0); }