GL3: Refactor vertex buffers

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 46ac4541f9
commit b6ac857074

@ -234,13 +234,13 @@ CDriverGL3::CDriverGL3()
_ForceNormalize= false; _ForceNormalize= false;
_AGPVertexArrayRange= NULL; /*_AGPVertexArrayRange= NULL;
_VRAMVertexArrayRange= NULL; _VRAMVertexArrayRange= NULL;
_CurrentVertexArrayRange= NULL; _CurrentVertexArrayRange= NULL;*/
_CurrentVertexBufferHard= NULL; _CurrentVertexBufferGL= NULL;
_NVCurrentVARPtr= NULL; /*_NVCurrentVARPtr= NULL;
_NVCurrentVARSize= 0; _NVCurrentVARSize= 0;*/
_SlowUnlockVBHard= false; _SlowUnlockVBHard= true;
_AllocatedTextureMemory= 0; _AllocatedTextureMemory= 0;
@ -387,16 +387,14 @@ bool CDriverGL3::setupDisplay()
_PZBCameraPos = CVector::Null; _PZBCameraPos = CVector::Null;
// Init VertexArrayRange according to supported extenstion. // Init VertexArrayRange according to supported extenstion.
_SlowUnlockVBHard = false; /*_AGPVertexArrayRange = new CVertexArrayRange(this);
_AGPVertexArrayRange = new CVertexArrayRange(this);
_VRAMVertexArrayRange = new CVertexArrayRange(this); _VRAMVertexArrayRange = new CVertexArrayRange(this);
// Reset VertexArrayRange. // Reset VertexArrayRange.
_CurrentVertexArrayRange = NULL; _CurrentVertexArrayRange = NULL;
_CurrentVertexBufferHard = NULL; _CurrentVertexBufferGL = NULL;
_NVCurrentVARPtr = NULL; _NVCurrentVARPtr = NULL;
_NVCurrentVARSize = 0; _NVCurrentVARSize = 0;*/
initVertexBufferHard(NL3D_DRV_VERTEXARRAY_AGP_INIT_SIZE, 0); initVertexBufferHard(NL3D_DRV_VERTEXARRAY_AGP_INIT_SIZE, 0);
@ -581,8 +579,7 @@ bool CDriverGL3::swapBuffers()
if (!_WndActive) if (!_WndActive)
{ {
if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers(); updateLostBuffers();
if (_VRAMVertexArrayRange) _VRAMVertexArrayRange->updateLostBuffers();
} }
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
@ -641,9 +638,10 @@ bool CDriverGL3::swapBuffers()
_CurVBHardLockCount= 0; _CurVBHardLockCount= 0;
_NumVBHardProfileFrame++; _NumVBHardProfileFrame++;
} }
// on ati, if the window is inactive, check all vertex buffer to see which one are lost
if (_AGPVertexArrayRange) _AGPVertexArrayRange->updateLostBuffers(); // Check all vertex buffer to see which one are lost
if (_VRAMVertexArrayRange) _VRAMVertexArrayRange->updateLostBuffers(); updateLostBuffers();
return true; return true;
} }
@ -688,14 +686,8 @@ bool CDriverGL3::release()
// release caustic cube map // release caustic cube map
// _CauticCubeMap = NULL; // _CauticCubeMap = NULL;
// Reset VertexArrayRange. // Make sure vertex buffers are really all gone
resetVertexArrayRange(); // FIXME VERTEXBUFFER
// delete containers
delete _AGPVertexArrayRange;
delete _VRAMVertexArrayRange;
_AGPVertexArrayRange= NULL;
_VRAMVertexArrayRange= NULL;
// destroy window and associated ressources // destroy window and associated ressources
destroyWindow(); destroyWindow();
@ -1432,13 +1424,13 @@ void CDriverGL3::profileVBHardAllocation(std::vector<std::string> &result)
result.reserve(1000); result.reserve(1000);
result.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM", result.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000)); getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000));
result.push_back(toString("Num VBHard: %d", _VertexBufferHardSet.Set.size())); result.push_back(toString("Num VBHard: %d", _VertexBufferGLSet.Set.size()));
uint totalMemUsed= 0; uint totalMemUsed= 0;
set<IVertexBufferHardGL*>::iterator it; set<IVertexBufferGL*>::iterator it;
for (it= _VertexBufferHardSet.Set.begin(); it!=_VertexBufferHardSet.Set.end(); it++) for (it= _VertexBufferGLSet.Set.begin(); it!=_VertexBufferGLSet.Set.end(); it++)
{ {
IVertexBufferHardGL *vbHard= *it; IVertexBufferGL *vbHard= *it;
if (vbHard) if (vbHard)
{ {
uint vSize= vbHard->VB->getVertexSize(); uint vSize= vbHard->VB->getVertexSize();
@ -1448,9 +1440,9 @@ void CDriverGL3::profileVBHardAllocation(std::vector<std::string> &result)
} }
result.push_back(toString("Mem Used: %4d Ko", totalMemUsed/1000)); result.push_back(toString("Mem Used: %4d Ko", totalMemUsed/1000));
for (it= _VertexBufferHardSet.Set.begin(); it!=_VertexBufferHardSet.Set.end(); it++) for (it= _VertexBufferGLSet.Set.begin(); it!=_VertexBufferGLSet.Set.end(); it++)
{ {
IVertexBufferHardGL *vbHard= *it; IVertexBufferGL *vbHard= *it;
if (vbHard) if (vbHard)
{ {
uint vSize= vbHard->VB->getVertexSize(); uint vSize= vbHard->VB->getVertexSize();

@ -88,7 +88,7 @@ namespace NLDRIVERGL3 {
class CDriverGL3; class CDriverGL3;
class IVertexArrayRange; class IVertexArrayRange;
class IVertexBufferHardGL; class IVertexBufferGL;
class COcclusionQueryGL3; class COcclusionQueryGL3;
void displayGLError(GLenum error); void displayGLError(GLenum error);
@ -190,7 +190,7 @@ public:
CVBDrvInfosGL3(CDriverGL3 *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb); CVBDrvInfosGL3(CDriverGL3 *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb);
// Verex buffer hard ? // Verex buffer hard ?
IVertexBufferHardGL *_VBHard; IVertexBufferGL *_VBHard;
CDriverGL3 *_DriverGL; CDriverGL3 *_DriverGL;
// From IVBDrvInfos // From IVBDrvInfos
@ -250,7 +250,7 @@ public:
} }
void setupVertexBuffer(CVertexBuffer &vb); void setupVertexBuffer(CVertexBuffer &vb);
void setupVertexBufferHard(IVertexBufferHardGL &vb); void setupVertexBufferHard(IVertexBufferGL &vb);
}; };
@ -690,7 +690,7 @@ public:
#endif #endif
private: private:
virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb); virtual class IVertexBufferGL *createVertexBufferGL(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb);
friend class CTextureDrvInfosGL3; friend class CTextureDrvInfosGL3;
friend class CVertexProgamDrvInfosGL3; friend class CVertexProgamDrvInfosGL3;
@ -1123,31 +1123,19 @@ private:
void disableAllLights(); void disableAllLights();
/// \name VertexBufferHard /// \name Vertex Buffer
// @{ // @{
CPtrSet<IVertexBufferHardGL> _VertexBufferHardSet; CPtrSet<IVertexBufferGL> _VertexBufferGLSet;
friend class CVertexArrayRange; friend class CVertexBufferGL;
friend class CVertexBufferHard;
friend class CVBDrvInfosGL3; friend class CVBDrvInfosGL3;
// The VertexArrayRange activated.
IVertexArrayRange *_CurrentVertexArrayRange;
// The VertexBufferHardGL activated. // The VertexBufferHardGL activated.
IVertexBufferHardGL *_CurrentVertexBufferHard; IVertexBufferGL *_CurrentVertexBufferGL;
// current setup passed to nglVertexArrayRangeNV()
void *_NVCurrentVARPtr;
uint32 _NVCurrentVARSize;
bool _SlowUnlockVBHard; bool _SlowUnlockVBHard;
// The AGP VertexArrayRange. // Handle lost buffers
IVertexArrayRange *_AGPVertexArrayRange; void updateLostBuffers();
// The VRAM VertexArrayRange. std::list<CVertexBufferGL *> _LostVBList;
IVertexArrayRange *_VRAMVertexArrayRange;
void resetVertexArrayRange();
// @} // @}
@ -1341,7 +1329,7 @@ protected:
public: public:
void incrementResetCounter() { ++_ResetCounter; } void incrementResetCounter() { ++_ResetCounter; }
bool isWndActive() const { return _WndActive; } bool isWndActive() const { return _WndActive; }
const IVertexBufferHardGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferHard; } const IVertexBufferGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferGL; }
// For debug : dump list of mapped buffers // For debug : dump list of mapped buffers
#ifdef NL_DEBUG #ifdef NL_DEBUG
void dumpMappedBuffers(); void dumpMappedBuffers();

