Presentation is loading. Please wait.

Presentation is loading. Please wait.

Game Programming 07 OGRE3D Mesh in Action 2010 년 2 학기 디지털콘텐츠전공.

Similar presentations


Presentation on theme: "Game Programming 07 OGRE3D Mesh in Action 2010 년 2 학기 디지털콘텐츠전공."— Presentation transcript:

1 Game Programming 07 OGRE3D Mesh in Action 2010 년 2 학기 디지털콘텐츠전공

2 Rendering in Video Games Depth-Buffered Triangle Rasterization –Virtual Scene –Virtual Camera –Various Light Sources –Visual Properties  Solving the Rendering Equation (Shading Equation)

3 Rendering in OGRE3D Depth-Buffered Triangle Rasterization –Virtual Scene  createScene() –Virtual Camera  createCamera()/ createViewport() –Various Light Sources  createScene() –Visual Properties  material  Solving the Rendering Equation (OGRE3D engine)

4 Camera Setting in OGRE3D Two classes: Ogre::Camera, OgreBites::CameraMan void BaseApplication::createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); // Position it at 500 in Z direction mCamera->setPosition(Ogre::Vector3(0,0,80)); // Look back along -Z mCamera->lookAt(Ogre::Vector3(0,0,-300)); mCamera->setNearClipDistance(5); mCameraMan = new OgreBites::SdkCameraMan(mCamera); } void BaseApplication::createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); // Position it at 500 in Z direction mCamera->setPosition(Ogre::Vector3(0,0,80)); // Look back along -Z mCamera->lookAt(Ogre::Vector3(0,0,-300)); mCamera->setNearClipDistance(5); mCameraMan = new OgreBites::SdkCameraMan(mCamera); }

5 Camera Control in OGRE3D OgreBites::CameraMan CameraMan::injectKeyDown(const OIS::KeyEvent& evt) CameraMan:: injectKeyUp(const OIS::KeyEvent& evt) CameraMan:: injectMouseMove(const OIS::MouseEvent& evt)

6 OGRE::Mesh in action.mesh files for loading a mesh in Ogre –.mesh is a binary file only for the ogre’s use. –There is no way to create your own.mesh file from the scratch. Meshes are located at a specific folder –Resources.cfg file says where you can find the files ex.) FileSystem=../../media/models ex.) FileSystem=../../media/models Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

7 OGRE::Mesh in Action You can create your own mesh, too! –Using primitive mesh structure: For example, a Plane –Or, Define your own mesh manually Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0); Ogre::MeshManager::getSingleton().createPlane ("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z); Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground"); Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0); Ogre::MeshManager::getSingleton().createPlane ("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z); Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");

8 OGRE::Mesh in Action createPlane function to generate the mesh MeshPtr Ogre::MeshManager::createPlane ( const String & name, const String & groupName, const Plane & plane, Real width, Real height, int xsegments = 1, int ysegments = 1, bool normals = true, int numTexCoordSets = 1, Real uTile = 1.0f, Real vTile = 1.0f, const Vector3 & upVector = Vector3::UNIT_Y ) MeshPtr Ogre::MeshManager::createPlane ( const String & name, const String & groupName, const Plane & plane, Real width, Real height, int xsegments = 1, int ysegments = 1, bool normals = true, int numTexCoordSets = 1, Real uTile = 1.0f, Real vTile = 1.0f, const Vector3 & upVector = Vector3::UNIT_Y )

9 Singleton pattern in OGRE3D Which class will be useful if you can access it from anywhere? –Resources should be used anywhere! Mesh Material Manager classes for the resources: TextureManager::getSingleton() MeshManager::getSingleton() TextureManager::getSingleton() MeshManager::getSingleton()  What is singleton?

10 C++ Design Patterns10 The Singleton Pattern Sometimes it is appropriate to have exactly one instance of a class:  window managers,  print spoolers,  filesystems. Typically, those types of objects known as singletons, are accessed by disparate objects throughout a software system, and therefore require a global point of access. The Singleton pattern addresses all the concerns above. With the Singleton design pattern you can:  Ensure that only one instance of a class is created.  Provide a global point of access to the object.  Allow multiple instances in the future without affecting a singleton class' clients. :: Definition & Applicability - I

11 C++ Design Patterns11 The Singleton Pattern  The Singleton pattern ensures a class has only one instance, and provides a global point of access to it.  The class itself is responsible for keeping track of its sole instance. The class can ensure that no other instance can be created (by intercepting requests to create new objects), and it can provide a way to access the instance.  Singletons maintain a static reference to the sole singleton instance and return a reference to that instance from a static instance() method. :: Definition & Applicability - II

