Skip to content

Commit

Permalink
UPBGE: Use GPUBuffer in RAS_InstancingBuffer.
Browse files Browse the repository at this point in the history
Using GPUBuffer allow to reuse existing and frequently maintained code
from the viewport. The only issue encountered was for resize the VBO.
The GPUBuffer is not able to be resized, but reallocated instead.
The reallocation is not a problems as the viewport use a pool of all
freed GPUbuffers and reuse it in some case.
The reallocation is done in RAS_InstancingBuffer::Realloc(). None
performance decrease was noticed.
  • Loading branch information
panzergame committed Jul 18, 2016
1 parent cb0d42b commit b585b4a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 13 deletions.
1 change: 1 addition & 0 deletions source/gameengine/Rasterizer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ set(INC
../../blender/makesdna
../../blender/blenlib
../../blender/blenkernel
../../blender/gpu
../../blender/imbuf
../../../intern/glew-mx
../../../intern/guardedalloc
Expand Down
4 changes: 3 additions & 1 deletion source/gameengine/Rasterizer/RAS_DisplayArrayBucket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ void RAS_DisplayArrayBucket::RenderMeshSlotsInstancing(const MT_Transform& camer
UpdateActiveMeshSlots(rasty);

// Bind the instancing buffer to work on it.
m_instancingBuffer->Bind();
m_instancingBuffer->Realloc(nummeshslots);

/* If the material use the transparency we must sort all mesh slots depending on the distance.
* This code share the code used in RAS_BucketManager to do the sort.
Expand All @@ -309,6 +309,8 @@ void RAS_DisplayArrayBucket::RenderMeshSlotsInstancing(const MT_Transform& camer
m_instancingBuffer->Update(rasty, material->GetDrawingMode(), m_activeMeshSlots);
}

m_instancingBuffer->Bind();

// Bind all vertex attributs for the used material and the given buffer offset.
if (rasty->GetOverrideShader() == RAS_IRasterizer::RAS_OVERRIDE_SHADER_NONE) {
material->ActivateInstancing(
Expand Down
33 changes: 23 additions & 10 deletions source/gameengine/Rasterizer/RAS_InstancingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,40 +29,53 @@
#include "RAS_InstancingBuffer.h"
#include "RAS_IRasterizer.h"
#include "RAS_MeshUser.h"
#include "glew-mx.h"

extern "C" {
// To avoid include BKE_DerivedMesh.h.
typedef int (*DMSetMaterial)(int mat_nr, void *attribs);
#include "GPU_buffers.h"
}

RAS_InstancingBuffer::RAS_InstancingBuffer()
:m_matrixOffset(NULL),
:m_vbo(NULL),
m_matrixOffset(NULL),
m_positionOffset(NULL),
m_colorOffset(NULL),
m_stride(sizeof(RAS_InstancingBuffer::InstancingObject))
{
glGenBuffersARB(1, &m_vbo);

m_matrixOffset = (void *)((InstancingObject *)NULL)->matrix;
m_positionOffset = (void *)((InstancingObject *)NULL)->position;
m_colorOffset = (void *)((InstancingObject *)NULL)->color;
}

RAS_InstancingBuffer::~RAS_InstancingBuffer()
{
glDeleteBuffersARB(1, &m_vbo);
if (m_vbo) {
GPU_buffer_free(m_vbo);
}
}

void RAS_InstancingBuffer::Realloc(unsigned int size)
{
if (m_vbo) {
GPU_buffer_free(m_vbo);
}
m_vbo = GPU_buffer_alloc(m_stride * size);
}

void RAS_InstancingBuffer::Bind()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
GPU_buffer_bind(m_vbo, GPU_BINDING_ARRAY);
}

void RAS_InstancingBuffer::Unbind()
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
GPU_buffer_unbind(m_vbo, GPU_BINDING_ARRAY);
}

void RAS_InstancingBuffer::Update(RAS_IRasterizer *rasty, int drawingmode, RAS_MeshSlotList &meshSlots)
{
glBufferData(GL_ARRAY_BUFFER, sizeof(InstancingObject) * meshSlots.size(), 0, GL_DYNAMIC_DRAW);
InstancingObject *buffer = (InstancingObject *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
InstancingObject *buffer = (InstancingObject *)GPU_buffer_lock_stream(m_vbo, GPU_BINDING_ARRAY);

for (unsigned int i = 0, size = meshSlots.size(); i < size; ++i) {
RAS_MeshSlot *ms = meshSlots[i];
Expand Down Expand Up @@ -90,5 +103,5 @@ void RAS_InstancingBuffer::Update(RAS_IRasterizer *rasty, int drawingmode, RAS_M
data.color[3] = color[3] * 255.0f;
}

glUnmapBuffer(GL_ARRAY_BUFFER);
GPU_buffer_unlock(m_vbo, GPU_BINDING_ARRAY);
}
8 changes: 6 additions & 2 deletions source/gameengine/Rasterizer/RAS_InstancingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@

class RAS_IRasterizer;

struct GPUBuffer;

class RAS_InstancingBuffer
{
/// The OpenGL VBO identificator.
unsigned int m_vbo;
/// The OpenGL VBO.
GPUBuffer *m_vbo;
/// The matrix offset in the VBO.
void *m_matrixOffset;
/// The position offset in the VBO.
Expand All @@ -58,6 +60,8 @@ class RAS_InstancingBuffer
RAS_InstancingBuffer();
virtual ~RAS_InstancingBuffer();

/// Realloc the VBO.
void Realloc(unsigned int size);
/// Bind the VBO before work on it.
void Bind();
/// Unbind the VBO after work on it.
Expand Down

0 comments on commit b585b4a

Please sign in to comment.