Ogre3d simple game tutorial




















The first parameter determines whether or not Ogre will create a RenderWindow for us. We could also create a window using the win32 API, wxWidgets, or any other windowing system.

Here is a quick example of how to do this under Windows:. You can see that we still need to call Root::initialise , but the first parameter is set to false. We then call Root::createRenderWindow to directly assign our render window using the information we've gathered.

In a very large application, we may have thousands of resources. This can include meshes, textures, and scripts. However, at any given time, we will probably only be using a small subset of those resources. To help manage memory use, we will try to only initialise resources when we need them. For further reading on this topic, you can read Resources and ResourceManagers. Before we initialise our resources, let's set the default number of mipmaps to be used.

These are the lower resolution versions of textures used to produce different "level of detail" LOD for a texture, depending on how far it is away from the Camera. Continue adding to go. Now we'll call a single method from the ResourceGroupManager singleton that will initialise all of the resources found by Ogre.

As we described in the early tutorials, we need a SceneManager to First, add this include to your class:. Now we ask the Root object to create the manager for us in go. We've chosen the default, generic manager. Other than needing to ask the SceneManager to create the Camera, this should all be familiar from past tutorials.

Now we will declare the viewport and create it in the go method. This should also be familiar from past tutorials. We need a viewport to actually see a camera's viewpoint rendered on the screen. We're ready to add something to our scene!

None of this should be new to you by now. Make sure to include the Entity class. We still have to get the rendering started somehow. The first thing we will try is calling Root::renderOneFrame in a while loop. We briefly looked at this function in Basic Tutorial 4. This will loop infinitely until the window is closed or the renderOneFrame method returns false. The messagePump call basically updates the RenderWindow.

You should see the familiar Ogre head rendered in your window. You have to exit by pressing the close button on the window.

We will add back input in the next section. We will now provide an introduction to initialising OIS to work with Ogre. For more information, reference the OIS documentation. Also, remember to include the OIS library in your project. If you're using the CMake script from the tutorial framework, then it is already attempting to find OIS and including everything.

If you're working with an IDE, then you'll need to add these settings to your project:. OIS uses a general InputManager which is a touch difficult to set up, but easy to use once you have created it properly.

OIS does not integrate into Ogre; it's a standalone library, which means that you will need to provide it with some information at the beginning for it to work properly. In practice it really only needs the window handle in which Ogre is rendering.

Thankfully, since we have used the automatically created window, Ogre makes this easy for us. This sets up the InputManager for use, but to actually use OIS to get input for the Keyboard, Mouse, or Joystick of your choice, you'll need to create those objects:.

We are passing 'false ' to the createInputObject function because we want mouse and keyboard unbuffered. Note : If you wish to use buffered input meaning you get event callbacks to mouseMoved, mousePressed, keyReleased, and so on , then you must set the second parameter to createInputObject to be true.

OIS is a bit tricky to shut down properly. The most failsafe way to do this is by using a WindowEventListener. First, put this line in your list of includes in BasicTutorial6. Then we need to change our class declaration to derive from WindowEventListener :. To make our application act as a WindowEventListener, we need to register it as one.

So add these lines to BasicTutorialgo :. There's one more thing we need to do. Find the BasicTutorial6 destructor and make it look like this:. No matter if you are using buffered or unbuffered input, every frame you must call the capture method on all Keyboard, Mouse, and Joystick objects you use. For unbuffered input, this is all you need to do. Every frame you can call the various Keyboard and Mouse functions to query for the state of these objects.

So, we need to make our BasicTutorial6 class become a FrameListener. Before we're ready to compile and run our application, we need to register our application as a FrameListener. We don't need a custom render loop either. The MouseEvent that is passed to these functions contains information about the relative movement of the mouse how far it has moved since the last frame and information about where the mouse is in absolute screen coordinates. You'll find situations where both pieces of information are useful.

Go ahead and add overrides for the MouseListener methods to your header and cpp file. Add the declaration to the private section as well.

Do not compile your application yet. We've taken over some input management from BaseApplication and you'll be stuck with no way to move around or exit. We'll fix that soon.

Now we are going to create two SceneNodes that we can attach the Camera to. This will allow us to toggle back and forth between the two viewpoints using buffered input. The first thing you should do is remove this line in createScene :.

We're now positioning the camera by attaching it to a SceneNode so this was no longer needed. Now we are going to build the SceneNodes. Add the following to createScene right after we create the Light:. Here we have created a new SceneNode and reused the node variable to rotate it 90 degrees around the y-axis. The next thing we will do is assign our mCamNode pointer to our new SceneNode and attach our Camera to it. We will move the pointer to another SceneNode based on keyboard input. This will mean our Camera will now start out at the position of the SceneNode it was just attached to.

Now we want to create another SceneNode that we can move the Camera to. Now we have two "anchors" that we can attach the Camera to. Remember that the Camera won't just get placed at the position of the SceneNode, it will also inherit any transformations like rotations that have been applied to the node.

As with most listener classes, we need to register the KeyListener and MouseListener with their respective objects for them to work correctly. This is something that is already being done for us in BaseApplication. If you look at BaseApplication::createFrameListener , you will see these two calls:. They register our class which inherits from KeyListener and MouseListener as the source of the callback methods.

