本文整理汇总了C++中HardwareIndexBufferSharedPtr::lock方法的典型用法代码示例。如果您正苦于以下问题:C++ HardwareIndexBufferSharedPtr::lock方法的具体用法?C++ HardwareIndexBufferSharedPtr::lock怎么用?C++ HardwareIndexBufferSharedPtr::lock使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类HardwareIndexBufferSharedPtr
的用法示例。
在下文中一共展示了HardwareIndexBufferSharedPtr::lock方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addIndexData
//------------------------------------------------------------------------------------------------
void VertexIndexToShape::addIndexData(IndexData* data, const unsigned int offset) {
const unsigned int prev_size = mIndexCount;
mIndexCount += (unsigned int)data->indexCount;
unsigned int* tmp_ind = new unsigned int[mIndexCount];
if(mIndexBuffer) {
memcpy(tmp_ind, mIndexBuffer, sizeof(unsigned int) * prev_size);
delete[] mIndexBuffer;
}
mIndexBuffer = tmp_ind;
const unsigned int numTris = (unsigned int) data->indexCount / 3;
HardwareIndexBufferSharedPtr ibuf = data->indexBuffer;
const bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT);
unsigned int index_offset = prev_size;
if(use32bitindexes) {
const unsigned int* pInt = static_cast<unsigned int*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k) {
mIndexBuffer[index_offset ++] = offset + *pInt++;
mIndexBuffer[index_offset ++] = offset + *pInt++;
mIndexBuffer[index_offset ++] = offset + *pInt++;
}
ibuf->unlock();
} else {
const unsigned short* pShort = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
for(unsigned int k = 0; k < numTris; ++k) {
mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int>(*pShort++);
mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int>(*pShort++);
mIndexBuffer[index_offset ++] = offset + static_cast<unsigned int>(*pShort++);
}
ibuf->unlock();
}
}
示例2: createCone
void GeomUtils::createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData,
float radius , float height, int nVerticesInBase)
{
assert(vertexData && indexData);
// define the vertex format
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
// positions
vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
// allocate the vertex buffer
vertexData->vertexCount = nVerticesInBase + 1;
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
// allocate index buffer - cone and base
indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2));
indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
//Positions : cone head and base
for (int i=0; i<3; i++)
*pVertex++ = 0.0f;
//Base :
float fDeltaBaseAngle = (2 * Math::PI) / nVerticesInBase;
for (int i=0; i<nVerticesInBase; i++)
{
float angle = i * fDeltaBaseAngle;
*pVertex++ = radius * cosf(angle);
*pVertex++ = height;
*pVertex++ = radius * sinf(angle);
}
//Indices :
//Cone head to vertices
for (int i=0; i<nVerticesInBase; i++)
{
*pIndices++ = 0;
*pIndices++ = (i%nVerticesInBase) + 1;
*pIndices++ = ((i+1)%nVerticesInBase) + 1;
}
//Cone base
for (int i=0; i<nVerticesInBase-2; i++)
{
*pIndices++ = 1;
*pIndices++ = i + 3;
*pIndices++ = i + 2;
}
// Unlock
vBuf->unlock();
iBuf->unlock();
}
示例3:
void DebugRectangle2D::setCorners(Real left, Real top, Real right, Real bottom)
{
VertexDeclaration * const decl = mRenderOp.vertexData->vertexDeclaration;
const VertexElement* poselem = decl->findElementBySemantic(VES_POSITION);
const VertexElement* colorelem = decl->findElementBySemantic(VES_DIFFUSE);
HardwareVertexBufferSharedPtr vbuf =
mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
const size_t vertexSize = vbuf->getVertexSize ();
float *pPos;
RGBA *pColor;
Root * const root = Root::getSingletonPtr();
uchar* pMain = static_cast<uchar *>(
vbuf->lock(HardwareBuffer::HBL_DISCARD));
// #define V3(AX, AY, AZ, ACOLOR) poselem->baseVertexPointerToElement(pMain, &pPos); \
// *pPos++ = AX; *pPos++ = AY; *pPos++ = AZ; \
// pMain += vertexSize;
#define V3(A_X, A_Y, A_Z, ACOLOR) poselem->baseVertexPointerToElement(pMain, &pPos); \
*pPos++ = static_cast <float> (A_X); \
*pPos++ = static_cast <float> (A_Y); \
*pPos++ = static_cast <float> (A_Z); \
colorelem->baseVertexPointerToElement(pMain, &pColor); \
root->convertColourValue (ACOLOR, pColor); \
pMain += vertexSize;
V3(left, top, -1.0f, ColourValue::White)
V3(left, bottom, -1.0f, ColourValue::White)
V3(right, bottom, -1.0f, ColourValue::White)
V3(right, top, -1.0f, ColourValue::White)
vbuf->unlock();
HardwareIndexBufferSharedPtr iBuf = mRenderOp.indexData->indexBuffer;
ushort* pIdx = static_cast<ushort*>(
iBuf->lock(0, iBuf->getSizeInBytes(),HardwareBuffer::HBL_DISCARD));
*pIdx++ = static_cast<ushort> (0); *pIdx++ = static_cast<ushort> (1); // line 1
*pIdx++ = static_cast<ushort> (1); *pIdx++ = static_cast<ushort> (2);// line 2
*pIdx++ = static_cast<ushort> (2); *pIdx++ = static_cast<ushort> (3);// line 3
*pIdx++ = static_cast<ushort> (3); *pIdx++ = static_cast<ushort> (0);// line 4
iBuf->unlock();
}
示例4: createSphere
void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16)
{
MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
SubMesh *pSphereVertex = pSphere->createSubMesh();
pSphere->sharedVertexData = new VertexData();
VertexData* vertexData = pSphere->sharedVertexData;
// define the vertex format
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// positions
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// normals
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
// two dimensional texture coordinates
vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
currOffset += VertexElement::getTypeSize(VET_FLOAT2);
// allocate the vertex buffer
vertexData->vertexCount = (nRings + 1) * (nSegments + 1);
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
// allocate index buffer
pSphereVertex->indexData->indexCount = 6 * nRings * (nSegments + 1);
pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
float fDeltaRingAngle = (Math::PI / nRings);
float fDeltaSegAngle = (2 * Math::PI / nSegments);
unsigned short wVerticeIndex = 0;
// Generate the group of rings for the sphere
for (int ring = 0; ring <= nRings; ring++) {
float r0 = r * sinf(ring * fDeltaRingAngle);
float y0 = r * cosf(ring * fDeltaRingAngle);
// Generate the group of segments for the current ring
for (int seg = 0; seg <= nSegments; seg++) {
float x0 = r0 * sinf(seg * fDeltaSegAngle);
float z0 = r0 * cosf(seg * fDeltaSegAngle);
// Add one vertex to the strip which makes up the sphere
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
*pVertex++ = vNormal.x;
*pVertex++ = vNormal.y;
*pVertex++ = vNormal.z;
*pVertex++ = (float)seg / (float)nSegments;
*pVertex++ = (float)ring / (float)nRings;
if (ring != nRings) {
// each vertex (except the last) has six indices pointing to it
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex;
*pIndices++ = wVerticeIndex + nSegments;
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex + 1;
*pIndices++ = wVerticeIndex;
wVerticeIndex++;
}
}; // end for seg
} // end for ring
// Unlock
vBuf->unlock();
iBuf->unlock();
// Generate face list
pSphereVertex->useSharedVertices = true;
// the original code was missing this line:
pSphere->_setBounds(AxisAlignedBox(Vector3(-r, -r, -r), Vector3(r, r, r)), false);
pSphere->_setBoundingSphereRadius(r);
// this line makes clear the mesh is loaded (avoids memory leaks)
pSphere->load();
}
示例5: createHardwareBuffers
void SurfacePatchRenderable::createHardwareBuffers()
{
VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer(
mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
mRenderOp.vertexData->vertexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
bind->setBinding(0, vbuf);
HardwareIndexBufferSharedPtr ibuf =
HardwareBufferManager::getSingleton().createIndexBuffer(
HardwareIndexBuffer::IT_32BIT, // type of index
mRenderOp.indexData->indexCount, // number of indexes
HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
false); // no shadow buffer
mRenderOp.indexData->indexBuffer = ibuf;
Vector3 vaabMin(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max());
Vector3 vaabMax(0.0, 0.0, 0.0);
Real* prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
const float textureWeights[3][3] = {{1, 0, 0},
{0, 1, 0},
{0, 0, 1}};
/*const int textureNumberOffsets[3][3] = {{0, 1, 2},
{-1, 0, 1},
{-2, -1, 0}};*/
for (int v = 0; v < patch->numVertices * 2; v += 2)
{
// Position
*prPos++ = patch->vertices[v].x;
*prPos++ = patch->vertices[v].y;
*prPos++ = patch->vertices[v].z;
// Normal
*prPos++ = patch->vertices[v+1].x;
*prPos++ = patch->vertices[v+1].y;
*prPos++ = patch->vertices[v+1].z;
// texture weights
const int curIndex = patch->vertNumbers[v/2];
const int posInTriangle = curIndex % 3;
*prPos++ = textureWeights[posInTriangle][0];
*prPos++ = textureWeights[posInTriangle][1];
*prPos++ = textureWeights[posInTriangle][2];
// texture numbers
for (int i = 0; i < posInTriangle; i++)
*prPos++ = patch->textures[patch->indices[curIndex - (posInTriangle - i)]];
*prPos++ = patch->textures[patch->indices[curIndex]];
for (int i = posInTriangle + 1; i < 3; i++)
*prPos++ = patch->textures[patch->indices[curIndex + (i - posInTriangle)]];
// texture numbers
//*prPos++ = patch->textures[(v/2)/3*3 + 0] + 0.5f; // 0.5f: number between 0 and 1 as offset because in the shader,
//*prPos++ = patch->textures[(v/2)/3*3 + 1] + 0.5f; // floor() is used to determine the texture number as integer and this is
//*prPos++ = patch->textures[(v/2)/3*3 + 2] + 0.5f; // much too imprecise if the real texture numbers are passed in!
// Adjust bounding box ...
if (patch->vertices[v].x < vaabMin.x)
vaabMin.x = patch->vertices[v].x;
if (patch->vertices[v].y < vaabMin.y)
vaabMin.y = patch->vertices[v].y;
if (patch->vertices[v].z < vaabMin.z)
vaabMin.z = patch->vertices[v].z;
if (patch->vertices[v].x > vaabMax.x)
vaabMax.x = patch->vertices[v].x;
if (patch->vertices[v].y > vaabMax.y)
vaabMax.y = patch->vertices[v].y;
if (patch->vertices[v].z > vaabMax.z)
vaabMax.z = patch->vertices[v].z;
}
vbuf->unlock();
mBox.setExtents(vaabMin, vaabMax);
Ogre::uint* pIdx = static_cast<Ogre::uint*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
for (int i = 0; i < patch->numIndices; i++)
{
*pIdx++ = patch->indices[i];
}
ibuf->unlock();
// Clean up the surface patch as much as possible
delete[] patch->textures;
delete[] patch->vertNumbers;
}
示例6: while
//-----------------------------------------------------------------------
void MeshManager::tesselate2DMesh(SubMesh* sm, unsigned short meshWidth, unsigned short meshHeight,
bool doubleSided, HardwareBuffer::Usage indexBufferUsage, bool indexShadowBuffer)
{
// The mesh is built, just make a list of indexes to spit out the triangles
unsigned short vInc, v, iterations;
if (doubleSided)
{
iterations = 2;
vInc = 1;
v = 0; // Start with front
}
else
{
iterations = 1;
vInc = 1;
v = 0;
}
// Allocate memory for faces
// Num faces, width*height*2 (2 tris per square), index count is * 3 on top
sm->indexData->indexCount = (meshWidth-1) * (meshHeight-1) * 2 * iterations * 3;
sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().
createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
sm->indexData->indexCount, indexBufferUsage, indexShadowBuffer);
unsigned short v1, v2, v3;
//bool firstTri = true;
HardwareIndexBufferSharedPtr ibuf = sm->indexData->indexBuffer;
// Lock the whole buffer
unsigned short* pIndexes = static_cast<unsigned short*>(
ibuf->lock(HardwareBuffer::HBL_DISCARD) );
while (iterations--)
{
// Make tris in a zigzag pattern (compatible with strips)
unsigned short u = 0;
unsigned short uInc = 1; // Start with moving +u
unsigned short vCount = meshHeight - 1;
while (vCount--)
{
unsigned short uCount = meshWidth - 1;
while (uCount--)
{
// First Tri in cell
// -----------------
v1 = ((v + vInc) * meshWidth) + u;
v2 = (v * meshWidth) + u;
v3 = ((v + vInc) * meshWidth) + (u + uInc);
// Output indexes
*pIndexes++ = v1;
*pIndexes++ = v2;
*pIndexes++ = v3;
// Second Tri in cell
// ------------------
v1 = ((v + vInc) * meshWidth) + (u + uInc);
v2 = (v * meshWidth) + u;
v3 = (v * meshWidth) + (u + uInc);
// Output indexes
*pIndexes++ = v1;
*pIndexes++ = v2;
*pIndexes++ = v3;
// Next column
u += uInc;
}
// Next row
v += vInc;
u = 0;
}
// Reverse vInc for double sided
v = meshHeight - 1;
vInc = -vInc;
}
// Unlock
ibuf->unlock();
}
示例7: createSphere
void GeomUtils::createSphere(VertexData*& vertexData, IndexData*& indexData
, float radius
, int nRings, int nSegments
, bool bNormals
, bool bTexCoords)
{
assert(vertexData && indexData);
// define the vertex format
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// positions
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
if (bNormals)
{
// normals
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
}
// two dimensional texture coordinates
if (bTexCoords)
{
vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
}
// allocate the vertex buffer
vertexData->vertexCount = (nRings + 1) * (nSegments+1);
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
// allocate index buffer
indexData->indexCount = 6 * nRings * (nSegments + 1);
indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
float fDeltaRingAngle = (Math::PI / nRings);
float fDeltaSegAngle = (2 * Math::PI / nSegments);
unsigned short wVerticeIndex = 0 ;
// Generate the group of rings for the sphere
for( int ring = 0; ring <= nRings; ring++ ) {
float r0 = radius * sinf (ring * fDeltaRingAngle);
float y0 = radius * cosf (ring * fDeltaRingAngle);
// Generate the group of segments for the current ring
for(int seg = 0; seg <= nSegments; seg++) {
float x0 = r0 * sinf(seg * fDeltaSegAngle);
float z0 = r0 * cosf(seg * fDeltaSegAngle);
// Add one vertex to the strip which makes up the sphere
*pVertex++ = x0;
*pVertex++ = y0;
*pVertex++ = z0;
if (bNormals)
{
Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
*pVertex++ = vNormal.x;
*pVertex++ = vNormal.y;
*pVertex++ = vNormal.z;
}
if (bTexCoords)
{
*pVertex++ = (float) seg / (float) nSegments;
*pVertex++ = (float) ring / (float) nRings;
}
if (ring != nRings)
{
// each vertex (except the last) has six indices pointing to it
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex;
*pIndices++ = wVerticeIndex + nSegments;
*pIndices++ = wVerticeIndex + nSegments + 1;
*pIndices++ = wVerticeIndex + 1;
*pIndices++ = wVerticeIndex;
wVerticeIndex ++;
}
}; // end for seg
} // end for ring
// Unlock
vBuf->unlock();
iBuf->unlock();
}
示例8: createSphereMesh
void createSphereMesh(const String &name, const float radius, const int slices, const int stacks)
{
MeshPtr mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
mesh->sharedVertexData = new VertexData();
mesh->_setBounds(AxisAlignedBox(Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius)));
mesh->_setBoundingSphereRadius(radius);
VertexData *vertexData = mesh->sharedVertexData;
vertexData->vertexDeclaration->addElement(0, 0, VET_FLOAT3, VES_POSITION);
vertexData->vertexDeclaration->addElement(1, 0, VET_FLOAT3, VES_NORMAL);
vertexData->vertexCount = slices * (stacks + 1);
HardwareVertexBufferSharedPtr positionBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
vertexData->vertexDeclaration->getVertexSize(0),
vertexData->vertexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
HardwareVertexBufferSharedPtr normalBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
vertexData->vertexDeclaration->getVertexSize(1),
vertexData->vertexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
float *position = static_cast<float *>(positionBuffer->lock(HardwareBuffer::HBL_DISCARD));
float *normal = static_cast<float *>(normalBuffer->lock(HardwareBuffer::HBL_DISCARD));
for (int ring = 0; ring <= stacks; ring++) {
float r = radius * sinf(ring * Math::PI / stacks);
float y = radius * cosf(ring * Math::PI / stacks);
for (int segment = 0; segment < slices; segment++) {
float x = r * sinf(segment * 2 * Math::PI / slices);
float z = r * cosf(segment * 2 * Math::PI / slices);
*position++ = x;
*position++ = y;
*position++ = z;
Vector3 tmp = Vector3(x, y, z).normalisedCopy();
*normal++ = tmp.x;
*normal++ = tmp.y;
*normal++ = tmp.z;
}
}
positionBuffer->unlock();
normalBuffer->unlock();
vertexData->vertexBufferBinding->setBinding(0, positionBuffer);
vertexData->vertexBufferBinding->setBinding(1, normalBuffer);
SubMesh *subMesh = mesh->createSubMesh();
subMesh->useSharedVertices = true;
IndexData *indexData = subMesh->indexData;
indexData->indexCount = 6 * slices * stacks;
HardwareIndexBufferSharedPtr indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
HardwareIndexBuffer::IT_16BIT,
indexData->indexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
unsigned short *index = static_cast<unsigned short *>(indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
unsigned short i = 0;
for (int ring = 0; ring < stacks; ring++) {
for (int segment = 0; segment < slices - 1; segment++) {
*index++ = i;
*index++ = i + slices;
*index++ = i + slices + 1;
*index++ = i;
*index++ = i + slices + 1;
*index++ = i + 1;
i++;
}
*index++ = i;
*index++ = i + slices;
*index++ = i + 1;
*index++ = i;
*index++ = i + 1;
*index++ = i + 1 - slices;
i++;
}
indexBuffer->unlock();
indexData->indexBuffer = indexBuffer;
mesh->load();
}
示例9: processFaces
//---------------------------------------------------------------------
void TangentSpaceCalc::processFaces(Result& result)
{
// Quick pre-check for triangle strips / fans
for (OpTypeList::iterator ot = mOpTypes.begin(); ot != mOpTypes.end(); ++ot)
{
if (*ot != RenderOperation::OT_TRIANGLE_LIST)
{
// Can't split strips / fans
setSplitMirrored(false);
setSplitRotated(false);
}
}
for (size_t i = 0; i < mIDataList.size(); ++i)
{
IndexData* i_in = mIDataList[i];
RenderOperation::OperationType opType = mOpTypes[i];
// Read data from buffers
uint16 *p16 = 0;
uint32 *p32 = 0;
HardwareIndexBufferSharedPtr ibuf = i_in->indexBuffer;
if (ibuf->getType() == HardwareIndexBuffer::IT_32BIT)
{
p32 = static_cast<uint32*>(
ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
// offset by index start
p32 += i_in->indexStart;
}
else
{
p16 = static_cast<uint16*>(
ibuf->lock(HardwareBuffer::HBL_READ_ONLY));
// offset by index start
p16 += i_in->indexStart;
}
// current triangle
size_t vertInd[3] = { 0, 0, 0 };
// loop through all faces to calculate the tangents and normals
size_t faceCount = opType == RenderOperation::OT_TRIANGLE_LIST ?
i_in->indexCount / 3 : i_in->indexCount - 2;
for (size_t f = 0; f < faceCount; ++f)
{
bool invertOrdering = false;
// Read 1 or 3 indexes depending on type
if (f == 0 || opType == RenderOperation::OT_TRIANGLE_LIST)
{
vertInd[0] = p32? *p32++ : *p16++;
vertInd[1] = p32? *p32++ : *p16++;
vertInd[2] = p32? *p32++ : *p16++;
}
else if (opType == RenderOperation::OT_TRIANGLE_FAN)
{
// Element 0 always remains the same
// Element 2 becomes element 1
vertInd[1] = vertInd[2];
// read new into element 2
vertInd[2] = p32? *p32++ : *p16++;
}
else if (opType == RenderOperation::OT_TRIANGLE_STRIP)
{
// Shunt everything down one, but also invert the ordering on
// odd numbered triangles (== even numbered i's)
// we interpret front as anticlockwise all the time but strips alternate
if (f & 0x1)
{
// odd tris (index starts at 3, 5, 7)
invertOrdering = true;
}
vertInd[0] = vertInd[1];
vertInd[1] = vertInd[2];
vertInd[2] = p32? *p32++ : *p16++;
}
// deal with strip inversion of winding
size_t localVertInd[3];
localVertInd[0] = vertInd[0];
if (invertOrdering)
{
localVertInd[1] = vertInd[2];
localVertInd[2] = vertInd[1];
}
else
{
localVertInd[1] = vertInd[1];
localVertInd[2] = vertInd[2];
}
// For each triangle
// Calculate tangent & binormal per triangle
// Note these are not normalised, are weighted by UV area
Vector3 faceTsU, faceTsV, faceNorm;
calculateFaceTangentSpace(localVertInd, faceTsU, faceTsV, faceNorm);
// Skip invalid UV space triangles
if (faceTsU.isZeroLength() || faceTsV.isZeroLength())
continue;
//.........这里部分代码省略.........
示例10: generateShadowVolume
// ------------------------------------------------------------------------
void ShadowCaster::generateShadowVolume(EdgeData* edgeData,
const HardwareIndexBufferSharedPtr& indexBuffer, const Light* light,
ShadowRenderableList& shadowRenderables, unsigned long flags)
{
// Edge groups should be 1:1 with shadow renderables
assert(edgeData->edgeGroups.size() == shadowRenderables.size());
EdgeData::EdgeGroupList::const_iterator egi, egiend;
ShadowRenderableList::const_iterator si;
Light::LightTypes lightType = light->getType();
// Lock index buffer for writing
unsigned short* pIdx = static_cast<unsigned short*>(
indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
size_t numIndices = 0;
// Iterate over the groups and form renderables for each based on their
// lightFacing
si = shadowRenderables.begin();
egiend = edgeData->edgeGroups.end();
for (egi = edgeData->edgeGroups.begin(); egi != egiend; ++egi, ++si)
{
const EdgeData::EdgeGroup& eg = *egi;
// Initialise the index start for this shadow renderable
IndexData* indexData = (*si)->getRenderOperationForUpdate()->indexData;
indexData->indexStart = numIndices;
// original number of verts (without extruded copy)
size_t originalVertexCount = eg.vertexData->vertexCount;
bool firstDarkCapTri = true;
unsigned short darkCapStart;
EdgeData::EdgeList::const_iterator i, iend;
iend = eg.edges.end();
for (i = eg.edges.begin(); i != iend; ++i)
{
const EdgeData::Edge& edge = *i;
// Silhouette edge, when two tris has opposite light facing, or
// degenerate edge where only tri 1 is valid and the tri light facing
char lightFacing = edgeData->triangleLightFacings[edge.triIndex[0]];
if ((edge.degenerate && lightFacing) ||
(!edge.degenerate && (lightFacing != edgeData->triangleLightFacings[edge.triIndex[1]])))
{
size_t v0 = edge.vertIndex[0];
size_t v1 = edge.vertIndex[1];
if (!lightFacing)
{
// Inverse edge indexes when t1 is light away
std::swap(v0, v1);
}
/* Note edge(v0, v1) run anticlockwise along the edge from
the light facing tri so to point shadow volume tris outward,
light cap indexes have to be backwards
We emit 2 tris if light is a point light, 1 if light
is directional, because directional lights cause all
points to converge to a single point at infinity.
First side tri = near1, near0, far0
Second tri = far0, far1, near1
'far' indexes are 'near' index + originalVertexCount
because 'far' verts are in the second half of the
buffer
*/
*pIdx++ = v1;
*pIdx++ = v0;
*pIdx++ = v0 + originalVertexCount;
numIndices += 3;
// Are we extruding to infinity?
if (!(lightType == Light::LT_DIRECTIONAL &&
flags & SRF_EXTRUDE_TO_INFINITY))
{
// additional tri to make quad
*pIdx++ = v0 + originalVertexCount;
*pIdx++ = v1 + originalVertexCount;
*pIdx++ = v1;
numIndices += 3;
}
// Do dark cap tri
// Use McGuire et al method, a triangle fan covering all silhouette
// edges and one point (taken from the initial tri)
if (flags & SRF_INCLUDE_DARK_CAP)
{
if (firstDarkCapTri)
{
darkCapStart = v0 + originalVertexCount;
firstDarkCapTri = false;
}
else
{
*pIdx++ = darkCapStart;
*pIdx++ = v1 + originalVertexCount;
*pIdx++ = v0 + originalVertexCount;
numIndices += 3;
//.........这里部分代码省略.........
示例11: getMeshInformation
//-----------------------------------------------------------------------------------------
bool TemplateUtils::getMeshInformation(const Mesh* mesh,
size_t &vertex_count,
OgreVector3Array &vertices,
size_t &index_count,
LongArray &indices,
const Vector3 position,
const Quaternion &orient,
const Vector3 &scale)
{
bool added_shared = false;
size_t current_offset = 0;
size_t shared_offset = 0;
size_t next_offset = 0;
size_t index_offset = 0;
vertex_count = index_count = 0;
// Calculate how many vertices and indices we're going to need
for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
SubMesh* submesh = mesh->getSubMesh(i);
if(!submesh) {
Exception(Exception::ERR_INTERNAL_ERROR,"Could not load submesh at index :" + i,"Mesh::getSubMesh");
}
// We only need to add the shared vertices once
if(submesh->useSharedVertices)
{
if( !added_shared )
{
vertex_count += mesh->sharedVertexData->vertexCount;
added_shared = true;
}
}
else
{
vertex_count += submesh->vertexData->vertexCount;
}
// Add the indices
index_count += submesh->indexData->indexCount;
}
// Allocate space for the vertices and indices
// NO VALID DATA SHOULD BE PRESENT IN THE FOLLOWING 2 ARRAYS
// UNTIL AFTER THE NEXT FOR LOOP
/*
vertices = new Ogre::Vector3 [vertex_count];
std::vector<Ogre::Vector3> vertices [vertex_count];
indices = new unsigned long [index_count];
std::vector<long> indices [index_count];
*/
vertices.resize(vertex_count);
indices.resize(index_count);
added_shared = false;
// Run through the submeshes again, adding the data into the arrays
for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
SubMesh* submesh = mesh->getSubMesh(i);
if(!submesh) {
Exception(Exception::ERR_INTERNAL_ERROR,"Could not load submesh at index :" + i,"Mesh::getSubMesh");
}
VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
{
if(submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
const VertexElement* posElem =
vertex_data->vertexDeclaration->findElementBySemantic(VES_POSITION);
HardwareVertexBufferSharedPtr vbuf =
vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex =
static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
// as second argument. So make it float, to avoid trouble when Ogre::Real will
// be comiled/typedefed as double:
//Ogre::Real* pReal;
float* pReal;
for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
{
posElem->baseVertexPointerToElement(vertex, &pReal);
Vector3 pt(pReal[0], pReal[1], pReal[2]);
vertices[current_offset + j] = (orient * (pt * scale)) + position;
}
vbuf->unlock();
next_offset += vertex_data->vertexCount;
//.........这里部分代码省略.........
示例12: importObject
static MeshPtr importObject(QDataStream &stream)
{
using namespace Ogre;
QVector4D bbMin, bbMax;
stream >> bbMin >> bbMax;
float distance, distanceSquared; // Here's a bug for you: writes "double"'s instead of floats
stream >> distanceSquared >> distance;
MeshPtr ogreMesh = MeshManager::getSingleton().createManual("conversion",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
int vertexCount, indexCount;
stream >> vertexCount >> indexCount;
VertexData *vertexData = new VertexData();
ogreMesh->sharedVertexData = vertexData;
LogManager::getSingleton().logMessage("Reading geometry...");
VertexDeclaration* decl = vertexData->vertexDeclaration;
VertexBufferBinding* bind = vertexData->vertexBufferBinding;
unsigned short bufferId = 0;
// Information for calculating bounds
Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE, pos = Vector3::ZERO;
Real maxSquaredRadius = -1;
bool firstVertex = true;
/*
Create a vertex definition for our buffer
*/
size_t offset = 0;
const VertexElement &positionElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_POSITION);
offset += VertexElement::getTypeSize(VET_FLOAT3);
const VertexElement &normalElement = decl->addElement(bufferId, offset, VET_FLOAT3, VES_NORMAL);
offset += VertexElement::getTypeSize(VET_FLOAT3);
// calculate how many vertexes there actually are
vertexData->vertexCount = vertexCount;
// Now create the vertex buffer
HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().
createVertexBuffer(offset, vertexData->vertexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
// Bind it
bind->setBinding(bufferId, vbuf);
// Lock it
unsigned char *pVert = static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
unsigned char *pVertStart = pVert;
QVector<float> positions;
positions.reserve(vertexCount * 3);
// Iterate over all children (vertexbuffer entries)
for (int i = 0; i < vertexCount; ++i) {
float *pFloat;
QVector4D vertex;
stream >> vertex;
vertex.setZ(vertex.z() * -1);
/* Copy over the position */
positionElement.baseVertexPointerToElement(pVert, &pFloat);
*(pFloat++) = (float)vertex.x();
*(pFloat++) = (float)vertex.y();
*(pFloat++) = (float)vertex.z();
positions.append(vertex.x());
positions.append(vertex.y());
positions.append(vertex.z());
/* While we're at it, calculate the bounding sphere */
pos.x = vertex.x();
pos.y = vertex.y();
pos.z = vertex.z();
if (firstVertex) {
min = max = pos;
maxSquaredRadius = pos.squaredLength();
firstVertex = false;
} else {
min.makeFloor(pos);
max.makeCeil(pos);
maxSquaredRadius = qMax(pos.squaredLength(), maxSquaredRadius);
}
pVert += vbuf->getVertexSize();
}
// Set bounds
const AxisAlignedBox& currBox = ogreMesh->getBounds();
Real currRadius = ogreMesh->getBoundingSphereRadius();
if (currBox.isNull())
{
//do not pad the bounding box
//.........这里部分代码省略.........
示例13: createIndexedFaceSet
//.........这里部分代码省略.........
std::swap(t.vertices[1], t.vertices[2]);
triangles.push_back(t);
triVerts[1] = vpos;
}
}
}
// createOgreMesh
int nvertices = vertices.size();
int nfaces = triangles.size();
VertexData* vertexData = new VertexData();
sub->vertexData = vertexData;
IndexData* indexData = sub->indexData;
VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
size_t currOffset = 0;
// positions
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
if (hasPointNormals)
{
// normals
vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
currOffset += VertexElement::getTypeSize(VET_FLOAT3);
}
// two dimensional texture coordinates
if (hasTextureCoordinates)
{
vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
currOffset += VertexElement::getTypeSize(VET_FLOAT2);
}
std::cout << std::endl;
// allocate index buffer
indexData->indexCount = nfaces * 3;
indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer;
unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));
std::cout << triangles.size() << ": ";
for(std::vector<triangle>::const_iterator T = triangles.begin(); T != triangles.end(); T++)
{
const triangle &t = (*T);
*pIndices++ = t.vertices[0];
*pIndices++ = t.vertices[1];
*pIndices++ = t.vertices[2];
std::cout << t.vertices[0] << " " << t.vertices[1] << " " << t.vertices[2] << " ";
}
std::cout << std::endl;
// allocate the vertex buffer
vertexData->vertexCount = nvertices;
HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
VertexBufferBinding* binding = vertexData->vertexBufferBinding;
binding->setBinding(0, vBuf);
float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));
AxisAlignedBox aabox;
std::cout << vertices.size() << ": ";
for(std::vector<vertex>::const_iterator V = vertices.begin(); V != vertices.end(); V++)
{
const vertex &v = (*V);
SFVec3f pos = _coords.at(v.pos);
*pVertex++ = pos.x;
*pVertex++ = pos.y;
*pVertex++ = pos.z;
aabox.merge(Vector3(pos.x, pos.y, pos.z));
std::cout << pos.x << " " << pos.y << " " << pos.z << " " << std::endl;
//std::cout << v.pos << " ";
if (hasPointNormals)
{
const SFVec3f normal = _normals.at(v.normal);
*pVertex++ = normal.x;
*pVertex++ = normal.y;
*pVertex++ = normal.z;
}
}
std::cout << std::endl;
// Unlock
vBuf->unlock();
iBuf->unlock();
sub->useSharedVertices = false;
// the original code was missing this line:
mesh->_setBounds(aabox);
mesh->_setBoundingSphereRadius((aabox.getMaximum()-aabox.getMinimum()).length()/2.0);
// this line makes clear the mesh is loaded (avoids memory leaks)
mesh->load();
}
示例14: getMeshInformation
void OgreToBulletMesh::getMeshInformation(MeshPtr mesh, unsigned& vertex_count, std::vector<Vector3>& vertices,
unsigned& index_count, std::vector<unsigned>& indices, const Vector3& position,
const Quaternion& orientation, const Vector3& scale)
{
bool added_shared = false;
unsigned current_offset = 0;
unsigned shared_offset = 0;
unsigned next_offset = 0;
unsigned index_offset = 0;
vertex_count = index_count = 0;
for (uint16_t i = 0; i < mesh->getNumSubMeshes(); ++i)
{
SubMesh* submesh = mesh->getSubMesh(i);
if (submesh->useSharedVertices)
{
if (!added_shared)
{
vertex_count += mesh->sharedVertexData->vertexCount;
added_shared = true;
}
}
else
vertex_count += submesh->vertexData->vertexCount;
index_count += submesh->indexData->indexCount;
}
vertices.clear();
vertices.reserve(vertex_count);
indices.clear();
indices.reserve(index_count);
added_shared = false;
for (uint16_t i = 0; i < mesh->getNumSubMeshes(); ++i)
{
SubMesh* submesh = mesh->getSubMesh(i);
VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
if (!submesh->useSharedVertices || (submesh->useSharedVertices && !added_shared))
{
if (submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
const VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(VertexElementSemantic::VES_POSITION);
HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
uint8_t* vertex = (uint8_t*)vbuf->lock(HardwareBuffer::LockOptions::HBL_READ_ONLY);
float* pReal;
for (int j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
{
posElem->baseVertexPointerToElement(vertex, &pReal);
Vector3 pt(pReal[0], pReal[1], pReal[2]);
vertices[current_offset + j] = (orientation * (pt * scale)) + position;
}
vbuf->unlock();
next_offset += vertex_data->vertexCount;
}
IndexData* index_data = submesh->indexData;
uint numTris = index_data->indexCount / 3;
HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
bool use32bitindexes = (ibuf->getType() == HardwareIndexBuffer::IndexType::IT_32BIT);
uint* pLong = (uint*)ibuf->lock(HardwareBuffer::LockOptions::HBL_READ_ONLY);
ushort* pShort = (ushort*)pLong;
uint offset = submesh->useSharedVertices ? shared_offset : current_offset;
if (use32bitindexes)
for (int k = 0; k < index_data->indexCount; ++k)
indices[index_offset++] = pLong[k] + offset;
else
for (int k = 0; k < index_data->indexCount; ++k)
indices[index_offset++] = (uint)pShort[k] + (uint)offset;
ibuf->unlock();
current_offset = next_offset;
}
}
示例15:
/// reads out mesh vertices and indices
/// must be called before rayintersect if the mesh has moved/deformed, probably every frame for animated meshes and mousepicking
/// calling it once for static meshes is enough
/// code is based on OgreOpCode MeshCollisionShape::convertMeshData
void MeshShape::Update (Ogre::Entity *pEntity) {
// if (!pEntity) return;
if (mpMesh.isNull()) return;
if (pEntity && mbInitialised && !pEntity->hasSkeleton()) return; // no need to update static models every frame...
mbInitialised = true;
//printf("#### MeshShape::Update\n");
//printf("MeshShape::Update skeleton=%d\n",pEntity->hasSkeleton()?1:0);
//assert(pEntity->getMesh().get() == mpMesh.get() && "mesh pointer changed ! (ogrecaching/garbage collection?)");
mlVertices.clear();
mlIndices.clear();
bool added_shared = false;
size_t current_offset = 0;
size_t shared_offset = 0;
size_t next_offset = 0;
size_t index_offset = 0;
int numOfSubs = 0;
// true if the entity is possibly animated (=has skeleton) , this means Update should be called every frame
bool useSoftwareBlendingVertices = pEntity && pEntity->hasSkeleton();
if (useSoftwareBlendingVertices)
{
pEntity->_updateAnimation();
}
// Run through the submeshes again, adding the data into the arrays
for ( size_t i = 0; i < mpMesh->getNumSubMeshes(); ++i) {
SubMesh* submesh = mpMesh->getSubMesh(i);
bool useSharedVertices = submesh->useSharedVertices;
//----------------------------------------------------------------
// GET VERTEXDATA
//----------------------------------------------------------------
const VertexData * vertex_data;
if(useSoftwareBlendingVertices)
vertex_data = useSharedVertices ? pEntity->_getSkelAnimVertexData() : pEntity->getSubEntity(i)->_getSkelAnimVertexData();
else vertex_data = useSharedVertices ? mpMesh->sharedVertexData : submesh->vertexData;
if((!useSharedVertices)||(useSharedVertices && !added_shared))
{
if(useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
const VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex =
static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_READ_ONLY));
// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
// as second argument. So make it float, to avoid trouble when Ogre::Real is
// comiled/typedefed as double:
float* pReal;
mlVertices.reserve(mlVertices.size()+vertex_data->vertexCount);
for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
{
posElem->baseVertexPointerToElement(vertex, &pReal);
if (mlVertices.size() == 0) {
mvMin.x = mvMax.x = pReal[0];
mvMin.y = mvMax.y = pReal[1];
mvMin.z = mvMax.z = pReal[2];
} else {
if (mvMin.x > pReal[0]) mvMin.x = pReal[0];
if (mvMin.y > pReal[1]) mvMin.y = pReal[1];
if (mvMin.z > pReal[2]) mvMin.z = pReal[2];
if (mvMax.x < pReal[0]) mvMax.x = pReal[0];
if (mvMax.y < pReal[1]) mvMax.y = pReal[1];
if (mvMax.z < pReal[2]) mvMax.z = pReal[2];
}
mlVertices.push_back(Vector3(pReal[0],pReal[1],pReal[2]));
}
vbuf->unlock();
next_offset += vertex_data->vertexCount;
}
// TODO : GET TEXCOORD DATA
// TODO : GET FACE-MATERIAL MAP, or at least material cound....
// TODO : no need to update index, texcoord and material buffers for animation !
// TODO : const VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
// for texture alpha checking, VertexElementType should be VET_FLOAT2
//----------------------------------------------------------------
// GET INDEXDATA
//----------------------------------------------------------------
IndexData* index_data = submesh->indexData;
//.........这里部分代码省略.........