gpuCache/gpuCacheVBOProxy.h

gpuCache/gpuCacheVBOProxy.h
#ifndef _gpuCacheVBOProxy_h_
#define _gpuCacheVBOProxy_h_
//-
//**************************************************************************/
// Copyright 2015 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
//**************************************************************************/
//+
#include "gpuCacheSample.h"
#include <maya/MGLdefinitions.h>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
namespace GPUCache {
//
// VBOBuffer
//
// This class represents a VBO buffer.
// All functions assume a valid OpenGL context.
//
class VBOBuffer
{
public:
/*----- typedefs and enumerations -----*/
typedef ArrayBase::Key Key;
typedef ArrayBase::KeyHash KeyHash;
typedef ArrayBase::KeyEqualTo KeyEqualTo;
enum BufferType {
kIndexBufferType,
kVertexBufferType,
kFlippedNormalBufferType,
kNbBufferType
};
/*----- static member functions -----*/
// Allocate a VBO and upload the index buffer data to the VBO.
//
// A temporary VBO will be immediately discarded when no longer
// referenced. This is mainly used when running low on video
// memory and it is no longer possible to keep VBO loaded from
// frame to frame.
static boost::shared_ptr<const VBOBuffer> create(
const boost::shared_ptr<const IndexBuffer>& buffer,
const bool isTemporary = false);
// Allocate a VBO and upload the vertex buffer data to the VBO
static boost::shared_ptr<const VBOBuffer> create(
const boost::shared_ptr<const VertexBuffer>& buffer,
const bool isTemporary = false);
// Allocate a VBO and initialize it by flipping the normals of the
// passed VBO.
static boost::shared_ptr<const VBOBuffer> createFlippedNormals(
const boost::shared_ptr<const VertexBuffer>& buffer,
const bool isTemporary = false);
// Lookup to see if VBOBuffer for the given buffer already exists.
static boost::shared_ptr<const VBOBuffer> lookup(
const boost::shared_ptr<const IndexBuffer>& buffer);
// Lookup to see if VBOBuffer for the given buffer already exists.
static boost::shared_ptr<const VBOBuffer> lookup(
const boost::shared_ptr<const VertexBuffer>& buffer);
// Lookup to see if VBOBuffer for the given buffer already exists.
static boost::shared_ptr<const VBOBuffer> lookupFlippedNormals(
const boost::shared_ptr<const VertexBuffer>& buffer);
// Total size of all the VBOs currently allocated
static size_t nbAllocatedBytes();
static size_t nbIndexAllocatedBytes();
static size_t nbVertexAllocatedBytes();
// Number of VBOs currently allocated
static size_t nbAllocated();
static size_t nbIndexAllocated();
static size_t nbVertexAllocated();
// Statistics about the VBO operations that have occurred since
// the plug-in was loaded.
static size_t nbUploaded();
static size_t nbUploadedBytes();
static size_t nbEvicted();
static size_t nbEvictedBytes();
// Flush all VBO buffers.
static void clear();
// Tell the registry that we are about to start drawing a new
// frame. This is used as hint to mark some VBOs as potential
// candidates for eviction.
static void nextRefresh();
/*----- member functions -----*/
// Free the VBO
virtual ~VBOBuffer();
// The buffer type.
BufferType bufferType() const { return fBufferType; }
// The key used to lookup the buffer in maps.
const Key& key() const { return fKey; }
// OpenGL VBO handle
MGLuint name() const { return fVBOName; }
private:
/*----- member functions -----*/
GPUCACHE_DECLARE_MAKE_SHARED_FRIEND_3;
// Construct the VBO Buffer with a memory address and size
VBOBuffer(BufferType bufferType, const Key& key, const void* buffer);
// Construct the VBO Buffer with a VBO handle and size
VBOBuffer(BufferType bufferType, const Key& key, MGLuint vboName);
// Forbidden and not implemented.
VBOBuffer(const VBOBuffer&);
const VBOBuffer& operator=(const VBOBuffer&);
/*----- static data members -----*/
// This is used to limit the size of VBOs used in VP1.0 and in
// VP2.0 when using the MPxDrawOverride API. The display driver
// will start to use system memory when the graphic card's video
// memory is used up.
static size_t fsTotalVBOSize;
// This is used to limit the number of VBOs used in VP1.0 and in
// VP2.0 when using the MPxDrawOverride API. Some display drivers
// behaves badly when too many VBOs are allocated.
static size_t fsNbAllocated;
// Statistics.
static size_t fsNbUploaded;
static size_t fsNbUploadedBytes;
static size_t fsNbEvicted;
static size_t fsNbEvictedBytes;
/*----- data members -----*/
const BufferType fBufferType;
const ArrayBase::Key fKey;
MGLuint fVBOName;
};
//
// VBOProxy
//
// Helper class used to draw geometry samples using VBOs if the amount
// of available graphic memory allows it, or using vertex arrays
// otherwise.
//
// When the VBOProxy class is created, it assumes that no vertex
// arrays are currently active and that no VBOs are currently
// bound. It then takes charge of managing and cache the OpenGL client
// state related to vertex arrays and VBOs. It attempts to minimize
// the amount of OpenGL state changes necessary to draw multiple
// samples.
//
class VBOProxy
{
public:
/*----- typedefs and enumerations -----*/
enum NormalsMode {
kNoNormals,
kFrontNormals,
kBackNormals
};
enum UVsMode {
kNoUVs,
kUVs
};
enum VBOMode {
kUseVBOIfPossible,
kDontUseVBO
};
/*----- member functions -----*/
// Initializes the VBOProxy and takes over the OpenGL client state.
VBOProxy();
// Unbounds any currently active vertex array or VBO and releases
// control of the OpenGL client state.
~VBOProxy();
// Draw the vertices of the given geometry sample
void drawVertices(
const boost::shared_ptr<const ShapeSample>& sample,
const VBOMode vboMode = kUseVBOIfPossible);
// Draw the wireframe of the given geometry sample
void drawWireframe(
const boost::shared_ptr<const ShapeSample>& sample,
const VBOMode vboMode = kUseVBOIfPossible);
// Draw the triangles of the given geometry sample
void drawTriangles(
const boost::shared_ptr<const ShapeSample>& sample,
const size_t groupId,
const NormalsMode normalsMode, const UVsMode uvsMode,
const VBOMode vboMode = kUseVBOIfPossible);
// Draw the bounding box of the given geometry sample
void drawBoundingBox(
const boost::shared_ptr<const ShapeSample>& sample,
bool overrideShadedState = false);
void drawBoundingBox(
const MBoundingBox& boundingBox,
bool overrideShadedState = false);
private:
/*----- typedefs and enumerations -----*/
typedef IndexBuffer::index_t index_t;
enum BindingType {
kPrimitives,
kVertexArrays,
kVBOs
};
/*----- member functions -----*/
// Forbidden and not implemented.
VBOProxy(const VBOProxy&);
const VBOProxy& operator=(const VBOProxy&);
// Try to upload/bind all of the following buffers the graphic
// card. Returns an enum representing the graphic API that should
// be used to perform the drawing.
BindingType updateBuffers(
const boost::shared_ptr<const IndexBuffer>& indices,
const boost::shared_ptr<const VertexBuffer>& positions,
const boost::shared_ptr<const VertexBuffer>& normals,
const boost::shared_ptr<const VertexBuffer>& uvs,
const bool areNormalsFlipped,
const VBOMode vboMode,
VertexBuffer::ReadInterfacePtr& positionsRead,
VertexBuffer::ReadInterfacePtr& normalsRead,
VertexBuffer::ReadInterfacePtr& uvsRead
);
/*----- member functions -----*/
// Currently bound buffers.
boost::shared_ptr<const IndexBuffer> fIndices;
boost::shared_ptr<const VertexBuffer> fPositions;
boost::shared_ptr<const VertexBuffer> fNormals;
boost::shared_ptr<const VertexBuffer> fUVs;
// Currently bound VBOs.
boost::shared_ptr<const VBOBuffer> fVBOIndices;
boost::shared_ptr<const VBOBuffer> fVBOPositions;
boost::shared_ptr<const VBOBuffer> fVBONormals;
boost::shared_ptr<const VBOBuffer> fVBOUVs;
bool fAreNormalsFlipped;
// Last binding type.
BindingType fLastBindingType;
};
}
#endif