game programming 07 ogre3d mesh in action 2010 년 2 학기 디지털콘텐츠전공

29
Game Programming 07 OGRE3D Mesh in Action 2010 년 2 년년 년년년년년년년년

Upload: bertha-simpson

Post on 13-Dec-2015

233 views

Category:

Documents


5 download

TRANSCRIPT

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

Game Programming 07OGRE3D Mesh in Action

2010 년 2 학기디지털콘텐츠전공

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

Rendering in Video Games

• Depth-Buffered Triangle Rasterization– Virtual Scene– Virtual Camera– Various Light Sources– Visual Properties

Solving the Rendering Equation (Shading Equation)

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

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)

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

Camera Setting in OGRE3D

• Two classes: Ogre::Camera, OgreBites::CameraManvoid 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);}

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

Camera Control in OGRE3D

• OgreBites::CameraMan

CameraMan::injectKeyDown(const OIS::KeyEvent& evt)CameraMan::injectKeyDown(const OIS::KeyEvent& evt)

CameraMan:: injectKeyUp(const OIS::KeyEvent& evt)CameraMan:: injectKeyUp(const OIS::KeyEvent& evt)

CameraMan:: injectMouseMove(const OIS::MouseEvent& evt)CameraMan:: injectMouseMove(const OIS::MouseEvent& evt)

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

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

filesex.)FileSystem=../../media/modelsex.)FileSystem=../../media/models

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

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

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");

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

OGRE::Mesh in Action

• createPlane function to generate the meshMeshPtr 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  ) 

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

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? What is singleton?

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

C++ Design Patterns 10

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

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

C++ Design Patterns 11

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

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

C++ Design Patterns 12

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

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

C++ Design Patterns 13

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:Solutions:We can make the Singleton constructor private so that only Singleton’s methods call it;

:: The Classic Singleton - II

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

C++ Design Patterns 14

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

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

Back to Ogre3D

• How to make your own mesh??– 1. Define the geometry.

Mesh

– 2. Define the appearance. Material

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

Geometry data in Ogre3D

• Indexed Triangle List

1v

2v

3v4v

5v

6v

7v

1v 2v 3v 4v 5v 6v 7v 8v

: 점의 좌표iv

Vertex Data:

0 1 3 1 2 3 0 4 1 Indexed triangle list:

0 1 2 3 4 5 6 7

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

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.

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

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.

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

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.

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

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

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

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 declaration4. Create a vertex buffer5. Fill the vertex buffer6. Create an index buffer7. 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);Ogre::SubMesh* mSubMesh = mMesh->createSubMesh(SubMeshName);

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

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();Ogre::VertexData* data = new Ogre::VertexData();

mMesh->sharedVertexData = data;mMesh->sharedVertexData = data;

data->vertexCount = iVertexCount;Ogre::VertexDeclaration* decl = data->vertexDeclaration;data->vertexCount = iVertexCount;Ogre::VertexDeclaration* decl = data->vertexDeclaration;

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

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);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);

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

Create a Vertex Buffer

• Using HardwareBufferManager To Create BufferOgre::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 )

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

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);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 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);

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

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 )

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

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);ibuf->writeData(0, ibuf->getSizeInBytes(), index, true);

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

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();mMesh->load();

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

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