Files
lity3d/Engine/Rendering/mesh.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

111 lines
4.6 KiB
C

#include "mesh.h"
#include <stdlib.h>
#include <math.h>
#ifndef MATH_ASM_AVAILABLE
#include "../ASM/math_c_fallback.h"
#endif
#define POS(n,x,y,z,nx,ny,nz,u,v,r,g,b,a) {x,y,z, nx,ny,nz, u,v, r,g,b,a}
static Mesh* create_mesh(ID3D11Device* dev, const void* verts, uint32_t vc, const uint32_t* idx, uint32_t ic, uint32_t stride) {
Mesh* m = (Mesh*)calloc(1, sizeof(Mesh));
m->stride = stride; m->vcount = vc; m->icount = ic;
D3D11_BUFFER_DESC bd = {0};
D3D11_SUBRESOURCE_DATA sd = {0};
bd.ByteWidth = stride * vc; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
sd.pSysMem = verts;
dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->vb);
if (idx && ic > 0) {
bd.ByteWidth = sizeof(uint32_t) * ic; bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
sd.pSysMem = idx;
dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->ib);
}
return m;
}
void mesh_destroy(Mesh* m) {
if (!m) return;
if (m->ib) m->ib->lpVtbl->Release(m->ib);
if (m->vb) m->vb->lpVtbl->Release(m->vb);
free(m);
}
void mesh_draw(Mesh* m, ID3D11DeviceContext* ctx) {
UINT stride = m->stride, offset = 0;
ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &m->vb, &stride, &offset);
if (m->ib) {
ctx->lpVtbl->IASetIndexBuffer(ctx, m->ib, DXGI_FORMAT_R32_UINT, 0);
ctx->lpVtbl->DrawIndexed(ctx, m->icount, 0, 0);
} else {
ctx->lpVtbl->Draw(ctx, m->vcount, 0);
}
}
Mesh* mesh_create_cube(ID3D11Device* dev) {
typedef struct { float p[3], n[3], uv[2], c[4]; } V;
V v[24] = {
POS(0,-.5f,-.5f,-.5f, 0,0,-1, 0,1, 1,1,1,1), POS(1, .5f,-.5f,-.5f, 0,0,-1, 1,1, 1,1,1,1),
POS(2, .5f, .5f,-.5f, 0,0,-1, 1,0, 1,1,1,1), POS(3,-.5f, .5f,-.5f, 0,0,-1, 0,0, 1,1,1,1),
POS(4, .5f,-.5f, .5f, 0,0, 1, 0,1, 1,1,1,1), POS(5,-.5f,-.5f, .5f, 0,0, 1, 1,1, 1,1,1,1),
POS(6,-.5f, .5f, .5f, 0,0, 1, 1,0, 1,1,1,1), POS(7, .5f, .5f, .5f, 0,0, 1, 0,0, 1,1,1,1),
POS(8,-.5f, .5f,-.5f, 0,1, 0, 0,1, 1,1,1,1), POS(9, .5f, .5f,-.5f, 0,1, 0, 1,1, 1,1,1,1),
POS(10,.5f, .5f, .5f, 0,1, 0, 1,0, 1,1,1,1), POS(11,-.5f, .5f, .5f, 0,1, 0, 0,0, 1,1,1,1),
POS(12,-.5f,-.5f, .5f, 0,-1,0, 0,1, 1,1,1,1), POS(13,.5f,-.5f, .5f, 0,-1,0, 1,1, 1,1,1,1),
POS(14,.5f,-.5f,-.5f, 0,-1,0, 1,0, 1,1,1,1), POS(15,-.5f,-.5f,-.5f, 0,-1,0, 0,0, 1,1,1,1),
POS(16,.5f,-.5f,-.5f, 1,0, 0, 0,1, 1,1,1,1), POS(17,.5f,-.5f, .5f, 1,0, 0, 1,1, 1,1,1,1),
POS(18,.5f, .5f, .5f, 1,0, 0, 1,0, 1,1,1,1), POS(19,.5f, .5f,-.5f, 1,0, 0, 0,0, 1,1,1,1),
POS(20,-.5f,-.5f, .5f, -1,0,0, 0,1, 1,1,1,1), POS(21,-.5f,-.5f,-.5f, -1,0,0, 1,1, 1,1,1,1),
POS(22,-.5f, .5f,-.5f, -1,0,0, 1,0, 1,1,1,1), POS(23,-.5f, .5f, .5f, -1,0,0, 0,0, 1,1,1,1),
};
uint32_t idx[36];
for (int i = 0; i < 6; i++) { int b = i*4; idx[i*6]=b; idx[i*6+1]=b+1; idx[i*6+2]=b+2; idx[i*6+3]=b; idx[i*6+4]=b+2; idx[i*6+5]=b+3; }
return create_mesh(dev, v, 24, idx, 36, sizeof(V));
}
Mesh* mesh_create_plane(ID3D11Device* dev, float size) {
typedef struct { float p[3], n[3], uv[2], c[4]; } V;
float h = size * 0.5f;
V v[4] = {
{{-h,0,h},{0,1,0},{0,1},{1,1,1,1}},
{{ h,0,h},{0,1,0},{1,1},{1,1,1,1}},
{{ h,0,-h},{0,1,0},{1,0},{1,1,1,1}},
{{-h,0,-h},{0,1,0},{0,0},{1,1,1,1}},
};
uint32_t idx[6] = {0,1,2,0,2,3};
return create_mesh(dev, v, 4, idx, 6, sizeof(V));
}
Mesh* mesh_create_sphere(ID3D11Device* dev, float r, int seg) {
typedef struct { float p[3], n[3], uv[2], c[4]; } V;
int vc = (seg+1)*(seg+1);
V* v = (V*)malloc(vc * sizeof(V));
int vi = 0;
for (int lat = 0; lat <= seg; lat++) {
float theta = 3.14159265f * lat / seg;
float st = sinf(theta), ct = cosf(theta);
for (int lon = 0; lon <= seg; lon++) {
float phi = 2.0f * 3.14159265f * lon / seg;
float sp = sinf(phi), cp = cosf(phi);
float nx = cp*st, ny = ct, nz = sp*st;
v[vi].p[0] = nx*r; v[vi].p[1] = ny*r; v[vi].p[2] = nz*r;
v[vi].n[0] = nx; v[vi].n[1] = ny; v[vi].n[2] = nz;
v[vi].uv[0] = (float)lon/seg; v[vi].uv[1] = (float)lat/seg;
v[vi].c[0]=1; v[vi].c[1]=1; v[vi].c[2]=1; v[vi].c[3]=1;
vi++;
}
}
int ic = seg*seg*6;
uint32_t* idx = (uint32_t*)malloc(ic * sizeof(uint32_t));
int ii = 0;
for (int lat = 0; lat < seg; lat++) {
for (int lon = 0; lon < seg; lon++) {
uint32_t f = lat*(seg+1)+lon, s = f+seg+1;
idx[ii++]=f; idx[ii++]=s; idx[ii++]=f+1;
idx[ii++]=s; idx[ii++]=s+1; idx[ii++]=f+1;
}
}
Mesh* m = create_mesh(dev, v, vc, idx, ic, sizeof(V));
free(v); free(idx);
return m;
}