Files
lity3d/Engine/Editor/editor_2d.c
T
shuiyu1123 2d56cb3bc9 MiMoEngine ASM: x86-64 MASM汇编+C混合架构游戏引擎
核心热路径(数学/内存/字符串/性能分析)用MASM汇编(SSE/AVX2)
外围系统(窗口/渲染/ECS/音频/UI/脚本)用C语言
含自研编辑器、VisualScript积木编程、中文渲染(glyph_atlas)
2026-07-10 19:20:40 +08:00

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);
}