libobs: Add vertex/index buffer "direct" flush functions
(Note: This commit also modifies libobs-d3d11 and libobs-opengl) Allows the ability to flush data directly without having to use the buffer's internal data. Allows the caller to manage his/her own vertex/index buffer data if desired, working around the design flaw of having to rely on a vertex/index buffer's internal data.
This commit is contained in:
parent
a46f0b4808
commit
c111fa68b8
@ -1938,36 +1938,53 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer)
|
|||||||
delete vertbuffer;
|
delete vertbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer)
|
static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vertbuffer,
|
||||||
|
const gs_vb_data *data)
|
||||||
{
|
{
|
||||||
|
size_t num_tex = data->num_tex < vertbuffer->uvBuffers.size()
|
||||||
|
? data->num_tex
|
||||||
|
: vertbuffer->uvBuffers.size();
|
||||||
|
|
||||||
if (!vertbuffer->dynamic) {
|
if (!vertbuffer->dynamic) {
|
||||||
blog(LOG_ERROR, "gs_vertexbuffer_flush: vertex buffer is "
|
blog(LOG_ERROR, "gs_vertexbuffer_flush: vertex buffer is "
|
||||||
"not dynamic");
|
"not dynamic");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertbuffer->FlushBuffer(vertbuffer->vertexBuffer,
|
if (data->points)
|
||||||
vertbuffer->vbd.data->points, sizeof(vec3));
|
vertbuffer->FlushBuffer(vertbuffer->vertexBuffer,
|
||||||
|
data->points, sizeof(vec3));
|
||||||
|
|
||||||
if (vertbuffer->normalBuffer)
|
if (vertbuffer->normalBuffer && data->normals)
|
||||||
vertbuffer->FlushBuffer(vertbuffer->normalBuffer,
|
vertbuffer->FlushBuffer(vertbuffer->normalBuffer,
|
||||||
vertbuffer->vbd.data->normals, sizeof(vec3));
|
data->normals, sizeof(vec3));
|
||||||
|
|
||||||
if (vertbuffer->tangentBuffer)
|
if (vertbuffer->tangentBuffer && data->tangents)
|
||||||
vertbuffer->FlushBuffer(vertbuffer->tangentBuffer,
|
vertbuffer->FlushBuffer(vertbuffer->tangentBuffer,
|
||||||
vertbuffer->vbd.data->tangents, sizeof(vec3));
|
data->tangents, sizeof(vec3));
|
||||||
|
|
||||||
if (vertbuffer->colorBuffer)
|
if (vertbuffer->colorBuffer && data->colors)
|
||||||
vertbuffer->FlushBuffer(vertbuffer->colorBuffer,
|
vertbuffer->FlushBuffer(vertbuffer->colorBuffer,
|
||||||
vertbuffer->vbd.data->colors, sizeof(uint32_t));
|
data->colors, sizeof(uint32_t));
|
||||||
|
|
||||||
for (size_t i = 0; i < vertbuffer->uvBuffers.size(); i++) {
|
for (size_t i = 0; i < num_tex; i++) {
|
||||||
gs_tvertarray &tv = vertbuffer->vbd.data->tvarray[i];
|
gs_tvertarray &tv = data->tvarray[i];
|
||||||
vertbuffer->FlushBuffer(vertbuffer->uvBuffers[i],
|
vertbuffer->FlushBuffer(vertbuffer->uvBuffers[i],
|
||||||
tv.array, tv.width*sizeof(float));
|
tv.array, tv.width*sizeof(float));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer)
|
||||||
|
{
|
||||||
|
gs_vertexbuffer_flush_internal(vertbuffer, vertbuffer->vbd.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer,
|
||||||
|
const gs_vb_data *data)
|
||||||
|
{
|
||||||
|
gs_vertexbuffer_flush_internal(vertbuffer, data);
|
||||||
|
}
|
||||||
|
|
||||||
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer)
|
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer)
|
||||||
{
|
{
|
||||||
return vertbuffer->vbd.data;
|
return vertbuffer->vbd.data;
|
||||||
@ -1979,7 +1996,8 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer)
|
|||||||
delete indexbuffer;
|
delete indexbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer)
|
static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *indexbuffer,
|
||||||
|
const void *data)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
@ -1992,12 +2010,22 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer)
|
|||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(map.pData, indexbuffer->indices.data,
|
memcpy(map.pData, data, indexbuffer->num * indexbuffer->indexSize);
|
||||||
indexbuffer->num * indexbuffer->indexSize);
|
|
||||||
|
|
||||||
indexbuffer->device->context->Unmap(indexbuffer->indexBuffer, 0);
|
indexbuffer->device->context->Unmap(indexbuffer->indexBuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer)
|
||||||
|
{
|
||||||
|
gs_indexbuffer_flush_internal(indexbuffer, indexbuffer->indices.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
gs_indexbuffer_flush_internal(indexbuffer, data);
|
||||||
|
}
|
||||||
|
|
||||||
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer)
|
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer)
|
||||||
{
|
{
|
||||||
return indexbuffer->indices.data;
|
return indexbuffer->indices.data;
|
||||||
|
@ -70,15 +70,15 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *ib)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs_indexbuffer_flush(gs_indexbuffer_t *ib)
|
static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *ib,
|
||||||
|
const void *data)
|
||||||
{
|
{
|
||||||
if (!ib->dynamic) {
|
if (!ib->dynamic) {
|
||||||
blog(LOG_ERROR, "Index buffer is not dynamic");
|
blog(LOG_ERROR, "Index buffer is not dynamic");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!update_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer, ib->data,
|
if (!update_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer, data, ib->size))
|
||||||
ib->size))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -87,6 +87,16 @@ fail:
|
|||||||
blog(LOG_ERROR, "gs_indexbuffer_flush (GL) failed");
|
blog(LOG_ERROR, "gs_indexbuffer_flush (GL) failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_indexbuffer_flush(gs_indexbuffer_t *ib)
|
||||||
|
{
|
||||||
|
gs_indexbuffer_flush_internal(ib, ib->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gs_indexbuffer_flush_direct(gs_indexbuffer_t *ib, const void *data)
|
||||||
|
{
|
||||||
|
gs_indexbuffer_flush_internal(ib, data);
|
||||||
|
}
|
||||||
|
|
||||||
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *ib)
|
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *ib)
|
||||||
{
|
{
|
||||||
return ib->data;
|
return ib->data;
|
||||||
|
@ -120,45 +120,51 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs_vertexbuffer_flush(gs_vertbuffer_t *vb)
|
static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vb,
|
||||||
|
const struct gs_vb_data *data)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t num_tex = data->num_tex < vb->data->num_tex
|
||||||
|
? data->num_tex
|
||||||
|
: vb->data->num_tex;
|
||||||
|
|
||||||
if (!vb->dynamic) {
|
if (!vb->dynamic) {
|
||||||
blog(LOG_ERROR, "vertex buffer is not dynamic");
|
blog(LOG_ERROR, "vertex buffer is not dynamic");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!update_buffer(GL_ARRAY_BUFFER, vb->vertex_buffer,
|
if (data->points) {
|
||||||
vb->data->points,
|
if (!update_buffer(GL_ARRAY_BUFFER, vb->vertex_buffer,
|
||||||
vb->data->num * sizeof(struct vec3)))
|
data->points,
|
||||||
goto failed;
|
data->num * sizeof(struct vec3)))
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (vb->normal_buffer) {
|
if (vb->normal_buffer && data->normals) {
|
||||||
if (!update_buffer(GL_ARRAY_BUFFER, vb->normal_buffer,
|
if (!update_buffer(GL_ARRAY_BUFFER, vb->normal_buffer,
|
||||||
vb->data->normals,
|
data->normals,
|
||||||
vb->data->num * sizeof(struct vec3)))
|
data->num * sizeof(struct vec3)))
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vb->tangent_buffer) {
|
if (vb->tangent_buffer && data->tangents) {
|
||||||
if (!update_buffer(GL_ARRAY_BUFFER, vb->tangent_buffer,
|
if (!update_buffer(GL_ARRAY_BUFFER, vb->tangent_buffer,
|
||||||
vb->data->tangents,
|
data->tangents,
|
||||||
vb->data->num * sizeof(struct vec3)))
|
data->num * sizeof(struct vec3)))
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vb->color_buffer) {
|
if (vb->color_buffer && data->colors) {
|
||||||
if (!update_buffer(GL_ARRAY_BUFFER, vb->color_buffer,
|
if (!update_buffer(GL_ARRAY_BUFFER, vb->color_buffer,
|
||||||
vb->data->colors,
|
data->colors,
|
||||||
vb->data->num * sizeof(uint32_t)))
|
data->num * sizeof(uint32_t)))
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < vb->data->num_tex; i++) {
|
for (i = 0; i < num_tex; i++) {
|
||||||
GLuint buffer = vb->uv_buffers.array[i];
|
GLuint buffer = vb->uv_buffers.array[i];
|
||||||
struct gs_tvertarray *tv = vb->data->tvarray+i;
|
struct gs_tvertarray *tv = data->tvarray+i;
|
||||||
size_t size = vb->data->num * tv->width * sizeof(float);
|
size_t size = data->num * tv->width * sizeof(float);
|
||||||
|
|
||||||
if (!update_buffer(GL_ARRAY_BUFFER, buffer, tv->array, size))
|
if (!update_buffer(GL_ARRAY_BUFFER, buffer, tv->array, size))
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -170,6 +176,17 @@ failed:
|
|||||||
blog(LOG_ERROR, "gs_vertexbuffer_flush (GL) failed");
|
blog(LOG_ERROR, "gs_vertexbuffer_flush (GL) failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_vertexbuffer_flush(gs_vertbuffer_t *vb)
|
||||||
|
{
|
||||||
|
gs_vertexbuffer_flush_internal(vb, vb->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vb,
|
||||||
|
const struct gs_vb_data *data)
|
||||||
|
{
|
||||||
|
gs_vertexbuffer_flush_internal(vb, data);
|
||||||
|
}
|
||||||
|
|
||||||
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vb)
|
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vb)
|
||||||
{
|
{
|
||||||
return vb->data;
|
return vb->data;
|
||||||
|
@ -141,10 +141,12 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||||||
|
|
||||||
GRAPHICS_IMPORT(gs_vertexbuffer_destroy);
|
GRAPHICS_IMPORT(gs_vertexbuffer_destroy);
|
||||||
GRAPHICS_IMPORT(gs_vertexbuffer_flush);
|
GRAPHICS_IMPORT(gs_vertexbuffer_flush);
|
||||||
|
GRAPHICS_IMPORT(gs_vertexbuffer_flush_direct);
|
||||||
GRAPHICS_IMPORT(gs_vertexbuffer_get_data);
|
GRAPHICS_IMPORT(gs_vertexbuffer_get_data);
|
||||||
|
|
||||||
GRAPHICS_IMPORT(gs_indexbuffer_destroy);
|
GRAPHICS_IMPORT(gs_indexbuffer_destroy);
|
||||||
GRAPHICS_IMPORT(gs_indexbuffer_flush);
|
GRAPHICS_IMPORT(gs_indexbuffer_flush);
|
||||||
|
GRAPHICS_IMPORT(gs_indexbuffer_flush_direct);
|
||||||
GRAPHICS_IMPORT(gs_indexbuffer_get_data);
|
GRAPHICS_IMPORT(gs_indexbuffer_get_data);
|
||||||
GRAPHICS_IMPORT(gs_indexbuffer_get_num_indices);
|
GRAPHICS_IMPORT(gs_indexbuffer_get_num_indices);
|
||||||
GRAPHICS_IMPORT(gs_indexbuffer_get_type);
|
GRAPHICS_IMPORT(gs_indexbuffer_get_type);
|
||||||
|
@ -189,11 +189,15 @@ struct gs_exports {
|
|||||||
|
|
||||||
void (*gs_vertexbuffer_destroy)(gs_vertbuffer_t *vertbuffer);
|
void (*gs_vertexbuffer_destroy)(gs_vertbuffer_t *vertbuffer);
|
||||||
void (*gs_vertexbuffer_flush)(gs_vertbuffer_t *vertbuffer);
|
void (*gs_vertexbuffer_flush)(gs_vertbuffer_t *vertbuffer);
|
||||||
|
void (*gs_vertexbuffer_flush_direct)(gs_vertbuffer_t *vertbuffer,
|
||||||
|
const struct gs_vb_data *data);
|
||||||
struct gs_vb_data *(*gs_vertexbuffer_get_data)(
|
struct gs_vb_data *(*gs_vertexbuffer_get_data)(
|
||||||
const gs_vertbuffer_t *vertbuffer);
|
const gs_vertbuffer_t *vertbuffer);
|
||||||
|
|
||||||
void (*gs_indexbuffer_destroy)(gs_indexbuffer_t *indexbuffer);
|
void (*gs_indexbuffer_destroy)(gs_indexbuffer_t *indexbuffer);
|
||||||
void (*gs_indexbuffer_flush)(gs_indexbuffer_t *indexbuffer);
|
void (*gs_indexbuffer_flush)(gs_indexbuffer_t *indexbuffer);
|
||||||
|
void (*gs_indexbuffer_flush_direct)(gs_indexbuffer_t *indexbuffer,
|
||||||
|
const void *data);
|
||||||
void *(*gs_indexbuffer_get_data)(const gs_indexbuffer_t *indexbuffer);
|
void *(*gs_indexbuffer_get_data)(const gs_indexbuffer_t *indexbuffer);
|
||||||
size_t (*gs_indexbuffer_get_num_indices)(
|
size_t (*gs_indexbuffer_get_num_indices)(
|
||||||
const gs_indexbuffer_t *indexbuffer);
|
const gs_indexbuffer_t *indexbuffer);
|
||||||
|
@ -2477,6 +2477,16 @@ void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer)
|
|||||||
thread_graphics->exports.gs_vertexbuffer_flush(vertbuffer);
|
thread_graphics->exports.gs_vertexbuffer_flush(vertbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer,
|
||||||
|
const struct gs_vb_data *data)
|
||||||
|
{
|
||||||
|
if (!gs_valid_p2("gs_vertexbuffer_flush_direct", vertbuffer, data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
thread_graphics->exports.gs_vertexbuffer_flush_direct(vertbuffer,
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer)
|
struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer)
|
||||||
{
|
{
|
||||||
if (!gs_valid_p("gs_vertexbuffer_get_data", vertbuffer))
|
if (!gs_valid_p("gs_vertexbuffer_get_data", vertbuffer))
|
||||||
@ -2505,6 +2515,15 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer)
|
|||||||
thread_graphics->exports.gs_indexbuffer_flush(indexbuffer);
|
thread_graphics->exports.gs_indexbuffer_flush(indexbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
if (!gs_valid_p2("gs_indexbuffer_flush_direct", indexbuffer, data))
|
||||||
|
return;
|
||||||
|
|
||||||
|
thread_graphics->exports.gs_indexbuffer_flush_direct(indexbuffer, data);
|
||||||
|
}
|
||||||
|
|
||||||
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer)
|
void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer)
|
||||||
{
|
{
|
||||||
if (!gs_valid_p("gs_indexbuffer_get_data", indexbuffer))
|
if (!gs_valid_p("gs_indexbuffer_get_data", indexbuffer))
|
||||||
|
@ -718,11 +718,15 @@ EXPORT void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate);
|
|||||||
|
|
||||||
EXPORT void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer);
|
EXPORT void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer);
|
||||||
EXPORT void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer);
|
EXPORT void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer);
|
||||||
|
EXPORT void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer,
|
||||||
|
const struct gs_vb_data *data);
|
||||||
EXPORT struct gs_vb_data *gs_vertexbuffer_get_data(
|
EXPORT struct gs_vb_data *gs_vertexbuffer_get_data(
|
||||||
const gs_vertbuffer_t *vertbuffer);
|
const gs_vertbuffer_t *vertbuffer);
|
||||||
|
|
||||||
EXPORT void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer);
|
EXPORT void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer);
|
||||||
EXPORT void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer);
|
EXPORT void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer);
|
||||||
|
EXPORT void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer,
|
||||||
|
const void *data);
|
||||||
EXPORT void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer);
|
EXPORT void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer);
|
||||||
EXPORT size_t gs_indexbuffer_get_num_indices(
|
EXPORT size_t gs_indexbuffer_get_num_indices(
|
||||||
const gs_indexbuffer_t *indexbuffer);
|
const gs_indexbuffer_t *indexbuffer);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user