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