12 C++ Design Patterns12 The Singleton Pattern The Singleton class maintains a static reference to the sinle singleton instance (pinstance) and returns that reference from the static Instance() method. :: The Classic Singleton - I

13 C++ Design Patterns13 The Singleton Pattern  The Singleton class employs a technique known as lazy instantiation to create the singleton; as a result, the singleton instance is not created until the Instance() method is called for the first time. This technique ensures that singleton instances are created only when needed.  The Singleton class implements a protected constructor so clients cannot instantiate Singleton instances.  Protected constructors can be called by subclasses.Solutions: We can make the Singleton constructor private so that only Singleton’s methods call it; :: The Classic Singleton - II

14 C++ Design Patterns14 The Singleton Pattern  It can be difficult to subclass a Singleton, since this can only work if the base Singleton class has not yet been instantiated.  We can easily change a Singleton to allow a small number of instances where this is allowable and meaningful.  We can use the same approach to control the number of instances that the application uses. Only the operation that grants access to the Singleton instance needs to change.  The Singleton pattern permits refinement of operations and representation. The Singleton class may be subclassed, and it is easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time. :: Consequences of the Singleton Pattern

15 Back to Ogre3D How to make your own mesh?? –1. Define the geometry.  Mesh –2. Define the appearance.  Material

16 Geometry data in Ogre3D Indexed Triangle List : 점의 좌표 Vertex Data: Indexed triangle list: 01234567

17 Mesh and submesh In Ogre, a model is called Mesh. –A mesh can represent a whole ‘’object‘’. Ex.) a character, a car, a monster –Mesh is composed of different parts. Ex.) a character  head, arm, leg, and so on. Different part can have a different material. A part in a model is called SubMesh. –A mesh is a set of SubMesh. –A SubMesh has the actual geometry data. –A SubMesh has a unique material.

18 Entity and subentity A mesh can be instanced as an Entity. Then, Submeshes are automatically instanced as SubEntities. –A SubEntity can has its own material different from the submesh. Ex.) cars with different colors.

19 How to write the geometry data Hardware Buffer for the vertex and index data –Hardware buffer is any memory outside of core system. –Usually, it means for the video RAM. –It is very efficient once the data are transferred from CPU to GPU. –But, it has very restrictive usage such as only a sequential write is allowed.

20 OGRE::Mesh in action Get the sample file at our home page Create your own cylinder mesh from scratch. Reference to read: http://www.ogre3d.org/tikiwiki/Manual+Resource+Loading&structure=Tutorials http://www.ogre3d.org/tikiwiki/Manual+Resource+Loading&structure=Tutorials

21 OGRE::Mesh in action How to make your own mesh: 1.Create Mesh in Mesh Manager 2.Create a SubMesh on the mesh 3.Create a vertex declaration 4.Create a vertex buffer 5.Fill the vertex buffer 6.Create an index buffer 7.Fill the index buffer Ogre::Mesh* mMesh = Ogre::MeshManager::getSingleton().createManual(yourMeshName, "General"); Ogre::Mesh* mMesh = Ogre::MeshManager::getSingleton().createManual(yourMeshName, "General"); Ogre::SubMesh* mSubMesh = mMesh->createSubMesh(SubMeshName);

22 Create a Vertex Declaration (1/2) 1.Create Vertex Data 2.Connect it to the mesh submeshes share the vertex buffer 3.Declare the data format through an interface Ogre::VertexData* data = new Ogre::VertexData(); mMesh->sharedVertexData = data; data->vertexCount = iVertexCount; Ogre::VertexDeclaration* decl = data->vertexDeclaration; data->vertexCount = iVertexCount; Ogre::VertexDeclaration* decl = data->vertexDeclaration;

23 Create a Vertex Declaration (2/2) Using Vertex Declaration –A simplest case: Position only –Position + Normal –Position + Normal + UV Coord decl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION); size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES); size_t offset = 0; decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);