@ -353,8 +353,8 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
}*/ }*/
// NOTE: A vertex buffer MUST be enabled before calling setupMaterial! // NOTE: A vertex buffer MUST be enabled before calling setupMaterial!
nlassert(_CurrentVertexBufferHard); nlassert(_CurrentVertexBufferGL);
uint16 vertexFormat = _CurrentVertexBufferHard->VB->getVertexFormat(); uint16 vertexFormat = _CurrentVertexBufferGL->VB->getVertexFormat();
// Activate the textures. // Activate the textures.
// Do not do it for Lightmap and per pixel lighting , because done in multipass in a very special fashion. // Do not do it for Lightmap and per pixel lighting , because done in multipass in a very special fashion.

@ -576,7 +576,7 @@ void CDriverGL3::setUniformFog(TProgram program, uint index)
void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat) void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat)
{ {
desc.setShaderType(mat.getShader()); desc.setShaderType(mat.getShader());
uint16 vbFlags = _CurrentVertexBufferHard->VB->getVertexFormat(); uint16 vbFlags = _CurrentVertexBufferGL->VB->getVertexFormat();
for (sint i = 0; i < IDRV_MAT_MAXTEXTURES; ++i) for (sint i = 0; i < IDRV_MAT_MAXTEXTURES; ++i)
{ {
if (m_VPBuiltinCurrent.TexGenMode[i] >= 0) if (m_VPBuiltinCurrent.TexGenMode[i] >= 0)

@ -36,7 +36,7 @@ bool CDriverGL3::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)
if (!setupMaterial(mat) || _LastIB._Values == NULL) if (!setupMaterial(mat) || _LastIB._Values == NULL)
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives. // render primitives.
//============================== //==============================
// start multipass. // start multipass.
@ -83,7 +83,7 @@ bool CDriverGL3::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris
if (!setupMaterial(mat) || _LastIB._Values == NULL) if (!setupMaterial(mat) || _LastIB._Values == NULL)
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives. // render primitives.
//============================== //==============================
@ -132,7 +132,7 @@ bool CDriverGL3::renderSimpleTriangles(uint32 firstTri, uint32 ntris)
nlassert(ntris>0); nlassert(ntris>0);
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// Don't setup any material here. // Don't setup any material here.
// render primitives. // render primitives.
@ -167,7 +167,7 @@ bool CDriverGL3::renderRawPoints(CMaterial& mat, uint32 startIndex, uint32 numPo
if (!setupMaterial(mat)) if (!setupMaterial(mat))
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives. // render primitives.
//============================== //==============================
// start multipass. // start multipass.
@ -205,7 +205,7 @@ bool CDriverGL3::renderRawLines(CMaterial& mat, uint32 startIndex, uint32 numLin
if (!setupMaterial(mat)) if (!setupMaterial(mat))
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives. // render primitives.
//============================== //==============================
// start multipass. // start multipass.
@ -243,7 +243,7 @@ bool CDriverGL3::renderRawTriangles(CMaterial& mat, uint32 startIndex, uint32 nu
if (!setupMaterial(mat)) if (!setupMaterial(mat))
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
// render primitives. // render primitives.
//============================== //==============================
// start multipass. // start multipass.
@ -284,7 +284,7 @@ bool CDriverGL3::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQua
if (!setupMaterial(mat)) if (!setupMaterial(mat))
return false; return false;
if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true; if (_CurrentVertexBufferGL && _CurrentVertexBufferGL->isInvalid()) return true;
const uint32 QUAD_BATCH_SIZE = 2048; const uint32 QUAD_BATCH_SIZE = 2048;
static GLshort defaultIndices[QUAD_BATCH_SIZE * 6]; static GLshort defaultIndices[QUAD_BATCH_SIZE * 6];

@ -76,7 +76,7 @@ CVBDrvInfosGL3::~CVBDrvInfosGL3()
if (_VBHard) if (_VBHard)
{ {
_VBHard->disable(); _VBHard->disable();
_DriverGL->_VertexBufferHardSet.erase(_VBHard); _DriverGL->_VertexBufferGLSet.erase(_VBHard);
} }
_VBHard = NULL; _VBHard = NULL;
@ -131,7 +131,7 @@ bool CDriverGL3::setupVertexBuffer(CVertexBuffer& VB)
const uint size = VB.capacity()*VB.getVertexSize(); const uint size = VB.capacity()*VB.getVertexSize();
// Vertex buffer hard // Vertex buffer hard
info->_VBHard = createVertexBufferHard(size, VB.capacity(), preferred, &VB); info->_VBHard = createVertexBufferGL(size, VB.capacity(), preferred, &VB);
// Upload the data // Upload the data
VB.setLocation ((CVertexBuffer::TLocation)preferred); VB.setLocation ((CVertexBuffer::TLocation)preferred);
@ -173,8 +173,8 @@ bool CDriverGL3::activeVertexBuffer(CVertexBuffer& VB)
if (info->_VBHard == NULL) if (info->_VBHard == NULL)
{ {
// Disable the current vertexBufferHard if setuped. // Disable the current vertexBufferHard if setuped.
if (_CurrentVertexBufferHard) if (_CurrentVertexBufferGL)
_CurrentVertexBufferHard->disable(); _CurrentVertexBufferGL->disable();
} }
else else
{ {
@ -209,7 +209,7 @@ bool CDriverGL3::activeIndexBuffer(CIndexBuffer& IB)
bool CDriverGL3::supportVolatileVertexBuffer() const bool CDriverGL3::supportVolatileVertexBuffer() const
{ {
H_AUTO_OGL(CDriverGL3_supportVolatileVertexBuffer) H_AUTO_OGL(CDriverGL3_supportVolatileVertexBuffer)
return false; return false; // TODO VERTEXBUFFER PINNED
} }
@ -231,50 +231,59 @@ uint CDriverGL3::getMaxVerticesByVertexBufferHard() const
// *************************************************************************** // ***************************************************************************
IVertexBufferHardGL *CDriverGL3::createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb) IVertexBufferGL *CDriverGL3::createVertexBufferGL(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb)
{ {
H_AUTO_OGL(CDriverGL3_createVertexBufferHard) H_AUTO_OGL(CDriverGL3_createVertexBufferGL)
// choose the VertexArrayRange of good type
IVertexArrayRange *vertexArrayRange= NULL; // Create a Vertex Buffer
switch(vbType) GLuint vertexBufferID;
nglGenBuffers(1, &vertexBufferID);
_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch (vbType)
{ {
case CVertexBuffer::AGPPreferred: case CVertexBuffer::AGPPreferred:
vertexArrayRange= _AGPVertexArrayRange; nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break; break;
case CVertexBuffer::StaticPreferred: case CVertexBuffer::StaticPreferred:
if (getStaticMemoryToVRAM()) if (getStaticMemoryToVRAM())
vertexArrayRange= _VRAMVertexArrayRange; nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else else
vertexArrayRange= _AGPVertexArrayRange; nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break; break;
default: default:
break; nlassert(0);
break;
} }
CVertexBufferGL *newVbHard = new CVertexBufferGL(this, vb);
newVbHard->initGL(vertexBufferID, vbType);
_DriverGLStates.forceBindARBVertexBuffer(0);
return _VertexBufferGLSet.insert(newVbHard);
}
// If this one at least created (an extension support it). // ********************************************************************
if (!vertexArrayRange)
return NULL; void CDriverGL3::updateLostBuffers()
else {
H_AUTO_OGL(CDriverGL3_updateLostBuffers)
// Put all vb that have been lost in the NotResident state so that they will be recomputed
// We do this only if the app is active, because if vb were lost, it is likely that there are no resources available.
if (isWndActive())
{ {
// Create a CVertexBufferHardGL for (std::list<CVertexBufferGL *>::iterator it = _LostVBList.begin(); it != _LostVBList.end(); ++it)
IVertexBufferHardGL *vbHard = NULL;
// let the VAR create the vbhard.
vbHard= vertexArrayRange->createVBHardGL(size, vb);
// if fails
if (!vbHard)
{ {
return NULL; nlassert((*it)->VertexObjectId);
} GLuint id = (GLuint) (*it)->VertexObjectId;
else nlassert(nglIsBuffer(id));
{ nglDeleteBuffers(1, &id);
// insert in list. (*it)->VertexObjectId = 0;
return _VertexBufferHardSet.insert(vbHard); (*it)->VB->setLocation(CVertexBuffer::NotResident);
} }
_LostVBList.clear();
} }
} }
// ********************************************************************
// ***************************************************************************
const uint CDriverGL3::NumCoordinatesType[CVertexBuffer::NumType]= const uint CDriverGL3::NumCoordinatesType[CVertexBuffer::NumType]=
{ {
1, // Double1 1, // Double1
@ -471,35 +480,12 @@ void CVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb)
} }
} }
// ***************************************************************************
void CDriverGL3::resetVertexArrayRange()
{
H_AUTO_OGL(CDriverGL3_resetVertexArrayRange)
if (_CurrentVertexBufferHard)
{
// Must ensure it has ended any drawing
_CurrentVertexBufferHard->lock();
_CurrentVertexBufferHard->unlock();
// disable it
_CurrentVertexBufferHard->disable();
}
// Clear any VertexBufferHard created.
_VertexBufferHardSet.clear();
}
// *************************************************************************** // ***************************************************************************
bool CDriverGL3::initVertexBufferHard(uint agpMem, uint vramMem) bool CDriverGL3::initVertexBufferHard(uint agpMem, uint vramMem)
{ {
H_AUTO_OGL(CDriverGL3_initVertexBufferHard) H_AUTO_OGL(CDriverGL3_initVertexBufferHard)
// must be supported _SlowUnlockVBHard = true;
if (!_AGPVertexArrayRange || !_VRAMVertexArrayRange)
return false;
// First, reset any VBHard created.
resetVertexArrayRange();
return true; return true;
} }

@ -31,185 +31,69 @@ namespace NLDRIVERGL3 {
#endif #endif
// *************************************************************************** // ***************************************************************************
IVertexArrayRange::IVertexArrayRange(CDriverGL3 *drv) IVertexBufferGL::IVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb) : VB (vb)
{ {
H_AUTO_OGL(IVertexArrayRange_IVertexArrayRange) H_AUTO_OGL(IVertexBufferGL_IVertexBufferGL)
_Driver= drv; m_Driver= drv;
m_Invalid = false;
} }
// *************************************************************************** // ***************************************************************************
IVertexArrayRange::~IVertexArrayRange() IVertexBufferGL::~IVertexBufferGL()
{ {
H_AUTO_OGL(IVertexArrayRange_IVertexArrayRangeDtor) H_AUTO_OGL(IVertexBufferGL_IVertexBufferGLDtor)
} }
// *************************************************************************** // ***************************************************************************
IVertexBufferHardGL::IVertexBufferHardGL(CDriverGL3 *drv, CVertexBuffer *vb) : VB (vb) CVertexBufferGL::CVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb)
: IVertexBufferGL(drv, vb),
m_VertexPtr(NULL),
VertexObjectId(0)
{ {
H_AUTO_OGL(IVertexBufferHardGL_IVertexBufferHardGL) H_AUTO_OGL(CVertexBufferGLARB_CVertexBufferGLARB)
_Driver= drv;
_Invalid = false;
}
// ***************************************************************************
IVertexBufferHardGL::~IVertexBufferHardGL()
{
H_AUTO_OGL(IVertexBufferHardGL_IVertexBufferHardGLDtor)
}
// ***************************************************************************
// CVertexArrayRangeARB
// ***************************************************************************
// ***************************************************************************
CVertexArrayRange::CVertexArrayRange(CDriverGL3 *drv) : IVertexArrayRange(drv),
_VBType(CVertexBuffer::AGPPreferred)
{
H_AUTO_OGL(CVertexArrayRangeARB_CVertexArrayRangeARB)
}
// ***************************************************************************
IVertexBufferHardGL *CVertexArrayRange::createVBHardGL(uint size, CVertexBuffer *vb)
{
H_AUTO_OGL(CVertexArrayRange_createVBHardGL)
// create a ARB VBHard
GLuint vertexBufferID;
nglGenBuffers(1, &vertexBufferID);
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch(_VBType)
{
case CVertexBuffer::AGPPreferred:
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
case CVertexBuffer::StaticPreferred:
if (_Driver->getStaticMemoryToVRAM())
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break;
default:
nlassert(0);
break;
}
CVertexBufferHard *newVbHard= new CVertexBufferHard(_Driver, vb);
newVbHard->initGL(vertexBufferID, this, _VBType);
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
return newVbHard;
}
// ***************************************************************************
void CVertexArrayRange::enable()
{
H_AUTO_OGL(CVertexArrayRangeARB_enable)
if (_Driver->_CurrentVertexArrayRange != this)
{
_Driver->_CurrentVertexArrayRange= this;
}
}
// ***************************************************************************
void CVertexArrayRange::disable()
{
H_AUTO_OGL(CVertexArrayRangeARB_disbale)
if (_Driver->_CurrentVertexBufferHard != NULL)
{
_Driver->_CurrentVertexBufferHard= NULL;
}
} }
// *************************************************************************** // ***************************************************************************
void CVertexArrayRange::updateLostBuffers() CVertexBufferGL::~CVertexBufferGL()
{ {
H_AUTO_OGL(CVertexArrayRangeARB_updateLostBuffers) H_AUTO_OGL(CVertexBufferGLARB_CVertexBufferGLARBDtor)
// Put all vb that have been lost in the NotResident state so that they will be recomputed if (m_Driver && VertexObjectId)
// We do this only if the app is active, because if vb were lost, it is likely that there are no resources available.
nlassert(_Driver);
if (_Driver->isWndActive())
{ {
for (std::list<CVertexBufferHard *>::iterator it = _LostVBList.begin(); it != _LostVBList.end(); ++it) if (m_Driver->_DriverGLStates.getCurrBoundARBVertexBuffer() == VertexObjectId)
{ {
nlassert((*it)->_VertexObjectId); m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
GLuint id = (GLuint) (*it)->_VertexObjectId;
nlassert(nglIsBuffer(id));
nglDeleteBuffers(1, &id);
(*it)->_VertexObjectId = 0;
(*it)->VB->setLocation(CVertexBuffer::NotResident);
} }
_LostVBList.clear();
} }
} if (VertexObjectId)
// ***************************************************************************
// CVertexBufferHardARB
// ***************************************************************************
// ***************************************************************************
CVertexBufferHard::CVertexBufferHard(CDriverGL3 *drv, CVertexBuffer *vb) : IVertexBufferHardGL(drv, vb),
_VertexPtr(NULL),
_VertexObjectId(0)
{
H_AUTO_OGL(CVertexBufferHardARB_CVertexBufferHardARB)
_VertexArrayRange = NULL;
#ifdef NL_DEBUG
_Unmapping = false;
#endif
}
// ***************************************************************************
CVertexBufferHard::~CVertexBufferHard()
{
H_AUTO_OGL(CVertexBufferHardARB_CVertexBufferHardARBDtor)
if (_Driver && _VertexObjectId)
{
if (_Driver->_DriverGLStates.getCurrBoundARBVertexBuffer() == _VertexObjectId)
{
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
}
}
if (_VertexObjectId)
{ {
GLuint id = (GLuint) _VertexObjectId; GLuint id = (GLuint) VertexObjectId;
nlassert(nglIsBuffer(id)); nlassert(nglIsBuffer(id));
nglDeleteBuffers(1, &id); nglDeleteBuffers(1, &id);
} }
if (_VertexArrayRange) if (m_Driver)
{ {
if (_Invalid) if (m_Invalid)
{ {
if (VB->getLocation() != CVertexBuffer::NotResident) if (VB->getLocation() != CVertexBuffer::NotResident)
{ {
// when the vb is put in tthe NotResident state, it is removed from that list // when the vb is put in tthe NotResident state, it is removed from that list
_VertexArrayRange->_LostVBList.erase(_IteratorInLostVBList); m_Driver->_LostVBList.erase(m_IteratorInLostVBList);
} }
} }
} }
#ifdef NL_DEBUG
if (_VertexPtr)
{
_VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList);
}
#endif
} }
// *************************************************************************** // ***************************************************************************
void *CVertexBufferHard::lock() void *CVertexBufferGL::lock()
{ {
H_AUTO_OGL(CVertexBufferHardARB_lock); H_AUTO_OGL(CVertexBufferGLARB_lock);
if (_VertexPtr) return _VertexPtr; // already locked if (m_VertexPtr) return m_VertexPtr; // already locked
if (_Invalid) if (m_Invalid)
{ {
if (VB->getLocation() != CVertexBuffer::NotResident) if (VB->getLocation() != CVertexBuffer::NotResident)
{ {
nlassert(!_DummyVB.empty()); nlassert(!m_DummyVB.empty());
return &_DummyVB[0]; return &m_DummyVB[0];
} }
// recreate a vb // recreate a vb
GLuint vertexBufferID; GLuint vertexBufferID;
@ -219,18 +103,18 @@ void *CVertexBufferHard::lock()
if (glGetError() != GL_NO_ERROR) if (glGetError() != GL_NO_ERROR)
{ {
_Driver->incrementResetCounter(); m_Driver->incrementResetCounter();
return &_DummyVB[0]; return &m_DummyVB[0];
} }
const uint size = VB->getNumVertices() * VB->getVertexSize(); const uint size = VB->getNumVertices() * VB->getVertexSize();
_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID); m_Driver->_DriverGLStates.forceBindARBVertexBuffer(vertexBufferID);
switch(_MemType) switch(m_MemType)
{ {
case CVertexBuffer::AGPPreferred: case CVertexBuffer::AGPPreferred:
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
break; break;
case CVertexBuffer::StaticPreferred: case CVertexBuffer::StaticPreferred:
if (_Driver->getStaticMemoryToVRAM()) if (m_Driver->getStaticMemoryToVRAM())
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW); nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
else else
nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW); nglBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
@ -241,63 +125,63 @@ void *CVertexBufferHard::lock()
} }
if (glGetError() != GL_NO_ERROR) if (glGetError() != GL_NO_ERROR)
{ {
_Driver->incrementResetCounter(); m_Driver->incrementResetCounter();
nglDeleteBuffers(1, &vertexBufferID); nglDeleteBuffers(1, &vertexBufferID);
return &_DummyVB[0];; return &m_DummyVB[0];;
} }
_VertexObjectId = vertexBufferID; VertexObjectId = vertexBufferID;
NLMISC::contReset(_DummyVB); // free vector memory for real NLMISC::contReset(m_DummyVB); // free vector memory for real
nlassert(_VertexObjectId); nlassert(VertexObjectId);
_Invalid = false; m_Invalid = false;
_VertexArrayRange->_LostVBList.erase(_IteratorInLostVBList); m_Driver->_LostVBList.erase(m_IteratorInLostVBList);
// continue to standard mapping code below .. // continue to standard mapping code below ..
} }
TTicks beforeLock = 0; TTicks beforeLock = 0;
if (_Driver->_VBHardProfiling) if (m_Driver->_VBHardProfiling)
{ {
beforeLock= CTime::getPerformanceTime(); beforeLock= CTime::getPerformanceTime();
} }
_Driver->_DriverGLStates.bindARBVertexBuffer(_VertexObjectId); m_Driver->_DriverGLStates.bindARBVertexBuffer(VertexObjectId);
_VertexPtr = nglMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); m_VertexPtr = nglMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (!_VertexPtr) if (!m_VertexPtr)
{ {
nglUnmapBuffer(GL_ARRAY_BUFFER); nglUnmapBuffer(GL_ARRAY_BUFFER);
nlassert(nglIsBuffer((GLuint) _VertexObjectId)); nlassert(nglIsBuffer((GLuint) VertexObjectId));
invalidate(); invalidate();
return &_DummyVB[0]; return &m_DummyVB[0];
} }
#ifdef NL_DEBUG #ifdef NL_DEBUG
_VertexArrayRange->_MappedVBList.push_front(this); _VertexArrayRange->_MappedVBList.push_front(this);
_IteratorInMappedVBList = _VertexArrayRange->_MappedVBList.begin(); _IteratorInMappedVBList = _VertexArrayRange->_MappedVBList.begin();
#endif #endif
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0); m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
// Lock Profile? // Lock Profile?
if (_Driver->_VBHardProfiling) if (m_Driver->_VBHardProfiling)
{ {
TTicks afterLock; TTicks afterLock;
afterLock= CTime::getPerformanceTime(); afterLock= CTime::getPerformanceTime();
_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB); m_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
} }
return _VertexPtr; return m_VertexPtr;
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::unlock() void CVertexBufferGL::unlock()
{ {
H_AUTO_OGL(CVertexBufferHardARB_unlock); H_AUTO_OGL(CVertexBufferGLARB_unlock);
_VertexPtr = NULL; m_VertexPtr = NULL;
if (_Invalid) return; if (m_Invalid) return;
if (!_VertexObjectId) return; if (!VertexObjectId) return;
TTicks beforeLock = 0; TTicks beforeLock = 0;
if (_Driver->_VBHardProfiling) if (m_Driver->_VBHardProfiling)
{ {
beforeLock= CTime::getPerformanceTime(); beforeLock= CTime::getPerformanceTime();
} }
_Driver->_DriverGLStates.bindARBVertexBuffer(_VertexObjectId); m_Driver->_DriverGLStates.bindARBVertexBuffer(VertexObjectId);
// double start = CTime::ticksToSecond(CTime::getPerformanceTime()); // double start = CTime::ticksToSecond(CTime::getPerformanceTime());
#ifdef NL_DEBUG #ifdef NL_DEBUG
_Unmapping = true; _Unmapping = true;
@ -310,16 +194,16 @@ void CVertexBufferHard::unlock()
_Unmapping = false; _Unmapping = false;
#endif #endif
// Lock Profile? // Lock Profile?
if (_Driver->_VBHardProfiling) if (m_Driver->_VBHardProfiling)
{ {
TTicks afterLock; TTicks afterLock;
afterLock= CTime::getPerformanceTime(); afterLock= CTime::getPerformanceTime();
_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB); m_Driver->appendVBHardLockProfile(afterLock-beforeLock, VB);
} }
#ifdef NL_DEBUG #ifdef NL_DEBUG
_VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList); _VertexArrayRange->_MappedVBList.erase(_IteratorInMappedVBList);
#endif #endif
// _Driver->_DriverGLStates.forceBindARBVertexBuffer(0); m_Driver->_DriverGLStates.forceBindARBVertexBuffer(0);
if (!unmapOk) if (!unmapOk)
{ {
invalidate(); invalidate();
@ -329,95 +213,80 @@ void CVertexBufferHard::unlock()
} }
// *************************************************************************** // ***************************************************************************
void *CVertexBufferHard::getPointer() void *CVertexBufferGL::getPointer()
{ {
H_AUTO_OGL(CVertexBufferHardARB_getPointer) H_AUTO_OGL(CVertexBufferGLARB_getPointer)
return _VertexPtr; return m_VertexPtr;
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::unlock(uint /* startVert */,uint /* endVert */) void CVertexBufferGL::unlock(uint /* startVert */,uint /* endVert */)
{ {
H_AUTO_OGL(CVertexBufferHardARB_unlock) H_AUTO_OGL(CVertexBufferGLARB_unlock)
unlock(); // can't do a lock on a range of the vb.. unlock(); // can't do a lock on a range of the vb..
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::enable() void CVertexBufferGL::enable()
{ {
H_AUTO_OGL(CVertexBufferHardARB_enable) H_AUTO_OGL(CVertexBufferGLARB_enable)
if (_Driver->_CurrentVertexBufferHard != this) if (m_Driver->_CurrentVertexBufferGL != this)
{ {
/* nlassert(_VertexArrayRange); /* nlassert(_VertexArrayRange);
_VertexArrayRange->enable(); */ _VertexArrayRange->enable(); */
_Driver->_CurrentVertexBufferHard= this; m_Driver->_CurrentVertexBufferGL= this;
} }
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::disable() void CVertexBufferGL::disable()
{ {
H_AUTO_OGL(CVertexBufferHardARB_disable) H_AUTO_OGL(CVertexBufferGLARB_disable)
if (_Driver->_CurrentVertexBufferHard != NULL) if (m_Driver->_CurrentVertexBufferGL != NULL)
{ {
/* nlassert(_VertexArrayRange); /* nlassert(_VertexArrayRange);
_VertexArrayRange->disable(); */ _VertexArrayRange->disable(); */
_Driver->_CurrentVertexBufferHard= NULL; m_Driver->_CurrentVertexBufferGL= NULL;
} }
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::initGL(uint vertexObjectID, CVertexArrayRange *var, CVertexBuffer::TPreferredMemory memType) void CVertexBufferGL::initGL(uint vertexObjectID, CVertexBuffer::TPreferredMemory memType)
{ {
H_AUTO_OGL(CVertexBufferHardARB_initGL) H_AUTO_OGL(CVertexBufferGLARB_initGL)
_VertexObjectId = vertexObjectID; VertexObjectId = vertexObjectID;
_MemType = memType; m_MemType = memType;
_VertexArrayRange = var;
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::lockHintStatic(bool /* staticLock */) void CVertexBufferGL::lockHintStatic(bool /* staticLock */)
{ {
H_AUTO_OGL(CVertexBufferHardARB_lockHintStatic) H_AUTO_OGL(CVertexBufferGLARB_lockHintStatic)
// no op. // no op.
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::setupVBInfos(CVertexBufferInfo &vb) void CVertexBufferGL::setupVBInfos(CVertexBufferInfo &vb)
{ {
H_AUTO_OGL(CVertexBufferHardARB_setupVBInfos) H_AUTO_OGL(CVertexBufferGLARB_setupVBInfos)
vb.VertexObjectId = _VertexObjectId; vb.VertexObjectId = VertexObjectId;
} }
// *************************************************************************** // ***************************************************************************
void CVertexBufferHard::invalidate() void CVertexBufferGL::invalidate()
{ {
H_AUTO_OGL(CVertexBufferHardARB_invalidate) H_AUTO_OGL(CVertexBufferGLARB_invalidate)
nlassert(!_Invalid); nlassert(!m_Invalid);
// Buffer is lost (maybe there was a alt-tab or fullscrren / windowed change) // Buffer is lost (maybe there was a alt-tab or fullscrren / windowed change)
// Buffer is deleted at end of frame only // Buffer is deleted at end of frame only
_Invalid = true; m_Invalid = true;
_Driver->incrementResetCounter(); m_Driver->incrementResetCounter();
_DummyVB.resize(VB->getNumVertices() * VB->getVertexSize(), 0); m_DummyVB.resize(VB->getNumVertices() * VB->getVertexSize(), 0);
// insert in lost vb list // insert in lost vb list
_VertexArrayRange->_LostVBList.push_front(this); m_Driver->_LostVBList.push_front(this);
_IteratorInLostVBList = _VertexArrayRange->_LostVBList.begin(); m_IteratorInLostVBList = m_Driver->_LostVBList.begin();
} }
// ***************************************************************************
#ifdef NL_DEBUG
void CVertexArrayRange::dumpMappedBuffers()
{
nlwarning("*****************************************************");
nlwarning("Mapped buffers :");
for (std::list<CVertexBufferHard *>::iterator it = _MappedVBList.begin(); it != _MappedVBList.end(); ++it)
{
CVertexBufferHard &vbarb = **it;
nlwarning("Buffer id = %u, size = %u, address = %p", vbarb._VertexObjectId, vbarb.VB->getVertexSize() * vbarb.VB->getNumVertices(), vbarb.getPointer());
}
}
#endif
#ifdef NL_STATIC #ifdef NL_STATIC
} // NLDRIVERGL3 } // NLDRIVERGL3
#endif #endif

@ -19,164 +19,80 @@
#include "nel/misc/types_nl.h" #include "nel/misc/types_nl.h"
namespace NL3D { namespace NL3D {
#ifdef NL_STATIC #ifdef NL_STATIC
namespace NLDRIVERGL3 { namespace NLDRIVERGL3 {
#endif #endif
class CDriverGL; class CDriverGL;
class IVertexBufferHardGL; class IVertexBufferGL;
class CVertexBufferInfo; class CVertexBufferInfo;
class CVertexBufferHard; class CVertexBufferGL;
// *************************************************************************** class IVertexBufferGL
/** Interface to a Big block of video memory
*/
class IVertexArrayRange
{ {
public: public:
IVertexArrayRange(CDriverGL3 *drv); IVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~IVertexArrayRange(); virtual ~IVertexBufferGL();
virtual void *lock() = 0;
/// create a IVertexBufferHardGL virtual void unlock() = 0;
virtual IVertexBufferHardGL *createVBHardGL(uint size, CVertexBuffer *vb) =0; virtual void unlock(uint start, uint end) = 0;
// Check & invalidate lost buffers. Default assume they can't be lost virtual void *getPointer() = 0;
virtual void updateLostBuffers() {} virtual void enable() = 0;
// Get driver virtual void disable() = 0;
CDriverGL3* getDriver() const { return _Driver; } virtual void setupVBInfos(CVertexBufferInfo &vb) = 0;
// tmp, for debug
#ifdef NL_DEBUG
virtual void dumpMappedBuffers() {}
#endif
protected:
CDriverGL3 *_Driver;
};
class IVertexBufferHardGL
{
public:
IVertexBufferHardGL(CDriverGL3 *drv, CVertexBuffer *vb);
virtual ~IVertexBufferHardGL();
virtual void *lock() = 0;
virtual void unlock() = 0;
virtual void unlock(uint start, uint end) = 0;
virtual void *getPointer() = 0;
virtual void enable() =0;
virtual void disable() =0;
virtual void setupVBInfos(CVertexBufferInfo &vb) = 0;
// test if buffer content is invalid. If so, no rendering should occurs (rendering should silently fail) // test if buffer content is invalid. If so, no rendering should occurs (rendering should silently fail)
bool isInvalid() { return _Invalid; } inline bool isInvalid() { return m_Invalid; }
public: public:
CVertexBuffer *VB;
CVertexBuffer *VB;
protected: protected:
CDriverGL3 *_Driver; CDriverGL3 *m_Driver;
bool _Invalid; bool m_Invalid;
};
// ***************************************************************************
// ***************************************************************************
// ARB_vertex_buffer_object implementation
// ***************************************************************************
// ***************************************************************************
class CVertexArrayRange : public IVertexArrayRange
{
public:
CVertexArrayRange(CDriverGL3 *drv);
virtual IVertexBufferHardGL *createVBHardGL(uint size, CVertexBuffer *vb);
// Those methods read/write in _Driver->_CurrentVertexArrayRange.
/** active this VertexArrayRange as the current vertex array range used. no-op if already setup.
* NB: no-op for ARB, but ensure correct _Driver->_CurrentVertexArrayRange value.
*/
void enable();
/** disable this VertexArrayRange. _Driver->_CurrentVertexArrayRange= NULL;
* NB: no-op for ARB, but ensure correct _Driver->_CurrentVertexArrayRange value.
*/
void disable();
// check & invalidate lost buffers
void updateLostBuffers();
//
#ifdef NL_DEBUG
virtual void dumpMappedBuffers();
#endif
// *************************
private:
CVertexBuffer::TPreferredMemory _VBType;
// for use by CVertexBufferHardARB
public:
std::list<CVertexBufferHard*> _LostVBList;
#ifdef NL_DEBUG
std::list<CVertexBufferHard*> _MappedVBList;
#endif
}; };
/* GL Core vertex buffer. */
/** vb hard using the ARB_vertex_buffer_object extension. Buffer are kept separate rather than managed in a heap class CVertexBufferGL : public IVertexBufferGL
*/
class CVertexBufferHard : public IVertexBufferHardGL
{ {
public: public:
CVertexBufferGL(CDriverGL3 *drv, CVertexBuffer *vb);
CVertexBufferHard(CDriverGL3 *drv, CVertexBuffer *vb); virtual ~CVertexBufferGL();
virtual ~CVertexBufferHard();
/// \name Implementation /// \name Implementation
// @{ // @{
virtual void *lock(); virtual void *lock();
virtual void unlock(); virtual void unlock();
virtual void unlock(uint startVert, uint endVert); virtual void unlock(uint startVert, uint endVert);
virtual void *getPointer(); virtual void *getPointer();
virtual void enable(); virtual void enable();
virtual void disable(); virtual void disable();
virtual void lockHintStatic(bool staticLock); virtual void lockHintStatic(bool staticLock);
virtual void setupVBInfos(CVertexBufferInfo &vb); virtual void setupVBInfos(CVertexBufferInfo &vb);
// @} // @}
/** setup ptrs allocated by createVBHard() /// Setup ptrs allocated by createVBHard()
*/ void initGL(uint vertexObjectID, CVertexBuffer::TPreferredMemory memType);
void initGL(uint vertexObjectID, CVertexArrayRange *var, CVertexBuffer::TPreferredMemory memType);
public: public:
/// Get Handle of the ARB buffer.
uint getARBVertexObjectId() const { return VertexObjectId;}
/// get Handle of the ARB buffer. /// Invalidate the buffer (when it is lost, or when a lock fails)
uint getARBVertexObjectId() const { return _VertexObjectId;} void invalidate();
// Invalidate the buffer (when it is lost, or when a lock fails)
void invalidate();
// tmp
void checkMappedVBList();
// *************************
private: private:
CVertexArrayRange *_VertexArrayRange; CVertexBuffer::TPreferredMemory m_MemType;
CVertexBuffer::TPreferredMemory _MemType; void *m_VertexPtr; // pointer on current datas. Null if not locked
void *_VertexPtr; // pointer on current datas. Null if not locked
// if buffer has been invalidated, returns a dummy memory block and silently fails rendering // if buffer has been invalidated, returns a dummy memory block and silently fails rendering
std::vector<uint8> _DummyVB; std::vector<uint8> m_DummyVB;
// for use by CVertexArrayRange // for use by CVertexArrayRange
std::list<CVertexBufferHard*>::iterator _IteratorInLostVBList; std::list<CVertexBufferGL*>::iterator m_IteratorInLostVBList;
public: public:
uint _VertexObjectId; uint VertexObjectId;
// tmp for debug
#ifdef NL_DEBUG
bool _Unmapping;
std::list<CVertexBufferHard*>::iterator _IteratorInMappedVBList;
#endif
}; };
#ifdef NL_STATIC #ifdef NL_STATIC
@ -185,7 +101,6 @@ public:
} // NL3D } // NL3D
#endif // NL_DRIVER_OPENGL_VERTEX_BUFFER_H #endif // NL_DRIVER_OPENGL_VERTEX_BUFFER_H
/* End of driver_opengl_vertex_buffer.h */ /* End of driver_opengl_vertex_buffer.h */

@ -379,7 +379,7 @@ void CDriverGL3::touchLightVP(int i)
void CDriverGL3::touchVertexFormatVP() void CDriverGL3::touchVertexFormatVP()
{ {
H_AUTO_OGL(CDriverGL3_touchLightVP) H_AUTO_OGL(CDriverGL3_touchLightVP)
uint16 format = _CurrentVertexBufferHard->VB->getVertexFormat(); uint16 format = _CurrentVertexBufferGL->VB->getVertexFormat();
if (m_VPBuiltinCurrent.VertexFormat != format) if (m_VPBuiltinCurrent.VertexFormat != format)
{ {
m_VPBuiltinCurrent.VertexFormat = format; m_VPBuiltinCurrent.VertexFormat = format;

Loading…
Cancel
Save