OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: ManualSphereMeshes
View page
Source of version: 13
(current)
You could always generate a sphere in your favorite modeller, but given the nature of some of the ((OGRE Exporters|Ogre exporters)), it's not always so easy. The following code snippet will make a sphere, making full use of hardware ((-Vertex|vertex)) and ((Vertex and Index Buffers|index buffer))s for performance. Original credit for this code goes to ''mcspy0312'' from a [http://www.ogre3d.org/phpBB2/viewtopic.php?t=5530|post of his on the forums], but it looks like he got it from elsewhere too. His initial code was for a "sky sphere," with the faces pointing inwards. I modified it so that the faces had an outwards orientation and fixed a bug in the texture coordinate code. C# version is also available in ((MOGRE ManualSphereMeshes)). ''If you have a screenshot of a sphere, please upload and add it.'' {maketoc} !!Snippet This code creates a sphere mesh with the given name: {CODE(wrap="1", colors="c++")} 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(); } {CODE} The __parameters__ are * strName - The Mesh's name. You'll use this to access it. * r - The sphere's radius. * nRings - Number of lines of ((-Longitude|longitude)) in the sphere. Defaults to 16. * nSegments - Number of lines of ((-Latitude|latitude)) in the sphere. Also defaults to 16. !!Example Here's an example of how you would use this function and attach the new mesh to a SceneNode: {CODE(wrap="1", colors="c++")} createSphere("mySphereMesh", 10, 64, 64); Entity* sphereEntity = sceneMgr->createEntity("mySphereEntity", "mySphereMesh"); SceneNode* sphereNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); sphereEntity->setMaterialName("material_name_goes_here"); sphereNode->attachObject(sphereEntity); {CODE} Don't forget to replace "material_name_goes_here" with the name of your ((-material|material)). !!Creating a sphere with ManualObject You can also create the ((-Mesh|mesh)) with the ((ManualObject)) class: {CODE(wrap="1", colors="c++")} void createSphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16) { ManualObject * manual = sceneMgr->createManualObject(strName); manual->begin("BaseWhiteNoLighting", RenderOperation::OT_TRIANGLE_LIST); 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 manual->position( x0, y0, z0); manual->normal(Vector3(x0, y0, z0).normalisedCopy()); manual->textureCoord((float) seg / (float) nSegments, (float) ring / (float) nRings); if (ring != nRings) { // each vertex (except the last) has six indicies pointing to it manual->index(wVerticeIndex + nSegments + 1); manual->index(wVerticeIndex); manual->index(wVerticeIndex + nSegments); manual->index(wVerticeIndex + nSegments + 1); manual->index(wVerticeIndex + 1); manual->index(wVerticeIndex); wVerticeIndex ++; } }; // end for seg } // end for ring manual->end(); MeshPtr mesh = manual->convertToMesh(name); mesh->_setBounds( AxisAlignedBox( Vector3(-r, -r, -r), Vector3(r, r, r) ), false ); mesh->_setBoundingSphereRadius(r); unsigned short src, dest; if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) { mesh->buildTangentVectors(VES_TANGENT, src, dest); } } {CODE} You can use the above example to include it in your code. {IMG(src="dl2119&display",desc="ManualObjectSphere")}{IMG} ''Screen capture shown above is from ManualObject method lit with point light of ColourValue( 1.0f, 0.80f, 0.0f ), textured with MRAMOR6X6.jpg''
Search by Tags
Search Wiki by Freetags
Latest Changes
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
...more
Search
Find
Advanced
Search Help
Online Users
149 online users