Page 1 of 1

Creating a sky sphere.

Posted: Sun Aug 08, 2004 5:35 pm
by mcspy0312
Hi,
I'm a newbie in Ogre 3D engine.
I have a starmap(http://maps.jpl.nasa.gov/stars.html), and I want to map it to a skysphere.
However, I can't find setSkySphere in Scene Mgr.
There are no such a SkySphere examples in Ogre too.
How can I create a skysphere?
Thanks for helping.

Cheers,
:D

Posted: Sun Aug 08, 2004 6:52 pm
by Kencho
setSkyDome is the closest to what you want to do.

Otherwise (if you really want it to be a sphere), you would have to load a sphere model by yourself, make it move as the camera moves, and be displayed behind all other objects... I did something similar before (http://www.ogre3d.org/phpBB2/viewtopic. ... ynamic+sky) Maybe that helps

Posted: Mon Aug 09, 2004 10:15 am
by mcspy0312
Thx Kencho.
I created a SkySphere mesh.
But it doesn't show up.
I do it in this way.

Code: Select all

		CreateSkySphere("SkySphere", 1000);

		Entity* SkySphere = mSceneMgr->createEntity("SkySphere", "SkySphere");
		SceneNode* SkySphereNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		SkySphere->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
		SkySphere->setMaterialName("StarMap");
		SkySphereNode->attachObject(SkySphere);

Code: Select all

	void CreateSkySphere(const std::string& strName, const float r, const int nRings = 16, const int nSegments = 16)
	{
		Mesh* pSphere = MeshManager::getSingleton().createManual(strName);
		SubMesh *pSphereVertex = pSphere->createSubMesh();

		pSphere->sharedVertexData = new VertexData();
		VertexData* vertexData = pSphere->sharedVertexData;

		// Definite vertex format
		VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; 
		size_t currOffset = 0;
		// We always need 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); 
		// Assumes 2D texture coords 
		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); 
		currOffset += VertexElement::getTypeSize(VET_FLOAT2);

		// Allocate vertex buffer 
		vertexData->vertexCount = (nRings + 1) * nSegments;
		HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); 
		VertexBufferBinding* binding = vertexData->vertexBufferBinding; 
		binding->setBinding(0, vBuf);
		Real* pVertex = static_cast<Real*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

		// Allocate index buffer
		pSphereVertex->indexData->indexCount = 6 * nRings * nSegments;
		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)); 

		// fill vertex
		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 vertices 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) 
				{
					if (seg == nSegments - 1)
					{
						*pIndices++ = wVerticeIndex + 1;
						*pIndices++ = wVerticeIndex + nSegments;
						*pIndices++ = wVerticeIndex;
						*pIndices++ = wVerticeIndex + 1;
						*pIndices++ = wVerticeIndex;
						*pIndices++ = wVerticeIndex - nSegments + 1;
					}
					else
					{
						*pIndices++ = wVerticeIndex + nSegments + 1;
						*pIndices++ = wVerticeIndex + nSegments;
						*pIndices++ = wVerticeIndex;					
						*pIndices++ = wVerticeIndex + nSegments + 1;
						*pIndices++ = wVerticeIndex;
						*pIndices++ = wVerticeIndex + 1;
					}
					wVerticeIndex ++; 
				}
			}; // end for seg 
		} // end for ring 

		// Unlock 
		vBuf->unlock();
		iBuf->unlock();
		// Generate face list 
		pSphereVertex->useSharedVertices = true; 

		pSphere->_setBoundingSphereRadius(r); 
	}
The skysphere mesh is created prefectly. But it doesn't show up. Why?
Thanks. :D

Posted: Mon Aug 09, 2004 1:36 pm
by sinbad
You need to set the AABB bounds too (setBounds).

Posted: Mon Aug 09, 2004 3:05 pm
by mcspy0312
Thx.
It works fine now.
If I want to share my codes, where should I post it?
I think createSphere and createSkySphere are quite useful because it can gen. a sphere on the fly without loading mesh.

Posted: Mon Aug 09, 2004 3:10 pm
by _mental_
Best thing to do would be to send a patch. There's a link on the homepage which should describe how to do this.

Posted: Fri Oct 15, 2004 5:35 am
by Bren
Hi,

I'd like to adapt this to create a "standard" sphere, where the face normals point outward instead of inward like this skybox sphere.

I tried flipping the vertex normals in the line:

Code: Select all

Vector3 vNormal = Vector3(-x0, -y0, -z0).normalisedCopy();
to:

Code: Select all

Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
But there was no apparent change.

I also have some questions about this code. Unmodified, the first time through the loop, the normals are 0,-1,0 for all 16 segments on the first ring.

Are you sure that the loop condition:

Code: Select all

for( int ring = 0; ring <= Def->mRings; ring++ )
is right? Cause the last time through the loop, the x and z values for the last 16 segments appear to be invalid.

Despite this, the sphere does seem to look alright. Now, if I could only get those faces flipped...

Posted: Fri Oct 15, 2004 12:47 pm
by sinbad
Face culling has nothing to do with vertex normals. Vertex normals only affect lighting. The 'front' of a face is derived from the vertex winding - whether the vertices are listed in clockwise or anticlockwise order as viewed from the camera. So to invert the faces, you have to reverse the order of 2 of the vertex indices.

Posted: Fri Oct 15, 2004 6:18 pm
by Bren
Duh. I knew that. WTF was I thinking? Very tired these days. Sorted it out after a good night's sleep. :) Thanks.

Posted: Fri Oct 15, 2004 6:47 pm
by Brutha
I could use the full skysphere class (and the normal sphere too :) ). I'm currently trying to learn ogre and playing around with showing earth :)

http://www.imagedump.com/index.cgi?pick ... 0&warned=y

Posted: Fri Oct 15, 2004 10:30 pm
by Kencho
Nice pic, but... have you noticed the earth is mirrored? Spain is at the west of europe :)

Posted: Sun Oct 17, 2004 1:35 am
by Brutha
yes I know its mirrored, I have a different thead on this. By now it looks much better but it is still mirrored.. Guess I just have to flip the texture :)

Posted: Mon Oct 18, 2004 4:08 pm
by Brutha
I used this function and I have the bug Bren mentioned, the last segment is messed up. Does anyone know how to fix this ? I have to admit I don't understand whats going on in the inner loop :(

Here is a screenshot:
http://www.imagedump.com/index.cgi?pick=get&tp=137764

Posted: Wed Mar 09, 2005 4:39 am
by RoundSparrow

Posted: Wed Apr 20, 2005 6:30 pm
by Bren
How/when/where should the shared vertexes be deleted?

Code: Select all

pSphere->sharedVertexData = new VertexData();
It appears at the moment this is leaking.

I tried just storing the pointer and then deleting it after the Entity was removed, but this would crash somewhere in shutdown.

Posted: Fri May 06, 2005 3:25 am
by Bren
Bump?

Release error

Posted: Thu Jan 26, 2006 10:18 am
by fidaner
I used this code for creating a sphere
The program runned fine in debug mode
But there was a problem in release mode on exiting
I tracked the problem and it gives error at line "delete mRoot" in the application.

Hope someone knows the solution or an alternative way of creating spheres.

Posted: Wed Nov 29, 2006 10:19 am
by sunnybox
same here..

does anyone solve the problem..?
i create the sphere.

it runs ok when i call the createsphere function directly

but when the createSphere function is a static function , it crashes when the application exits...and it shows somewhere in delete mroot...and thus,...somewhere when deleting the sharevertexdata..

please help.