//----------------------------------------------------------------------- void BillboardChain::setupVertexDeclaration(void) { if (mVertexDeclDirty) { VertexDeclaration* decl = mVertexData->vertexDeclaration; decl->removeAllElements(); size_t offset = 0; // Add a description for the buffer of the positions of the vertices decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (mUseVertexColour) { decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); } if (mUseTexCoords) { decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); } if (!mUseTexCoords && !mUseVertexColour) { LogManager::getSingleton().logMessage( "Error - BillboardChain '" + mName + "' is using neither " "texture coordinates or vertex colours; it will not be " "visible on some rendering APIs so you should change this " "so you use one or the other."); } mVertexDeclDirty = false; } }
//--------------------------------------------------------------------- void BorderPanelOverlayElement::initialise(void) { bool init = !mInitialised; // init mRenderOp2 before calling superclass, as virtual _restoreManualHardwareResources would be called within if (init) { // Setup render op in advance mRenderOp2.vertexData = OGRE_NEW VertexData(); mRenderOp2.vertexData->vertexCount = 4 * 8; // 8 cells, can't necessarily share vertices cos // texcoords may differ mRenderOp2.vertexData->vertexStart = 0; // Vertex declaration VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration; // Position and texture coords each have their own buffers to allow // each to be edited separately with the discard flag decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // Index data mRenderOp2.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp2.useIndexes = true; mRenderOp2.indexData = OGRE_NEW IndexData(); mRenderOp2.indexData->indexCount = 8 * 6; mRenderOp2.indexData->indexStart = 0; mRenderOp2.useGlobalInstancingVertexBufferIsAvailable = false; // Create sub-object for rendering border mBorderRenderable = OGRE_NEW BorderRenderable(this); } // superclass will handle the interior panel area and call _restoreManualHardwareResources PanelOverlayElement::initialise(); }
void TextAreaOverlayElement::initialise(void) { if (!mInitialised) { // Set up the render op // Combine positions and texture coords since they tend to change together // since character sizes are different mRenderOp.vertexData = OGRE_NEW VertexData(); VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; size_t offset = 0; // Positions decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); // Texcoords decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // Colours - store these in a separate buffer because they change less often decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; mRenderOp.vertexData->vertexStart = 0; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; // Vertex buffer will be created in checkMemoryAllocation mRenderOp.srcRenderable = this; checkMemoryAllocation( DEFAULT_INITIAL_CHARS ); mInitialised = true; } }
//--------------------------------------------------------------------- void PrefabFactory::createPlane(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); float vertices[32] = { -100, -100, 0, // pos 0,0,1, // normal 0,1, // texcoord 100, -100, 0, 0,0,1, 1,1, 100, 100, 0, 0,0,1, 1,0, -100, 100, 0 , 0,0,1, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = 4; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[6] = {0,1,2, 0,2,3 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = 6; sub->indexData->indexStart =0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); }
ProceduralManualObject* createProceduralParticleSystem() { particleSystem = static_cast<ProceduralManualObject*> (mSceneMgr->createMovableObject("ParticleGSEntity", ProceduralManualObjectFactory::FACTORY_TYPE_NAME)); particleSystem->setMaterial("Ogre/ParticleGS/Display"); //Generate the geometry that will seed the particle system ManualObject* particleSystemSeed = mSceneMgr->createManualObject("ParticleSeed"); //This needs to be the initial launcher particle particleSystemSeed->begin("Ogre/ParticleGS/Display", RenderOperation::OT_POINT_LIST); particleSystemSeed->position(0,0,0); //Position particleSystemSeed->textureCoord(1); //Timer particleSystemSeed->textureCoord(0); //Type particleSystemSeed->textureCoord(0,0,0); //Velocity particleSystemSeed->end(); //Generate the RenderToBufferObject RenderToVertexBufferSharedPtr r2vbObject = HardwareBufferManager::getSingleton().createRenderToVertexBuffer(); r2vbObject->setRenderToBufferMaterialName("Ogre/ParticleGS/Generate"); //Apply the random texture TexturePtr randomTexture = RandomTools::generateRandomVelocityTexture(); r2vbObject->getRenderToBufferMaterial()->getTechnique(0)->getPass(0)-> getTextureUnitState("RandomTexture")->setTextureName( randomTexture->getName(), randomTexture->getTextureType()); r2vbObject->setOperationType(RenderOperation::OT_POINT_LIST); r2vbObject->setMaxVertexCount(16000); r2vbObject->setResetsEveryUpdate(false); VertexDeclaration* vertexDecl = r2vbObject->getVertexDeclaration(); size_t offset = 0; offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_POSITION).getSize(); //Position offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 0).getSize(); //Timer offset += vertexDecl->addElement(0, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 1).getSize(); //Type offset += vertexDecl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES, 2).getSize(); //Velocity //Bind the two together particleSystem->setRenderToVertexBuffer(r2vbObject); particleSystem->setManualObject(particleSystemSeed); //Set bounds AxisAlignedBox aabb; aabb.setMinimum(-100,-100,-100); aabb.setMaximum(100,100,100); particleSystem->setBoundingBox(aabb); return particleSystem; }
//-------------------------------------------------------------------------------// void OverlayPanelElement::initialise(const String& texName, float width, float height, float left, float top) { mTexture = TextureMgr::getSingletonPtr()->getByName(texName); setSize(width, height); setPosition(left, top); mIsVisible = true; if(!mIsInitialised) { mRenderData.vertexData = TITAN_NEW VertexData(); VertexDeclaration* decl = mRenderData.vertexData->vertexDecl; decl->addElement(0,0, VET_FLOAT3, VES_POSITION); mRenderData.vertexData->vertexStart = 0; mRenderData.vertexData->vertexCount = 4; VertexBufferPtr vbuf = HardwareBufferMgr::getSingletonPtr()->createVertexBuffer(decl->getVertexSize(0), mRenderData.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); mRenderData.vertexData->vertexBufferBinding->setBinding(0, vbuf); mRenderData.useIndex = false; mRenderData.operationType = OT_TRIANGLE_STRIP; mIsInitialised = true; } notifyGeometryOld(); }
void WireBoundingBox::_initWireBoundingBox() { mRenderOp.vertexData = OGRE_NEW VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 24; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.useIndexes = false; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); // set basic white material this->setMaterial("BaseWhiteNoLighting"); }
//--------------------------------------------------------------------- void PanelOverlayElement::initialise(void) { bool init = !mInitialised; OverlayContainer::initialise(); if (init) { // Setup render op in advance mRenderOp.vertexData = OGRE_NEW VertexData(); // Vertex declaration: 1 position, add texcoords later depending on #layers // Create as separate buffers so we can lock & discard separately VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); // Basic vertex data mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = 4; // Vertex buffer #1 HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing ); // Bind buffer mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf); // No indexes & issue as a strip mRenderOp.useIndexes = false; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mInitialised = true; } }
void GeomUtils::createQuad(VertexData*& vertexData) { assert(vertexData); vertexData->vertexCount = 4; vertexData->vertexStart = 0; VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; VertexBufferBinding* bind = vertexData->vertexBufferBinding; vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(0, vbuf); // Upload data float data[]={ -1,1,-1, // corner 1 -1,-1,-1, // corner 2 1,1,-1, // corner 3 1,-1,-1}; // corner 4 vbuf->writeData(0, sizeof(data), data, true); }
//--------------------------------------------------------------------- void PanelOverlayElement::initialise(void) { bool init = !mInitialised; OverlayContainer::initialise(); if (init) { // Setup render op in advance mRenderOp.vertexData = OGRE_NEW VertexData(); // Vertex declaration: 1 position, add texcoords later depending on #layers // Create as separate buffers so we can lock & discard separately VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); // Basic vertex data mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = 4; // No indexes & issue as a strip mRenderOp.useIndexes = false; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; mInitialised = true; _restoreManualHardwareResources(); } }
void Line3D::drawLines(void) { if(mDrawn) return; else mDrawn = true; // Initialization stuff mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = mPoints.size(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_LINE_LIST; // OT_LINE_LIST, OT_LINE_STRIP mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(POSITION_BINDING, vbuf); // Drawing stuff int size = mPoints.size(); Vector3 vaabMin = mPoints[0]; Vector3 vaabMax = mPoints[0]; Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); for(int i = 0; i < size; i++) { *prPos++ = mPoints[i].x; *prPos++ = mPoints[i].y; *prPos++ = mPoints[i].z; if(mPoints[i].x < vaabMin.x) vaabMin.x = mPoints[i].x; if(mPoints[i].y < vaabMin.y) vaabMin.y = mPoints[i].y; if(mPoints[i].z < vaabMin.z) vaabMin.z = mPoints[i].z; if(mPoints[i].x > vaabMax.x) vaabMax.x = mPoints[i].x; if(mPoints[i].y > vaabMax.y) vaabMax.y = mPoints[i].y; if(mPoints[i].z > vaabMax.z) vaabMax.z = mPoints[i].z; } vbuf->unlock(); mBox.setExtents(vaabMin, vaabMax); }
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(); }
DebugRectangle2D::DebugRectangle2D() : SimpleRenderable () { #ifdef PLSM2_EIHORT mUseIdentityProjection = true; mUseIdentityView = true; #endif mRenderOp.indexData = new IndexData(); mRenderOp.vertexData = new VertexData(); mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.indexData->indexCount = 8; mRenderOp.vertexData->vertexCount = 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.useIndexes = true; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); const size_t offset = VertexElement::getTypeSize(VET_FLOAT3); decl->addElement (POSITION_BINDING, offset, VET_COLOUR, VES_DIFFUSE); mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mRenderOp.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); SimpleRenderable::setBoundingBox(AxisAlignedBox(-1000 * Vector3::UNIT_SCALE, 1000 * Vector3::UNIT_SCALE)); SimpleRenderable::setRenderQueueGroup (RENDER_QUEUE_OVERLAY); // set basic white material SimpleRenderable::setMaterial("BaseWhiteNoLighting"); }
//----------------------------------------------------------------------------- VertexDeclaration* VertexDeclaration::clone(void) { VertexDeclaration* ret = HardwareBufferManager::getSingleton().createVertexDeclaration(); VertexElementList::const_iterator i, iend; iend = mElementList.end(); for (i = mElementList.begin(); i != iend; ++i) { ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex()); } return ret; }
void EffectBillboardChain::_createBuffer(void) { if (mRenderOp.vertexData) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; } mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = NULL; mRenderOp.vertexData->vertexCount = mCurrentNbChainElements * 2; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; // Add a description for the buffer of the positions of the vertices size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT2); // Create the buffer HardwareVertexBufferSharedPtr pVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mCurrentNbChainElements * 2, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind the buffer bind->setBinding(0, pVertexBuffer); }
SurfacePatchRenderable::SurfacePatchRenderable() : SimpleRenderable() { // Set up what we can of the vertex data mRenderOp.vertexData = new VertexData(); mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = 0; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; // Set up what we can of the index data mRenderOp.indexData = new IndexData(); mRenderOp.useIndexes = true; mRenderOp.indexData->indexStart = 0; mRenderOp.indexData->indexCount = 0; // Set up the vertex declaration VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; decl->removeAllElements(); decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); decl->addElement(0, 3 * sizeof(float), VET_FLOAT3, VES_NORMAL); decl->addElement(0, 6 * sizeof(float), VET_FLOAT3, VES_TEXTURE_COORDINATES); decl->addElement(0, 9 * sizeof(float), VET_FLOAT3, VES_TEXTURE_COORDINATES, 1); }
//-------------------------------------------------------------------------------// void OverlayPanelElement::updateTexData() { if(!mTexture.isNull() &&mIsInitialised) { VertexDeclaration* decl = mRenderData.vertexData->vertexDecl; if(mTexCoordNum == 0) { decl->addElement(1, 0,VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); VertexBufferPtr vbuf = HardwareBufferMgr::getSingletonPtr()->createVertexBuffer(decl->getVertexSize(1), mRenderData.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); mRenderData.vertexData->vertexBufferBinding->setBinding(1,vbuf); mTexCoordNum = 1; } if(mTexCoordNum) { VertexBufferPtr buf = mRenderData.vertexData->vertexBufferBinding->getBuffer(1); float* pVBStart = static_cast<float*>(buf->lock(HardwareBuffer::HBL_DISCARD)); size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float); size_t vertexSize = decl->getVertexSize(1) / sizeof(float); float* pTex = pVBStart; pTex[0] = mU1; pTex[1] = mV1; pTex += vertexSize; pTex[0] = mU1; pTex[1] = mV2; pTex += vertexSize; pTex[0] = mU2; pTex[1] = mV1; pTex += vertexSize; pTex[0] = mU2; pTex[1] = mV2; buf->unlock(); } } }
//--------------------------------------------------------------------- void PanelOverlayElement::updateTextureGeometry(void) { // Generate for as many texture layers as there are in material if (!mpMaterial.isNull() && mInitialised) { // Assume one technique and pass for the moment size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates(); VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; // Check the number of texcoords we have in our buffer now if (mNumTexCoordsInBuffer > numLayers) { // remove extras for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i) { decl->removeElement(VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i)); } } else if (mNumTexCoordsInBuffer < numLayers) { // Add extra texcoord elements size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer; for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i) { decl->addElement(TEXCOORD_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i)); offset += VertexElement::getTypeSize(VET_FLOAT2); } } // if number of layers changed at all, we'll need to reallocate buffer if (mNumTexCoordsInBuffer != numLayers) { // NB reference counting will take care of the old one if it exists HardwareVertexBufferSharedPtr newbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing ); // Bind buffer, note this will unbind the old one and destroy the buffer it had mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf); // Set num tex coords in use now mNumTexCoordsInBuffer = numLayers; } // Get the tcoord buffer & lock if (mNumTexCoordsInBuffer) { HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); float* pVBStart = static_cast<float*>( vbuf->lock(HardwareBuffer::HBL_DISCARD) ); size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float); size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float); for (ushort i = 0; i < numLayers; ++i) { // Calc upper tex coords Real upperX = mU2 * mTileX[i]; Real upperY = mV2 * mTileY[i]; /* 0-----2 | /| | / | |/ | 1-----3 */ // Find start offset for this set float* pTex = pVBStart + (i * uvSize); pTex[0] = mU1; pTex[1] = mV1; pTex += vertexSize; // jump by 1 vertex stride pTex[0] = mU1; pTex[1] = upperY; pTex += vertexSize; pTex[0] = upperX; pTex[1] = mV1; pTex += vertexSize; pTex[0] = upperX; pTex[1] = upperY; } vbuf->unlock(); } } }
//--------------------------------------------------------------------- void PrefabFactory::createSphere(Mesh* mesh) { // sphere creation code taken from the DeferredShading sample, originally from the wiki SubMesh *pSphereVertex = mesh->createSubMesh(); const int NUM_SEGMENTS = 16; const int NUM_RINGS = 16; const Real SPHERE_RADIUS = 50.0; mesh->sharedVertexData = OGRE_NEW VertexData(); VertexData* vertexData = mesh->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); // allocate the vertex buffer vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+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 * NUM_RINGS * (NUM_SEGMENTS + 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 / NUM_RINGS); float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS); unsigned short wVerticeIndex = 0 ; // Generate the group of rings for the sphere for( int ring = 0; ring <= NUM_RINGS; ring++ ) { float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle); float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle); // Generate the group of segments for the current ring for(int seg = 0; seg <= NUM_SEGMENTS; 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) NUM_SEGMENTS; *pVertex++ = (float) ring / (float) NUM_RINGS; if (ring != NUM_RINGS) { // each vertex (except the last) has six indicies pointing to it *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; *pIndices++ = wVerticeIndex; *pIndices++ = wVerticeIndex + NUM_SEGMENTS; *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 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: mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false ); mesh->_setBoundingSphereRadius(SPHERE_RADIUS); }
//--------------------------------------------------------------------- void PrefabFactory::createCube(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides const int NUM_ENTRIES_PER_VERTEX = 8; const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides const Real CUBE_SIZE = 100.0f; const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; // Create 4 vertices per side instead of 6 that are shared for the whole cube. // The reason for this is with only 6 vertices the normals will look bad // since each vertex can "point" in a different direction depending on the face it is included in. float vertices[NUM_VERTEX_ENTRIES] = { // front side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos 0,0,1, // normal 0,1, // texcoord CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , 0,0,1, 0,0, // back side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,0, // left side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,0, // right side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,0, // up side -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 0,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 0,0, // down side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 1,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 1,0, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = NUM_VERTICES; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, NUM_INDICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[NUM_INDICES] = { // front 0,1,2, 0,2,3, // back 4,5,6, 4,6,7, // left 8,9,10, 8,10,11, // right 12,13,14, 12,14,15, // up 16,17,18, 16,18,19, // down 20,21,22, 20,22,23 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = NUM_INDICES; sub->indexData->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); }
void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) { // use identity projection and view matrices mUseIdentityProjection = true; mUseIdentityView = true; mRenderOp.vertexData = OGRE_NEW VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexCount = 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(NORMAL_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); bind->setBinding(NORMAL_BINDING, vbuf); float *pNorm = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; *pNorm++ = 0.0f; *pNorm++ = 0.0f; *pNorm++ = 1.0f; vbuf->unlock(); if (includeTextureCoords) { decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); HardwareVertexBufferSharedPtr tvbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); // Bind buffer bind->setBinding(TEXCOORD_BINDING, tvbuf); // Set up basic tex coordinates setDefaultUVs(); } // set basic white material this->setMaterial("BaseWhiteNoLighting"); }
WaterMesh::WaterMesh(const String& inMeshName, Real planeSize, int inComplexity) { int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;( this->meshName = inMeshName ; this->complexity = inComplexity ; numFaces = 2 * complexity * complexity; numVertices = (complexity + 1) * (complexity + 1) ; lastTimeStamp = 0 ; lastAnimationTimeStamp = 0; lastFrameTime = 0 ; // initialize algorithm parameters PARAM_C = 0.3f ; // ripple speed PARAM_D = 0.4f ; // distance PARAM_U = 0.05f ; // viscosity PARAM_T = 0.13f ; // time useFakeNormals = false ; // allocate space for normal calculation vNormals = new Vector3[numVertices]; // create mesh and submesh mesh = MeshManager::getSingleton().createManual(meshName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); subMesh = mesh->createSubMesh(); subMesh->useSharedVertices=false; // Vertex buffers subMesh->vertexData = new VertexData(); subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = numVertices; VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration; VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding; vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL); vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); // Prepare buffer for positions - todo: first attempt, slow posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), numVertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(0, posVertexBuffer); // Prepare buffer for normals - write only normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), numVertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(1, normVertexBuffer); // Prepare texture coords buffer - static one // todo: optimize to write directly into buffer float *texcoordsBufData = new float[numVertices*2]; for(y=0;y<=complexity;y++) { for(x=0;x<=complexity;x++) { texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ; texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ; } } texcoordsVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); texcoordsVertexBuffer->writeData(0, texcoordsVertexBuffer->getSizeInBytes(), texcoordsBufData, true); // true? delete [] texcoordsBufData; vbind->setBinding(2, texcoordsVertexBuffer); // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 3*numFaces, HardwareBuffer::HBU_STATIC, true); unsigned short *faceVertexIndices = (unsigned short*) indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); for(y=0 ; y<complexity ; y++) { for(x=0 ; x<complexity ; x++) { unsigned short *twoface = faceVertexIndices + (y*complexity+x)*2*3; int p0 = y*(complexity+1) + x ; int p1 = y*(complexity+1) + x + 1 ; int p2 = (y+1)*(complexity+1) + x ; int p3 = (y+1)*(complexity+1) + x + 1 ; twoface[0]=p2; //first tri twoface[1]=p1; twoface[2]=p0; twoface[3]=p2; //second tri twoface[4]=p3; twoface[5]=p1; } } indexBuffer->unlock(); // Set index buffer for this submesh subMesh->indexData->indexBuffer = indexBuffer; subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 3*numFaces; /* prepare vertex positions * note - we use 3 vertex buffers, since algorighm uses two last phases * to calculate the next one */ for(b=0;b<3;b++) { vertexBuffers[b] = new float[numVertices * 3] ; for(y=0;y<=complexity;y++) { for(x=0;x<=complexity;x++) { int numPoint = y*(complexity+1) + x ; float* vertex = vertexBuffers[b] + 3*numPoint ; vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ; vertex[1]= 0 ; // rand() % 30 ; vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ; } } } AxisAlignedBox meshBounds(0,0,0, planeSize,0, planeSize); mesh->_setBounds(meshBounds); currentBuffNumber = 0 ; posVertexBuffer->writeData(0, posVertexBuffer->getSizeInBytes(), // size vertexBuffers[currentBuffNumber], // source true); // discard? mesh->load(); mesh->touch(); }
void NxLine::createVertexDeclaration() { VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); if(mUseVertexColour)decl->addElement( TEXCOORD_BINDING, 0, VET_COLOUR, VES_DIFFUSE ); }
Mesh *GrassLoader::generateGrass_SPRITE(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount) { //Calculate the number of quads to be added unsigned int quadCount; quadCount = grassCount; // check for overflows of the uint16's unsigned int maxUInt16 = std::numeric_limits<uint16>::max(); if(grassCount > maxUInt16) { LogManager::getSingleton().logMessage("grass count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page"); return 0; } if(quadCount > maxUInt16) { LogManager::getSingleton().logMessage("quad count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page"); return 0; } //Create manual mesh to store grass quads MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); SubMesh *subMesh = mesh->createSubMesh(); subMesh->useSharedVertices = false; //Setup vertex format information subMesh->vertexData = new VertexData; subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = 4 * quadCount; VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration; size_t offset = 0; dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); dcl->addElement(0, offset, VET_FLOAT4, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT4); dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT2); //Populate a new vertex buffer with grass HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() .createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); //Calculate size variance float rndWidth = layer->maxWidth - layer->minWidth; float rndHeight = layer->maxHeight - layer->minHeight; float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY; float *posPtr = grassPositions; //Position array "iterator" for (uint16 i = 0; i < grassCount; ++i) { //Get the x and z positions from the position array float x = *posPtr++; float z = *posPtr++; //Calculate height float y; if (heightFunction){ y = heightFunction(x, z, heightFunctionUserData); } else { y = 0; } float x1 = (x - page.centerPoint.x); float z1 = (z - page.centerPoint.z); //Get the color at the grass position uint32 color; if (layer->colorMap) color = layer->colorMap->getColorAt(x, z, layer->mapBounds); else color = 0xFFFFFFFF; //Calculate size float rnd = *posPtr++; //The same rnd value is used for width and height to maintain aspect ratio float halfXScale = (layer->minWidth + rndWidth * rnd) * 0.5f; float scaleY = (layer->minHeight + rndHeight * rnd); //Randomly mirror grass textures float uvLeft, uvRight; if (*posPtr++ > 0.5f){ uvLeft = 0; uvRight = 1; } else { uvLeft = 1; uvRight = 0; } //Add vertices *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 1; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 1; //uv //Update bounds if (y < minY) minY = y; if (y + scaleY > maxY) maxY = y + scaleY; } vbuf->unlock(); subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); //Populate index buffer subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 6 * quadCount; subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton() .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); for (uint16 i = 0; i < quadCount; ++i) { uint16 offset = i * 4; *pI++ = 0 + offset; *pI++ = 2 + offset; *pI++ = 1 + offset; *pI++ = 1 + offset; *pI++ = 2 + offset; *pI++ = 3 + offset; } subMesh->indexData->indexBuffer->unlock(); //subMesh->setBuildEdgesEnabled(autoEdgeBuildEnabled); //Finish up mesh AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z, page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z); mesh->_setBounds(bounds); Vector3 temp = bounds.getMaximum() - bounds.getMinimum(); mesh->_setBoundingSphereRadius(temp.length() * 0.5f); LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0)); mesh->setAutoBuildEdgeLists(autoEdgeBuildEnabled); mesh->load(); LogManager::getSingleton().setLogDetail(LL_NORMAL); //Apply grass material to mesh subMesh->setMaterialName(layer->material->getName()); //Return the mesh return mesh.getPointer(); }
void MovableText::_setupGeometry() { assert(mpFont); assert(!mpMaterial.isNull()); unsigned int vertexCount = 0; //count letters to determine how many vertices are needed std::string::iterator i = mCaption.begin(); std::string::iterator iend = mCaption.end(); for ( ; i != iend; ++i ) { if ((*i != ' ') && (*i != '\n')) { vertexCount += 6; } } if (mRenderOp.vertexData) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; mUpdateColors = true; } if (mCaption.empty()) { return; } if (!mRenderOp.vertexData) mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vertexCount; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; size_t offset = 0; // create/bind positions/tex.ccord. buffer if (!decl->findElementBySemantic(VES_POSITION)) decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES)) decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, ptbuf); // Colours - store these in a separate buffer because they change less often if (!decl->findElementBySemantic(VES_DIFFUSE)) decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, cbuf); float *pPCBuff = static_cast<float*> (ptbuf->lock(HardwareBuffer::HBL_DISCARD)); Real spaceWidth = mSpaceWidth; // Derive space width from a capital A if (spaceWidth == 0) spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0; float total_height = mCharHeight; float total_width = 0.0f; float current_width = 0.0f; i = mCaption.begin(); iend = mCaption.end(); for ( ; i != iend; ++i ) { if (*i == '\n') { total_height += mCharHeight + 0.01; if ( current_width > total_width ) { total_width = current_width; current_width = 0.0; } } else { current_width += mpFont->getGlyphAspectRatio(*i) * mCharHeight * 2.0; } } if ( current_width > total_width ) { total_width = current_width; } float top = 0.0f; switch (mVerticalAlignment) { case MovableText::V_ABOVE: top = total_height * 2; break; case MovableText::V_CENTER: top = 0.5 * total_height * 2; break; case MovableText::V_BELOW: top = 0.0f; break; } float starting_left = 0.0f; switch (mHorizontalAlignment) { case MovableText::H_LEFT: starting_left = 0.0f; break; case MovableText::H_CENTER: starting_left = -total_width / 2.0f; break; } float left = starting_left; bool newLine = true; Real len = 0.0f; // for calculation of AABB Ogre::Vector3 min(9999999.0f), max(-9999999.0f), currPos(0.0f); Ogre::Real maxSquaredRadius = -99999999.0f; float largestWidth = 0.0f; for (i = mCaption.begin(); i != iend; ++i) { if (newLine) { len = 0.0f; for (String::iterator j = i; j != iend && *j != '\n'; j++) { if (*j == ' ') len += spaceWidth; else len += mpFont->getGlyphAspectRatio(*j) * mCharHeight * 2.0; } newLine = false; } if (*i == '\n') { left = starting_left; top -= mCharHeight * 2.0; newLine = true; continue; } if (*i == ' ') { // Just leave a gap, no tris left += spaceWidth; continue; } Real horiz_height = mpFont->getGlyphAspectRatio(*i); Real u1, u2, v1, v2; Ogre::Font::UVRect utmp; utmp = mpFont->getGlyphTexCoords(*i); u1 = utmp.left; u2 = utmp.right; v1 = utmp.top; v2 = utmp.bottom; // each vert is (x, y, z, u, v) //------------------------------------------------------------------------------------- // First tri // // Upper left currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v1; // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; // Bottom left currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v2; // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top += mCharHeight * 2.0; left += horiz_height * mCharHeight * 2.0; // Top right currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v1; //------------------------------------------------------------------------------------- // Deal with bounds min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); //------------------------------------------------------------------------------------- // Second tri // // Top right (again) currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v1; min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; left -= horiz_height * mCharHeight * 2.0; // Bottom left (again) currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u1; *pPCBuff++ = v2; min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); left += horiz_height * mCharHeight * 2.0; // Bottom right currPos = Ogre::Vector3(left, top, 0.0); *pPCBuff++ = currPos.x; *pPCBuff++ = currPos.y; *pPCBuff++ = currPos.z; *pPCBuff++ = u2; *pPCBuff++ = v2; //------------------------------------------------------------------------------------- min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); // Go back up with top top += mCharHeight * 2.0; float currentWidth = (left + 1) / 2 - 0; if (currentWidth > largestWidth) largestWidth = currentWidth; } // Unlock vertex buffer ptbuf->unlock(); // update AABB/Sphere radius mAABB = Ogre::AxisAlignedBox(min, max); mRadius = Ogre::Math::Sqrt(maxSquaredRadius); if (mUpdateColors) this->_updateColors(); mNeedUpdate = false; }
void _prepareMesh() { int i,lvl ; mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) ; subMesh = mesh->createSubMesh(); subMesh->useSharedVertices=false; int numVertices = 4 ; if (first) { // first Circle, create some static common data first = false ; // static buffer for position and normals posnormVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 6*sizeof(float), // size of one vertex data 4, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer float *posnormBufData = (float*) posnormVertexBuffer-> lock(HardwareBuffer::HBL_DISCARD); for(i=0;i<numVertices;i++) { posnormBufData[6*i+0]=((Real)(i%2)-0.5f)*CIRCLE_SIZE; // pos X posnormBufData[6*i+1]=0; // pos Y posnormBufData[6*i+2]=((Real)(i/2)-0.5f)*CIRCLE_SIZE; // pos Z posnormBufData[6*i+3]=0 ; // normal X posnormBufData[6*i+4]=1 ; // normal Y posnormBufData[6*i+5]=0 ; // normal Z } posnormVertexBuffer->unlock(); // static buffers for 16 sets of texture coordinates texcoordsVertexBuffers = new HardwareVertexBufferSharedPtr[16]; for(lvl=0;lvl<16;lvl++) { texcoordsVertexBuffers[lvl] = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), // size of one vertex data numVertices, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer float *texcoordsBufData = (float*) texcoordsVertexBuffers[lvl]-> lock(HardwareBuffer::HBL_DISCARD); float x0 = (Real)(lvl % 4) * 0.25 ; float y0 = (Real)(lvl / 4) * 0.25 ; y0 = 0.75-y0 ; // upside down for(i=0;i<4;i++) { texcoordsBufData[i*2 + 0]= x0 + 0.25 * (Real)(i%2) ; texcoordsBufData[i*2 + 1]= y0 + 0.25 * (Real)(i/2) ; } texcoordsVertexBuffers[lvl]->unlock(); } // Index buffer for 2 faces unsigned short faces[6] = {2,1,0, 2,3,1}; indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); indexBuffer->writeData(0, indexBuffer->getSizeInBytes(), faces, true); // true? } // Initialize vertex data subMesh->vertexData = new VertexData(); subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = 4; // first, set vertex buffer bindings VertexBufferBinding *vbind = subMesh->vertexData->vertexBufferBinding ; vbind->setBinding(0, posnormVertexBuffer); vbind->setBinding(1, texcoordsVertexBuffers[0]); // now, set vertex buffer declaration VertexDeclaration *vdecl = subMesh->vertexData->vertexDeclaration ; vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); vdecl->addElement(0, 3*sizeof(float), VET_FLOAT3, VES_NORMAL); vdecl->addElement(1, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); // Initialize index data subMesh->indexData->indexBuffer = indexBuffer; subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 6; // set mesh bounds AxisAlignedBox circleBounds(-CIRCLE_SIZE/2.0f, 0, -CIRCLE_SIZE/2.0f, CIRCLE_SIZE/2.0f, 0, CIRCLE_SIZE/2.0f); mesh->_setBounds(circleBounds); mesh->load(); mesh->touch(); }
/* ******************************************************************************* | implement of CGrassSticks ******************************************************************************* */ void CGrassSticks::createGrassMesh() { MeshPtr mesh = MeshManager::getSingleton().createManual(GRASS_MESH_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // create a submesh with the grass material SubMesh* sm = mesh->createSubMesh(); sm->setMaterialName("Examples/GrassBlades"); sm->useSharedVertices = false; sm->vertexData = OGRE_NEW VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = 12; sm->indexData->indexCount = 18; // specify a vertex format declaration for our mesh: 3 floats for position, 3 floats for normal, 2 floats for UV VertexDeclaration* decl = sm->vertexData->vertexDeclaration; decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); decl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL); decl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // create a vertex buffer HardwareVertexBufferSharedPtr vb = HardwareBufferManager::getSingleton().createVertexBuffer (decl->getVertexSize(0), sm->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); GrassVertex* verts = (GrassVertex*)vb->lock(HardwareBuffer::HBL_DISCARD); // start filling in vertex data for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { // planes intersect along the Y axis with 60 degrees between them Real x = Math::Cos(Degree(i * 60)) * GRASS_WIDTH / 2; Real z = Math::Sin(Degree(i * 60)) * GRASS_WIDTH / 2; for (unsigned int j = 0; j < 4; j++) // each plane has 4 vertices { GrassVertex& vert = verts[i * 4 + j]; vert.x = j < 2 ? -x : x; vert.y = j % 2 ? 0 : GRASS_HEIGHT; vert.z = j < 2 ? -z : z; // all normals point straight up vert.nx = 0; vert.ny = 1; vert.nz = 0; vert.u = j < 2 ? 0 : 1; vert.v = j % 2; } } vb->unlock(); // commit vertex changes sm->vertexData->vertexBufferBinding->setBinding(0, vb); // bind vertex buffer to our submesh // create an index buffer sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer (HardwareIndexBuffer::IT_16BIT, sm->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // start filling in index data Ogre::uint16* indices = (Ogre::uint16*)sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD); for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { unsigned int off = i * 4; // each plane consists of 2 triangles *indices++ = 0 + off; *indices++ = 3 + off; *indices++ = 1 + off; *indices++ = 0 + off; *indices++ = 2 + off; *indices++ = 3 + off; } sm->indexData->indexBuffer->unlock(); // commit index changes // update mesh AABB Ogre::AxisAlignedBox aabb; aabb.setExtents(-1,-1,-1,1,1,1); mesh->_setBounds(aabb); // Ogre::MeshSerializer serial; // serial.exportMesh(mesh.getPointer(), "grass.mesh"); }
void MovableText::_setupGeometry() { assert(mpFont); assert(!mpMaterial.isNull()); unsigned int vertexCount = static_cast<unsigned int>(mCaption.size() * 6); if (mRenderOp.vertexData) { // Removed this test as it causes problems when replacing a caption // of the same size: replacing "Hello" with "hello" // as well as when changing the text alignment //if (mRenderOp.vertexData->vertexCount != vertexCount) { delete mRenderOp.vertexData; mRenderOp.vertexData = NULL; mUpdateColors = true; } } if (!mRenderOp.vertexData) mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = vertexCount; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = false; VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; size_t offset = 0; // create/bind positions/tex.ccord. buffer if (!decl->findElementBySemantic(VES_POSITION)) decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES)) decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0); HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(POS_TEX_BINDING, ptbuf); // Colours - store these in a separate buffer because they change less often if (!decl->findElementBySemantic(VES_DIFFUSE)) decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(COLOUR_BINDING, cbuf); size_t charlen = mCaption.size(); float *pPCBuff = static_cast<float*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD)); float largestWidth = 0; float left = 0 * 2.0 - 1.0; float top = -((0 * 2.0) - 1.0); Real spaceWidth = mSpaceWidth; // Derive space width from a capital A if (spaceWidth == 0) spaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0; // for calculation of AABB Ogre::Vector3 min, max, currPos; Ogre::Real maxSquaredRadius; bool first = true; // Use iterator String::iterator i, iend; iend = mCaption.end(); bool newLine = true; Real len = 0.0f; Real verticalOffset = 0; switch (mVerticalAlignment) { case MovableText::V_ABOVE: verticalOffset = mCharHeight; break; case MovableText::V_CENTER: verticalOffset = 0.5*mCharHeight; break; case MovableText::V_BELOW: verticalOffset = 0; break; } // Raise the first line of the caption top += verticalOffset; for (i = mCaption.begin(); i != iend; ++i) { if (*i == '\n') top += verticalOffset * 2.0; } for (i = mCaption.begin(); i != iend; ++i) { if (newLine) { len = 0.0f; for (String::iterator j = i; j != iend && *j != '\n'; j++) { if (*j == ' ') len += spaceWidth; else len += mpFont->getGlyphAspectRatio((unsigned char)*j) * mCharHeight * 2.0; } newLine = false; } if (*i == '\n') { left = 0 * 2.0 - 1.0; top -= mCharHeight * 2.0; newLine = true; // Bugfix by Wladimir Lukutin - thanks :) // Also reduce tri count mRenderOp.vertexData->vertexCount -= 6; // Bugfix end. continue; } if (*i == ' ') { // Just leave a gap, no tris left += spaceWidth; // Also reduce tri count mRenderOp.vertexData->vertexCount -= 6; continue; } Real horiz_height = mpFont->getGlyphAspectRatio((unsigned char)*i); Real u1, u2, v1, v2; Ogre::Font::UVRect utmp; utmp = mpFont->getGlyphTexCoords((unsigned char)*i); u1 = utmp.left; u2 = utmp.right; v1 = utmp.top; v2 = utmp.bottom; // each vert is (x, y, z, u, v) //------------------------------------------------------------------------------------- // First tri // // Upper left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v1; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); if (first) { min = max = currPos; maxSquaredRadius = currPos.squaredLength(); first = false; } else { min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); } top -= mCharHeight * 2.0; // Bottom left if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top += mCharHeight * 2.0; left += horiz_height * mCharHeight * 2.0; // Top right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; //------------------------------------------------------------------------------------- // Deal with bounds if(mHorizontalAlignment == MovableText::H_LEFT) currPos = Ogre::Vector3(left, top, -1.0); else currPos = Ogre::Vector3(left - (len / 2), top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); //------------------------------------------------------------------------------------- // Second tri // // Top right (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v1; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); top -= mCharHeight * 2.0; left -= horiz_height * mCharHeight * 2.0; // Bottom left (again) if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u1; *pPCBuff++ = v2; currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); left += horiz_height * mCharHeight * 2.0; // Bottom right if(mHorizontalAlignment == MovableText::H_LEFT) *pPCBuff++ = left; else *pPCBuff++ = left - (len / 2); *pPCBuff++ = top; *pPCBuff++ = -1.0; *pPCBuff++ = u2; *pPCBuff++ = v2; //------------------------------------------------------------------------------------- currPos = Ogre::Vector3(left, top, -1.0); min.makeFloor(currPos); max.makeCeil(currPos); maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength()); // Go back up with top top += mCharHeight * 2.0; float currentWidth = (left + 1)/2 - 0; if (currentWidth > largestWidth) largestWidth = currentWidth; } // Unlock vertex buffer ptbuf->unlock(); // update AABB/Sphere radius mAABB = Ogre::AxisAlignedBox(min, max); mRadius = Ogre::Math::Sqrt(maxSquaredRadius); if (mUpdateColors) this->_updateColors(); mNeedUpdate = false; }
void ThingRenderable::initialise() { // Fill array with randomly oriented quads Vector3 ax, ay, az; Quaternion q; things.clear(); orbits.clear(); for(size_t x=0; x<mCount; x++) { ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); az = ax.crossProduct(ay); ay = az.crossProduct(ax); ax.normalise(); ay.normalise(); az.normalise(); q.FromAxes(ax, ay, az); //std::cerr << ax.dotProduct(ay) << " " << ay.dotProduct(az) << " " << az.dotProduct(ax) << std::endl; things.push_back(q); ax = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); ay = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); az = ax.crossProduct(ay); ay = az.crossProduct(ax); ax.normalise(); ay.normalise(); az.normalise(); q.FromAxes(ax, ay, az); orbits.push_back(q); } // Create buffers size_t nvertices = mCount*4; // n+1 planes //size_t elemsize = 2*3; // position, normal //size_t dsize = elemsize*nvertices; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Quads unsigned short *faces = new unsigned short[mCount*6]; for(uint16 x=0; x<uint16(mCount); x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+0; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); bind->setBinding(0, vbuf); //vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mCount*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mCount*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; }
void VolumeRenderable::initialise() { // Create geometry size_t nvertices = mSlices*4; // n+1 planes size_t elemsize = 3*3; size_t dsize = elemsize*nvertices; size_t x; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Create structures float *vertices = new float[dsize]; float coords[4][2] = { {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(x=0; x<mSlices; x++) { for(size_t y=0; y<4; y++) { float xcoord = coords[y][0]-0.5; float ycoord = coords[y][1]-0.5; float zcoord = -((float)x/(float)(mSlices-1) - 0.5f); // 1.0f .. a/(a+1) // coordinate vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f); // normal vertices[x*4*elemsize+y*elemsize+3] = 0.0f; vertices[x*4*elemsize+y*elemsize+4] = 0.0f; vertices[x*4*elemsize+y*elemsize+5] = 1.0f; // tex vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f); } } unsigned short *faces = new unsigned short[mSlices*6]; for(x=0; x<mSlices; x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+1; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT3); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mSlices*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mSlices*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] vertices; delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; // Create a brand new private material MaterialPtr material = MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", false, 0); // Manual, loader // Remove pre-created technique from defaults material->removeAllTechniques(); // Create a techinique and a pass and a texture unit Technique * technique = material->createTechnique(); Pass * pass = technique->createPass(); TextureUnitState * textureUnit = pass->createTextureUnitState(); // Set pass parameters pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setDepthWriteEnabled(false); pass->setCullingMode(CULL_NONE); pass->setLightingEnabled(false); // Set texture unit parameters textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); textureUnit->setTextureName(mTexture, TEX_TYPE_3D); textureUnit->setTextureFiltering(TFO_TRILINEAR); mUnit = textureUnit; m_pMaterial = material; }