核心热路径(数学/内存/字符串/性能分析)用MASM汇编(SSE/AVX2) 外围系统(窗口/渲染/ECS/音频/UI/脚本)用C语言 含自研编辑器、VisualScript积木编程、中文渲染(glyph_atlas)
125 lines
4.5 KiB
C
125 lines
4.5 KiB
C
#include "editor_2d.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
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);
|
|
}
|