24 Create a Vertex Buffer Using HardwareBufferManager To Create Buffer Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer ( decl->getVertexSize(0), // This value is the size of a vertex in memory iVertexNbr, // The number of vertices you'll put into this buffer Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY // Properties ) Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer ( decl->getVertexSize(0), // This value is the size of a vertex in memory iVertexNbr, // The number of vertices you'll put into this buffer Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY // Properties )

25 Fill the vertex buffer Prepare your vertex data as an array Write the data to the buffer Link the buffer to the mesh vbuf->writeData(0, vbuf->getSizeInBytes(), yourVertexArray, true); float array[vbufCount]; array[0] = vertices[1].x; array[1] = vertices[1].y; array[2] = vertices[1].z; array[3] = vertices[1].normal.x; array[4] = vertices[1].normal.y; array[5] = vertices[1].normal.z; array[6] = vertices[2].x; … float array[vbufCount]; array[0] = vertices[1].x; array[1] = vertices[1].y; array[2] = vertices[1].z; array[3] = vertices[1].normal.x; array[4] = vertices[1].normal.y; array[5] = vertices[1].normal.z; array[6] = vertices[2].x; …  In this case, each vertex is declared to have only position + normal data Ogre::VertexBufferBinding* bind = data->vertexBufferBinding; bind->setBinding(0, vbuf); Ogre::VertexBufferBinding* bind = data->vertexBufferBinding; bind->setBinding(0, vbuf);

26 Create an Index Buffer Using HardwareIndexBufferManager Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer ( Ogre::HardwareIndexBuffer::IT_16BIT, // value type: 16bit integer iIndexNbr, // The number of indices you'll put in that buffer Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY // Properties ) Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer ( Ogre::HardwareIndexBuffer::IT_16BIT, // value type: 16bit integer iIndexNbr, // The number of indices you'll put in that buffer Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY // Properties )

27 Fill the Index Buffer Prepare your index data as an array Write the index buffer Link the index with the submesh unsigned short index[ibufCount]; index[0] = subMesh[0].vertexIndices[0]; index[1] = subMesh[0].vertexIndices[1]; index[2] = subMesh[0].vertexIndices[2]; index[3] = subMesh[1].vertexIndices[0]; index[4] = subMesh[1].vertexIndices[1]; index[5] = subMesh[1].vertexIndices[2]; unsigned short index[ibufCount]; index[0] = subMesh[0].vertexIndices[0]; index[1] = subMesh[0].vertexIndices[1]; index[2] = subMesh[0].vertexIndices[2]; index[3] = subMesh[1].vertexIndices[0]; index[4] = subMesh[1].vertexIndices[1]; index[5] = subMesh[1].vertexIndices[2]; mSubMesh->indexData->indexBuffer = ibuf; // The pointer to the index buffer mSubMesh->indexData->indexCount = iIndexNbr; // The number of indices mSubMesh->indexData->indexStart = 0; // The offset from the beginning mSubMesh->indexData->indexBuffer = ibuf; // The pointer to the index buffer mSubMesh->indexData->indexCount = iIndexNbr; // The number of indices mSubMesh->indexData->indexStart = 0; // The offset from the beginning ibuf->writeData(0, ibuf->getSizeInBytes(), index, true);

28 Final touch by loading the mesh Define bounding box for efficient culling Notify that the Mesh is loaded mMesh->_setBounds(Ogre::AxisAlignedBox(xMin,yMin,zMin,xMax,yMax,zMax)); mMesh->_setBoundingSphereRadius (std::max(xMax-xMin, std::max(yMax-yMin, zMax-zMin))/2.0f) mMesh->_setBounds(Ogre::AxisAlignedBox(xMin,yMin,zMin,xMax,yMax,zMax)); mMesh->_setBoundingSphereRadius (std::max(xMax-xMin, std::max(yMax-yMin, zMax-zMin))/2.0f) mMesh->load();

29 Material basic attributes ambient reflectance = ColourValue::White (full) diffuse reflectance = ColourValue::White (full) specular reflectance = ColourValue::Black (none) emmissive = ColourValue::Black (none) shininess = 0 (not shiny) No texture layers (& hence no textures) SourceBlendFactor = SBF_ONE, DestBlendFactor = SBF_ZERO (opaque) Depth buffer checking = on Depth buffer writing = on Depth buffer comparison function = CMPF_LESS_EQUAL Culling mode = CULL_CLOCKWISE Ambient lighting in scene = ColourValue(0.5, 0.5, 0.5) (mid-grey) Dynamic lighting = enabled Gourad shading mode Solid polygon mode Bilinear texture filtering


Download ppt "Game Programming 07 OGRE3D Mesh in Action 2010 년 2 학기 디지털콘텐츠전공."

Similar presentations


Ads by Google