Torque3D Documentation / _generateds / gfxGLPrimitiveBuffer.cpp

gfxGLPrimitiveBuffer.cpp

Engine/source/gfx/gl/gfxGLPrimitiveBuffer.cpp

More...

Public Variables

Detailed Description

Public Variables

 MODULE_INIT 
 MODULE_SHUTDOWN 

Public Functions

getCircularVolatileIndexBuffer()

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "gfx/gl/gfxGLDevice.h"
 25#include "gfx/gl/gfxGLPrimitiveBuffer.h"
 26#include "gfx/gl/gfxGLEnumTranslate.h"
 27
 28#include "gfx/gl/tGL/tGL.h"
 29#include "gfx/gl/gfxGLUtils.h"
 30
 31#include "gfx/gl/gfxGLCircularVolatileBuffer.h"
 32
 33GLCircularVolatileBuffer* getCircularVolatileIndexBuffer()
 34{
 35   static GLCircularVolatileBuffer sCircularVolatileIndexBuffer(GL_ELEMENT_ARRAY_BUFFER);
 36   return &sCircularVolatileIndexBuffer;
 37}
 38
 39GFXGLPrimitiveBuffer::GFXGLPrimitiveBuffer(GFXDevice *device, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType) :
 40   GFXPrimitiveBuffer(device, indexCount, primitiveCount, bufferType), mZombieCache(NULL),
 41   mBufferOffset(0)
 42{
 43   if( mBufferType == GFXBufferTypeVolatile )
 44   {
 45      mBuffer = getCircularVolatileIndexBuffer()->getHandle();
 46      return;
 47   }
 48
 49   // Generate a buffer and allocate the needed memory
 50   glGenBuffers(1, &mBuffer);
 51   
 52   PRESERVE_INDEX_BUFFER();
 53   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
 54   glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(U16), NULL, GFXGLBufferType[bufferType]);   
 55}
 56
 57GFXGLPrimitiveBuffer::~GFXGLPrimitiveBuffer()
 58{
 59   // This is heavy handed, but it frees the buffer memory
 60   if( mBufferType != GFXBufferTypeVolatile )
 61      glDeleteBuffers(1, &mBuffer);
 62   
 63   if( mZombieCache )
 64      delete [] mZombieCache;
 65}
 66
 67void GFXGLPrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
 68{
 69   if( mBufferType == GFXBufferTypeVolatile )
 70   {
 71      AssertFatal(indexStart == 0, "");
 72      getCircularVolatileIndexBuffer()->lock( mIndexCount * sizeof(U16), 0, mBufferOffset, *indexPtr );
 73   }
 74   else
 75   {
 76      mFrameAllocator.lock( mIndexCount * sizeof(U16) );
 77
 78      *indexPtr = (void*)(mFrameAllocator.getlockedPtr() + (indexStart * sizeof(U16)) );
 79   }
 80
 81   lockedIndexStart = indexStart;
 82   lockedIndexEnd = indexEnd;
 83}
 84
 85void GFXGLPrimitiveBuffer::unlock()
 86{
 87   PROFILE_SCOPE(GFXGLPrimitiveBuffer_unlock);
 88
 89   if( mBufferType == GFXBufferTypeVolatile )
 90   {
 91      getCircularVolatileIndexBuffer()->unlock();
 92   }
 93   else
 94   {   
 95      U32 offset = lockedIndexStart * sizeof(U16);
 96      U32 length = (lockedIndexEnd - lockedIndexStart) * sizeof(U16);
 97   
 98      // Preserve previous binding
 99      PRESERVE_INDEX_BUFFER();
100   
101      // Bind ourselves
102      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
103
104      if( !lockedIndexStart && lockedIndexEnd == mIndexCount)
105         glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexCount * sizeof(U16), NULL, GFXGLBufferType[mBufferType]); // orphan the buffer
106
107      glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, mFrameAllocator.getlockedPtr() + offset );
108   
109      mFrameAllocator.unlock();
110   }
111
112   lockedIndexStart = 0;
113   lockedIndexEnd = 0;
114}
115
116void GFXGLPrimitiveBuffer::prepare()
117{
118   // Bind
119   GFXGLDevice* glDevice = static_cast<GFXGLDevice*>(mDevice);
120   glDevice->setPB(this);
121   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
122   glDevice->getOpenglCache()->setCacheBinded(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
123}
124
125void GFXGLPrimitiveBuffer::finish()
126{
127   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
128   static_cast<GFXGLDevice*>(mDevice)->getOpenglCache()->setCacheBinded(GL_ELEMENT_ARRAY_BUFFER, 0);
129}
130
131GLvoid* GFXGLPrimitiveBuffer::getBuffer()
132{
133   // NULL specifies no offset into the hardware buffer
134   return (GLvoid*)mBufferOffset;
135}
136
137void GFXGLPrimitiveBuffer::zombify()
138{
139   if(mZombieCache)
140      return;
141      
142   mZombieCache = new U8[mIndexCount * sizeof(U16)];
143   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
144   glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mIndexCount * sizeof(U16), mZombieCache);
145   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
146   glDeleteBuffers(1, &mBuffer);
147   mBuffer = 0;
148}
149
150void GFXGLPrimitiveBuffer::resurrect()
151{
152   if(!mZombieCache)
153      return;
154   
155   glGenBuffers(1, &mBuffer);
156   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBuffer);
157   glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexCount * sizeof(U16), mZombieCache, GFXGLBufferType[mBufferType]);
158   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
159   
160   delete[] mZombieCache;
161   mZombieCache = NULL;
162}
163
164namespace
165{
166   bool onGFXDeviceSignal( GFXDevice::GFXDeviceEventType type )
167   {
168      if( GFX->getAdapterType() == OpenGL && GFXDevice::deEndOfFrame == type )
169         getCircularVolatileIndexBuffer()->protectUsedRange();
170
171      return true;
172   }
173}
174
175MODULE_BEGIN( GFX_GL_PrimitiveBuffer )
176   MODULE_INIT_AFTER( gfx )
177   MODULE_SHUTDOWN_BEFORE( gfx )
178
179   MODULE_INIT
180   {
181      GFXDevice::getDeviceEventSignal( ).notify( &onGFXDeviceSignal );
182   }
183
184   MODULE_SHUTDOWN
185   {
186      GFXDevice::getDeviceEventSignal( ).remove( &onGFXDeviceSignal );
187   }
188MODULE_END
189