OBS立即顶点坐标vb
2024-05-23
16
0
顶点坐标通过graphics_init_immediate_vb创建,其存储于graphics_subsystem结构体的immediate_vertbuffer成员指针。
static bool graphics_init_immediate_vb(struct graphics_subsystem *graphics)
{
struct gs_vb_data *vbd;
vbd = gs_vbdata_create();//内请结构体内存空间
vbd->num = IMMEDIATE_COUNT;//512
vbd->points = bmalloc(sizeof(struct vec3) * IMMEDIATE_COUNT);
vbd->normals = bmalloc(sizeof(struct vec3) * IMMEDIATE_COUNT);
vbd->colors = bmalloc(sizeof(uint32_t) * IMMEDIATE_COUNT);
//这里没有切线tangents
vbd->num_tex = 1;
vbd->tvarray = bmalloc(sizeof(struct gs_tvertarray));
vbd->tvarray[0].width = 2;
vbd->tvarray[0].array = bmalloc(sizeof(struct vec2) * IMMEDIATE_COUNT);
graphics->immediate_vertbuffer =graphics->exports.device_vertexbuffer_create(graphics->device, vbd, GS_DYNAMIC);
if (!graphics->immediate_vertbuffer)
return false;
return true;
}
从类型来看其顶点坐标支持:坐标,法线,颜色和一个纹理。
device_vertexbuffer_create函数其实际是创建结构体gs_vertex_buffer
gs_vertbuffer_t *device_vertexbuffer_create(gs_device_t *device,
struct gs_vb_data *data,
uint32_t flags)
{
gs_vertex_buffer buffer = new gs_vertex_buffer(device, data, flags);
retrun buffer;
}
gs_vertex_buffer结构体中使用成员函数BuildBuffers初始化数据
void gs_vertex_buffer::::BuildBuffers()
{
InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->points, &vertexBuffer);
if (vbd.data->normals)
InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->normals, &normalBuffer);
if (vbd.data->tangents)
InitBuffer(sizeof(vec3), vbd.data->num, vbd.data->tangents,&tangentBuffer);
if (vbd.data->colors)
InitBuffer(sizeof(uint32_t), vbd.data->num, vbd.data->colors, &colorBuffer);
for (size_t i = 0; i < vbd.data->num_tex; i++) {
struct gs_tvertarray *tverts = vbd.data->tvarray + i;
if (tverts->width != 2 && tverts->width != 4)
throw "Invalid texture vertex size specified";
if (!tverts->array)
throw "No texture vertices specified";
ComPtr<ID3D11Buffer> buffer;
InitBuffer(tverts->width * sizeof(float), vbd.data->num, tverts->array, &buffer);
uvBuffers.push_back(buffer);
uvSizes.push_back(tverts->width * sizeof(float));
}
}
其中uvBuffers中gs_vertex_buffer的成员变量:
struct gs_vertex_buffer : gs_obj {
ComPtr<ID3D11Buffer> vertexBuffer;
ComPtr<ID3D11Buffer> normalBuffer;
ComPtr<ID3D11Buffer> colorBuffer;
ComPtr<ID3D11Buffer> tangentBuffer;
vector<ComPtr<ID3D11Buffer>> uvBuffers;
bool dynamic;
VBDataPtr vbd;
size_t numVerts;
vector<size_t> uvSizes;
...
}
另外关于buffer的初始化使用函数InitBuffer实现:
void gs_vertex_buffer::InitBuffer(const size_t elementSize,
const size_t numVerts, void *array,
ID3D11Buffer **buffer)
{
D3D11_BUFFER_DESC bd;
D3D11_SUBRESOURCE_DATA srd;
HRESULT hr;
memset(&bd, 0, sizeof(bd));
memset(&srd, 0, sizeof(srd));
bd.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
bd.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.ByteWidth = UINT(elementSize * numVerts);
srd.pSysMem = array;
hr = device->device->CreateBuffer(&bd, &srd, buffer);
if (FAILED(hr))
throw HRError("Failed to create buffer", hr);
}
buffer最终使用ID3D11Device::CreateBuffer实现。