OIS does not automatically capture the state of the keyboard and mouse every frame. We need to explicitly call the capture method to do this. This is another thing that is already being done by the tutorial framework. This is why this method is referred to as buffered input. The Intermediate Tutorials no longer use the BaseApplication framework to help move you away from relying on code that is "behind the scenes". For now, just keep in mind that a lot of our functionality is still coming from BaseApplication.

We are pointing it out here so things start to seem less mysterious. Also keep in mind that if we override one of the methods from BaseApplication, then we must remember to call the parent method so we continue to get the functionality from BaseApplication like we are currently doing with frameRenderingQueued. We are now ready to develop our actual input code. The first thing we will do is allow the user to exit the application by pressing the escape key. Add the following to TutorialApplication::keyPressed :.

When the keyPressed method is called by the listener, the KeyEvent reference that we have stored in ke will contain a member called key. We can use its value to determine which key was pressed. We will use a switch statement that tests for the key code associated with the escape key.

When we discover the escape key has been pressed, then we simply set our shutdown flag to true. BaseApplication::frameRenderingQueued will then return false next frame and the application will exit as we wanted. If you compile your application now, you won't be able to move the Camera, but you should be able to exit by pressing escape.

Next we are going to allow the user to jump between SceneNodes by pressing 1 or 2 on the keyboard. Add the following to the switch statement we just set up in keyPressed :. This will detach the Camera and reattach it whenever these keys are pressed. Compile your application. You should be able to change viewpoints. The only other thing you can do is press escape to exit. Now we will add Camera movement back into our application.

We are going to do this by using mDirection as a velocity vector. Whenever the user presses the W key we will set the velocity vector's z component to equal -mMove. I'll let him speak. This is from a forum post from sinbad.

I think software systems should be modular and pluggable, with clear interfaces and boundaries between them. I think each team should concentrate on their core area and let others get on with specialising in theirs I think it's pure madness to try to reinvent ODE for example, as some other engines are doing. I think the most important part of any software system is it's interface, to support all of the above.

I think developers should be free to combine the tools they choose into their game development platform, not be told which sound, physics, AI etc implementation to use just because they chose a graphics engine.

I realise this approach means that as of today, it's not as fast to develop a game with OGRE than it is with another all-in-one engine. But I'm not just thinking about today. My philosophy is to build a flexible graphics component which can be used in the maximum number of situations, and to make it easy to integrate with other components - not to build an engine that can be used to make a small number of game variants.

I favour flexibility over speed, because I think if you design it right, you can add the tools to make it quicker to develop in specific scenarios later. You'll find it a lot harder to extend an engine which is designed to handle only a small subset of scene types, with strongly integrated features designed from a certain perspective. I try to plan for the long term. Note that this doesn't mean that you can't use Ogre for games. In fact, it's probably going to be used for games more than anything else out there.

This simply means that Ogre doesn't decide what libraries you're going to use, and allows you the flexibility to fit Ogre into your application, rather than attempting to wrap your application around Ogre.

Programming language How do you plan on implementing your game logic? Your options may be limited with a closed source game engine. Other languages are available with Ogre, under community driven extensions or game engines which utilize Ogre3D for rendering. Source code Do you want or need access to the source code? Are you worried about using closed source in case you need to alter functionality or fix a bug?

Have you considered the long term ramifications for your company if you use closed source technology and the game engine company changes their licensing or goes out of business? With Ogre, you are free to use and modify the code for your own commercial projects, free of charge, and nobody can ever take that away from you. Tools Game engines usually come with a very slick package of highly integrated tools.

Ogre, due to it's nature of being very flexible and community driven, has tools, but they are far less integrated and sometimes less polished. Some are free, some are not. Middleware integration Do you like the middleware that comes integrated with your game engine?

Contrast this to the work and cost associated with integrating the exact middleware you want into an Ogre3D-based engine. Ogre3D has been integrated with a wide variety of physics, sound, user interface, networking, and input handling middleware.

Which again, is an advantage for flexibility, but do not underestimate the amount of effort that is often involved in integrating middleware. There are many existing Ogre middleware "wrappers" which can help you integrate middleware into your project. License and royalty structure Do you need to pay money to use the game engine? Do you need to pay for support?

Ogre is free to use, has a large, helpful community, and extensive documentation. However, there is no paid support, so don't expect someone on the Ogre team to drop everything to fix a problem you encounter.

Platforms How do you want to publish your game? Web deployment? Not a traditional part of Ogre's repertoire, but there have been some interesting community developments on this lately. There has unfortunately never been a supported ogre console port so you're on your own there. Flexibility vs. Sandbox One of the core differences is that game engines are usually very good at doing a specific thing. If you want to create some variation of that specific thing, the game engine is almost always the right choice in terms of work efficiency.

Implementing the same sandbox using Ogre as is already available with a game engine could easily be years of additional work. Alternatively, if you're trying to build something significantly different than your standard FPS or RPG that most game engines support, using Ogre3D to construct your own game engine might be a good approach, because it is designed to be customized to different purposes much moreso than most game engines.

Value of Skills in the Game Industry Having experience with a game engine like UDK is a valuable skill if you're trying to enter the game industry. However, with a closed-source game engine, you may find that your knowledge can only go so deep.



0コメント

  • 1000 / 1000