#include "mesh.h" #include #include #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; }