OBS
+ -

OBS立即顶点坐标vb

2024-05-23 4 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实现。

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!