Newer
Older
mMappedVertexRegions.clear();
}
}
Xiaohong Bao
committed
stop_glerror();
glUnmapBuffer(GL_ARRAY_BUFFER);
Xiaohong Bao
committed
stop_glerror();
Xiaohong Bao
committed
mMappedData = NULL;
}
Leslie Linden
committed
mVertexLocked = false;
Xiaohong Bao
committed
sMappedCount--;
}
David Parks
committed
if (mMappedIndexData && mIndexLocked)
Xiaohong Bao
committed
{
LL_RECORD_BLOCK_TIME(FTM_IBO_UNMAP);
David Parks
committed
bindGLIndices();
Xiaohong Bao
committed
{
David Parks
committed
if (!mMappedIndexRegions.empty())
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
if (mIndicesSize >= length + offset)
{
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, (U8*) mMappedIndexData+offset);
}
else
{
GLint size = 0;
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
<< "mapped size: " << mIndicesSize
<< ", gl buffer size: " << size
<< ", length: " << length
<< ", offset: " << offset
<< LL_ENDL;
}
David Parks
committed
stop_glerror();
}
mMappedIndexRegions.clear();
}
else
{
stop_glerror();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, getIndicesSize(), nullptr, mUsage); // <alchemy/>
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, getIndicesSize(), (U8*) mMappedIndexData);
David Parks
committed
stop_glerror();
}
Xiaohong Bao
committed
}
else
{
if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (!mMappedIndexRegions.empty())
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE);
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length);
#endif
}
else if (gGLManager.mHasFlushBufferRange)
{
David Parks
committed
#ifdef GL_APPLE_flush_buffer_range
Nyx Linden
committed
#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER, offset, length);
Nyx Linden
committed
#endif
David Parks
committed
#endif
stop_glerror();
}
mMappedIndexRegions.clear();
}
}
Xiaohong Bao
committed
stop_glerror();
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
Xiaohong Bao
committed
stop_glerror();
mMappedIndexData = NULL;
Xiaohong Bao
committed
}
mIndexLocked = false;
Xiaohong Bao
committed
sMappedCount--;
}
if(updated_all)
{
Leslie Linden
committed
mEmpty = false;
}
}
//----------------------------------------------------------------------------
{
typedef LLStrider<T> strider_t;
static bool get(LLVertexBuffer& vbo,
strider_t& strider,
S32 index, S32 count, bool map_range)
S32 stride = LLVertexBuffer::sTypeSize[type];
Xiaohong Bao
committed
volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
Xiaohong Bao
committed
{
LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
Leslie Linden
committed
return false;
Xiaohong Bao
committed
}
strider = (T*)ptr;
strider.setStride(stride);
Leslie Linden
committed
return true;
LL_ERRS() << "VertexBufferStrider could not find valid vertex data." << LL_ENDL;
Leslie Linden
committed
return false;
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
template<class T>
struct VertexBufferStrider<T, LLVertexBuffer::TYPE_INDEX>
{
typedef LLStrider<T> strider_t;
static bool get(LLVertexBuffer& vbo,
strider_t& strider,
S32 index, S32 count, bool map_range)
{
volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == nullptr)
{
LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
return false;
}
strider = (T*) ptr;
strider.setStride(0);
return true;
}
};
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4a,TYPE_VERTEX>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
David Parks
committed
bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
David Parks
committed
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
David Parks
committed
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector4a>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector4a,TYPE_TANGENT>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);
David Parks
committed
bool LLVertexBuffer::getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range)
David Parks
committed
return VertexBufferStrider<LLColor4U,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index, count, map_range);
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index, S32 count, bool map_range)
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index, count, map_range);
}
//----------------------------------------------------------------------------
static LLTrace::BlockTimerStatHandle FTM_BIND_GL_ARRAY("Bind Array");
David Parks
committed
bool LLVertexBuffer::bindGLArray()
{
if (mGLArray && sGLRenderArray != mGLArray)
{
//LL_RECORD_BLOCK_TIME(FTM_BIND_GL_ARRAY);
David Parks
committed
//really shouldn't be necessary, but some drivers don't properly restore the
//state of GL_ELEMENT_ARRAY_BUFFER_BINDING
bindGLIndices();
David Parks
committed
return true;
}
return false;
}
static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
David Parks
committed
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
David Parks
committed
sGLRenderBuffer = mGLBuffer;
sBindCount++;
David Parks
committed
llassert(!mGLArray || sGLRenderArray == mGLArray);
David Parks
committed
ret = true;
}
return ret;
}
static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices");
David Parks
committed
bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
{
//LL_RECORD_BLOCK_TIME(FTM_BIND_GL_INDICES);
David Parks
committed
/*if (sMapped)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
David Parks
committed
}*/
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
David Parks
committed
sGLRenderIndices = mGLIndices;
stop_glerror();
sBindCount++;
David Parks
committed
ret = true;
}
return ret;
}
void LLVertexBuffer::flush()
{
if (useVBOs())
{
unmapBuffer();
}
}
David Parks
committed
// bind for transform feedback (quick 'n dirty)
void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
{
David Parks
committed
U32 offset = mOffsets[type] + sTypeSize[type]*index;
U32 size= (sTypeSize[type]*count);
glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
David Parks
committed
}
// Set for rendering
David Parks
committed
void LLVertexBuffer::setBuffer(U32 data_mask)
David Parks
committed
flush();
//set up pointers if the data mask is different ...
Leslie Linden
committed
bool setup = (sLastMask != data_mask);
David Parks
committed
if (gDebugGL && data_mask != 0)
David Parks
committed
{ //make sure data requirements are fulfilled
David Parks
committed
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (shader)
{
U32 required_mask = 0;
David Parks
committed
for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i)
David Parks
committed
{
if (shader->getAttribLocation(i) > -1)
{
U32 required = 1 << i;
if ((data_mask & required) == 0)
{
LL_WARNS() << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << LL_ENDL;
David Parks
committed
}
required_mask |= required;
}
}
if ((data_mask & required_mask) != required_mask)
{
Graham Linden
committed
U32 unsatisfied_mask = (required_mask & ~data_mask);
Graham Madarasz (Graham Linden)
committed
for (U32 i = 0; i < TYPE_MAX; i++)
{
Graham Madarasz (Graham Linden)
committed
U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
switch (unsatisfied_flag)
{
case 0: break;
case MAP_VERTEX: LL_INFOS() << "Missing vert pos" << LL_ENDL; break;
case MAP_NORMAL: LL_INFOS() << "Missing normals" << LL_ENDL; break;
case MAP_TEXCOORD0: LL_INFOS() << "Missing TC 0" << LL_ENDL; break;
case MAP_TEXCOORD1: LL_INFOS() << "Missing TC 1" << LL_ENDL; break;
case MAP_TEXCOORD2: LL_INFOS() << "Missing TC 2" << LL_ENDL; break;
case MAP_TEXCOORD3: LL_INFOS() << "Missing TC 3" << LL_ENDL; break;
case MAP_COLOR: LL_INFOS() << "Missing vert color" << LL_ENDL; break;
case MAP_EMISSIVE: LL_INFOS() << "Missing emissive" << LL_ENDL; break;
case MAP_TANGENT: LL_INFOS() << "Missing tangent" << LL_ENDL; break;
case MAP_WEIGHT: LL_INFOS() << "Missing weight" << LL_ENDL; break;
case MAP_WEIGHT4: LL_INFOS() << "Missing weightx4" << LL_ENDL; break;
case MAP_CLOTHWEIGHT: LL_INFOS() << "Missing clothweight" << LL_ENDL; break;
case MAP_TEXTURE_INDEX: LL_INFOS() << "Missing tex index" << LL_ENDL; break;
default: LL_INFOS() << "Missing who effin knows: " << unsatisfied_flag << LL_ENDL;
}
}
// TYPE_INDEX is beyond TYPE_MAX, so check for it individually
if (unsatisfied_mask & (1 << TYPE_INDEX))
{
LL_INFOS() << "Missing indices" << LL_ENDL;
}
Graham Madarasz (Graham Linden)
committed
LL_WARNS() << "Shader consumption mismatches data provision." << LL_ENDL;
David Parks
committed
}
}
}
if (useVBOs())
{
David Parks
committed
if (mGLArray)
{
David Parks
committed
bindGLArray();
Leslie Linden
committed
setup = false; //do NOT perform pointer setup if using VAO
}
David Parks
committed
else
Leslie Linden
committed
const bool bindBuffer = bindGLBuffer();
const bool bindIndices = bindGLIndices();
setup = setup || bindBuffer || bindIndices;
David Parks
committed
if (gDebugGL && !mGLArray)
{
GLint buff;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff);
if (gDebugSession)
{
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
}
else
{
LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff);
if ((GLuint)buff != mGLIndices)
if (gDebugSession)
{
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
}
else
{
LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL;
David Parks
committed
}
else
{
if (sGLRenderArray)
{
David Parks
committed
glBindVertexArray(0);
David Parks
committed
sGLRenderArray = 0;
David Parks
committed
sGLRenderIndices = 0;
}
if (mGLBuffer)
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
sBindCount++;
Leslie Linden
committed
setup = true; // ... or a VBO is deactivated
}
if (sGLRenderBuffer != mGLBuffer)
{
David Parks
committed
sGLRenderBuffer = mGLBuffer;
Leslie Linden
committed
setup = true; // ... or a client memory pointer changed
David Parks
committed
if (mGLIndices)
David Parks
committed
if (sIBOActive)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
David Parks
committed
sBindCount++;
David Parks
committed
}
sGLRenderIndices = mGLIndices;
David Parks
committed
if (!mGLArray)
setupClientArrays(data_mask);
David Parks
committed
if (mGLBuffer)
{
if (data_mask && setup)
{
setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
sSetCount++;
}
}
}
// virtual (default)
David Parks
committed
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
stop_glerror();
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
{
U32 mask = 1 << i;
if (mask & data_mask && !(mask & mTypeMask))
{ //bit set in data_mask, but not set in mTypeMask
LL_WARNS() << "Missing required component " << vb_type_name[i] << LL_ENDL;
}
}
LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL;
David Parks
committed
if (LLGLSLShader::sNoFixedFunction)
David Parks
committed
if (data_mask & MAP_NORMAL)
David Parks
committed
S32 loc = TYPE_NORMAL;
void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
David Parks
committed
if (data_mask & MAP_TEXCOORD3)
David Parks
committed
S32 loc = TYPE_TEXCOORD3;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
David Parks
committed
if (data_mask & MAP_TEXCOORD2)
David Parks
committed
S32 loc = TYPE_TEXCOORD2;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
David Parks
committed
if (data_mask & MAP_TEXCOORD1)
David Parks
committed
S32 loc = TYPE_TEXCOORD1;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
David Parks
committed
if (data_mask & MAP_TANGENT)
David Parks
committed
S32 loc = TYPE_TANGENT;
void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
glVertexAttribPointer(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
David Parks
committed
if (data_mask & MAP_TEXCOORD0)
David Parks
committed
S32 loc = TYPE_TEXCOORD0;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
David Parks
committed
if (data_mask & MAP_COLOR)
David Parks
committed
S32 loc = TYPE_COLOR;
//bind emissive instead of color pointer if emissive is present
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
David Parks
committed
if (data_mask & MAP_EMISSIVE)
David Parks
committed
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
if (!(data_mask & MAP_COLOR))
{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
loc = TYPE_COLOR;
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
David Parks
committed
if (data_mask & MAP_WEIGHT)
David Parks
committed
S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
David Parks
committed
if (data_mask & MAP_WEIGHT4)
David Parks
committed
S32 loc = TYPE_WEIGHT4;
void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
David Parks
committed
if (data_mask & MAP_CLOTHWEIGHT)
David Parks
committed
S32 loc = TYPE_CLOTHWEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
David Parks
committed
if (data_mask & MAP_TEXTURE_INDEX &&
(gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
S32 loc = TYPE_TEXTURE_INDEX;
David Parks
committed
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
David Parks
committed
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
David Parks
committed
if (data_mask & MAP_VERTEX)
{
S32 loc = TYPE_VERTEX;
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
David Parks
committed
}
}
else
David Parks
committed
if (data_mask & MAP_NORMAL)
David Parks
committed
glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
David Parks
committed
if (data_mask & MAP_TEXCOORD3)
{
glClientActiveTexture(GL_TEXTURE3);
David Parks
committed
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
glClientActiveTexture(GL_TEXTURE0);
David Parks
committed
if (data_mask & MAP_TEXCOORD2)
David Parks
committed
{
glClientActiveTexture(GL_TEXTURE2);
David Parks
committed
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
glClientActiveTexture(GL_TEXTURE0);
David Parks
committed
}
David Parks
committed
if (data_mask & MAP_TEXCOORD1)
glClientActiveTexture(GL_TEXTURE1);
David Parks
committed
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
glClientActiveTexture(GL_TEXTURE0);
David Parks
committed
if (data_mask & MAP_TANGENT)
{
glClientActiveTexture(GL_TEXTURE2);
David Parks
committed
glTexCoordPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
glClientActiveTexture(GL_TEXTURE0);
David Parks
committed
if (data_mask & MAP_TEXCOORD0)
David Parks
committed
{
David Parks
committed
glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
David Parks
committed
}
David Parks
committed
if (data_mask & MAP_COLOR)
David Parks
committed
{
David Parks
committed
glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
David Parks
committed
if (data_mask & MAP_VERTEX)
David Parks
committed
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
}
}
llglassertok();
}
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{