Howto:Use a Camera View in an Instrument: Difference between revisions
m (Correct list formatting) |
m (note about allocRT) |
||
Line 54: | Line 54: | ||
* Implement the init and update functions, whatever instrument manager requires. | * Implement the init and update functions, whatever instrument manager requires. | ||
* In init set up proper texture sizes and call allocRT(). | * In init set up proper texture sizes and call allocRT(). | ||
* NOTE: od_gauge does NOT add camera to render the scenery, but a custom model. One needs to modify od_gauge so that allocRT calls globals()->get_renderer()->addCamera(camera.get(), '''true'''); | |||
* In update function update camera position according to viewer->getAbsolutePosition(...). | * In update function update camera position according to viewer->getAbsolutePosition(...). | ||
* Add the custom instrument to instrument_mgr.cxx. | * Add the custom instrument to instrument_mgr.cxx. |
Revision as of 17:33, 22 February 2012
Background
This was inspired by the ongoing effort to create a realistic 787 for FlightGear, including support for rendering external camera views on instruments: Boeing 787-8 Dreamliner#Camera.2FVideo Surveillance Instrument. The "Tail Camera" is also a feature found on the A380.
Objective
To create a 2D instrument which shows a camera view. Write C++ code, preferably an instrument that renders a Camera View (i.e. from the property tree) to a texture.
The steps involved in creating such an instrument would be:*
- create a new topic branch: FlightGear and Git#Local_Branch
- Add a new set of cxx/hxx files to $FG_SRC/Instrumentation/ (e.g. camera-texture.cxx and camera-texture.hxx): to get started quickly, just copy and customize the gyro.* files
- implement the SGSubsystem interface for the new subsystem [1]
- add the new files to the CMake build system: Developing using CMake#Adding_new_files_to_the_build
- add the new subsystem to the instrument_mgr (FGInstrumentMgr::build method)[2]
- implement the interface for the od_gauge instrument [3] to dynamically create a texture and display update it as a cockpit instrument
- implement SGPropertyChangeListener to process property tree events and updates [4]
- Render a property-driven camera view to the created texture (Zan has already code doing this sort of thing [5])
- Write an XML 2D Instrument file that displays the texture
There are obviously more steps involved here, some of which covered here Howto: Create a 2D drawing API for FlightGear.
Pre-Requisites
The following are required before we continue...
- To be able to build FlightGear from Source (with or without an IDE)
- To be able to create new instruments (that would be taking a simple one like gyro, copying it's files and changing the content)
- A Gitorious account to be able to clone the Flightgear Repository
- Basic Knowledge of FlightGear and XML
Part 1: Rendering a Camera View to Texture
There're probably many ways to do that, you could do it the way the ground radar instrument does, or how you take a screenshot etc. A very nice guide on OpenSceneGraph Rendering is available at http://www.palomino3d.com/pal_com/openscenegraph/ or http://sourceforge.net/apps/mediawiki/delta3d/index.php?title=Tutorial_Render_To_Texture
Screenshot Method
This is a very simple method and is used normally for taking screen-shots.
OpenSceneGraph C++ Code:
osg::Image* shot = new osg::Image();
shot->allocateImage(width, height, 24, GL_RGB, GL_UNSIGNED_BYTE);
camera->attach(osg::Camera::COLOR_BUFFER, shot);
osgDB::writeImageFile(*shot,"image_file.png");
FlightGear code
FlighGear already has an "Owner Drawn instrument" in flightgear/src/Instrumentation/od_gauge.cxx and .hxx. It already sets up a pre-render camera and a texture for it, and has a visitor to replace model's texture with the custom texture.
Using it would be something like this:
- Create a custom instrument which inherits od_gauge. class CameraInstrument : public FGODGauge { ... }
- Implement the init and update functions, whatever instrument manager requires.
- In init set up proper texture sizes and call allocRT().
- NOTE: od_gauge does NOT add camera to render the scenery, but a custom model. One needs to modify od_gauge so that allocRT calls globals()->get_renderer()->addCamera(camera.get(), true);
- In update function update camera position according to viewer->getAbsolutePosition(...).
- Add the custom instrument to instrument_mgr.cxx.
Part 2: Getting that texture into an instrument
This part doesn't require any C++ coding, just a simple XML script to use that texture in an instrument.
<?xml version="1.0"?>
<PropertyList>
<name>Camera Instrument</name>
<w-base>512</w-base>
<h-base>512</h-base>
<layers>
<layer>
<name>camera</name>
<texture>
<path>image_file.png</path> <!-- Path to the file we just rendered -->
<x1>0</x1>
<y1>0</y1>
<x2>1</x2>
<y2>1</y2>
</texture>
<emissive>1</emissive>
<w>512</w>
<h>512</h>
</layer>
</layers>
You could create more layers for more cameras/different views or even have a sprite or something on the view. Or we could also add transformations or conditions to the layer to give some function to the instrument other than just show a camera view.
<transformation>
<type>y-shift</type>
<property>/instrumentation/camera/y_shift</property>
<scale>2</scale>
</transformation>
Creating the CamView as a hard coded instrument
Header File: cam_display.hxx
The header file is used to simply initialize a new class that contains all functions related to this instrument. The Functions are just constructed here, the contents are put in the cam_display.cxx file.
// cam_display.hxx - simple function to render view to texture
#ifndef __INSTRUMENTATION_CAMVIEW_HXX
#define __INSTRUMENTATION_CAMVIEW_HXX
#include <simgear/props/props.hxx>
#include "od_gauge.hxx"
class CamView : public SGPropertyChangeListener, public FGODGauge
{
public:
static const int TextureHalfSize = 256;
CamView(SGPropertyNode* node);
virtual ~CamView();
void updateTexture();
virtual void valueChanged(SGPropertyNode*);
protected:
void createTexture(const char* texture_name);
};
#endif // __INSTRUMENTATION_CAMVIEW_HXX