1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 2007 Cedric Pinson
2 *
3 * This application is open source and may be redistributed and/or modified
4 * freely and without restriction, both in commercial and non commercial
5 * applications, as long as this copyright notice is maintained.
6 *
7 * This application is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 *
11 * Authors:
12 * Cedric Pinson <mornifle@plopbyte.net>
13 *
14 */
15
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #ifndef DATADIR
22 #define DATADIR "."
23 #endif // DATADIR
24
25 #include <osg/GraphicsContext>
26 #include "RenderSurface.h"
27 #include "CameraConfig.h"
28 #include <osgDB/FileNameUtils>
29 #include <osgDB/FileUtils>
30 #include <osgDB/Registry>
31 #include <osgDB/Input>
32 #include <osgDB/Output>
33 #include <osgDB/ReadFile>
34 #include <osgDB/WriteFile>
35 #include <osg/io_utils>
36
37 using namespace osgProducer;
buildTrait(RenderSurface & rs)38 static osg::GraphicsContext::Traits* buildTrait(RenderSurface& rs)
39 {
40 VisualChooser& vc = *rs.getVisualChooser();
41
42 osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
43
44 for (std::vector<VisualChooser::VisualAttribute>::iterator it = vc._visual_attributes.begin();
45 it != vc._visual_attributes.end();
46 it++)
47 {
48 switch(it->_attribute)
49 {
50 case(VisualChooser::UseGL): break; // on by default in osgViewer
51 case(VisualChooser::BufferSize): break; // no present mapping
52 case(VisualChooser::Level): traits->level = it->_parameter; break;
53 case(VisualChooser::RGBA): break; // automatically set in osgViewer
54 case(VisualChooser::DoubleBuffer): traits->doubleBuffer = true; break;
55 case(VisualChooser::Stereo): traits->quadBufferStereo = true; break;
56 case(VisualChooser::AuxBuffers): break; // no present mapping
57 case(VisualChooser::RedSize): traits->red = it->_parameter; break;
58 case(VisualChooser::GreenSize): traits->green = it->_parameter; break;
59 case(VisualChooser::BlueSize): traits->blue = it->_parameter; break;
60 case(VisualChooser::AlphaSize): traits->alpha = it->_parameter; break;
61 case(VisualChooser::DepthSize): traits->depth = it->_parameter; break;
62 case(VisualChooser::StencilSize): traits->stencil = it->_parameter; break;
63 case(VisualChooser::AccumRedSize): break; // no present mapping
64 case(VisualChooser::AccumGreenSize): break; // no present mapping
65 case(VisualChooser::AccumBlueSize): break; // no present mapping
66 case(VisualChooser::AccumAlphaSize): break; // no present mapping
67 case(VisualChooser::Samples): traits->samples = it->_parameter; break;
68 case(VisualChooser::SampleBuffers): traits->sampleBuffers = 1; break;
69 }
70 }
71
72 OSG_INFO<<"ReaderWriterCFG buildTrait traits->depth="<<traits->depth<<std::endl;
73 OSG_INFO<<"ReaderWriterCFG buildTrait traits->samples="<<traits->samples<<std::endl;
74 OSG_INFO<<"ReaderWriterCFG buildTrait traits->sampleBuffers="<<traits->sampleBuffers<<std::endl;
75
76
77 traits->hostName = rs.getHostName();
78 traits->displayNum = rs.getDisplayNum();
79 traits->screenNum = rs.getScreenNum();
80 traits->windowName = rs.getWindowName();
81 traits->x = rs.getWindowOriginX();
82 traits->y = rs.getWindowOriginY();
83 traits->width = rs.getWindowWidth();
84 traits->height = rs.getWindowHeight();
85 traits->windowDecoration = rs.usesBorder();
86 traits->sharedContext = 0;
87 traits->pbuffer = (rs.getDrawableType()==osgProducer::RenderSurface::DrawableType_PBuffer);
88
89 traits->overrideRedirect = rs.usesOverrideRedirect();
90
91 return traits;
92 }
93
load(const std::string & file,const osgDB::ReaderWriter::Options * option)94 static osgViewer::View* load(const std::string& file, const osgDB::ReaderWriter::Options* option)
95 {
96 osg::ref_ptr<CameraConfig> config = new CameraConfig;
97 //std::cout << "Parse file " << file << std::endl;
98 config->parseFile(file);
99
100 RenderSurface* rs = 0;
101 Camera* cm = 0;
102 std::map<RenderSurface*,osg::ref_ptr<osg::GraphicsContext> > surfaces;
103 osg::ref_ptr<osgViewer::View> _view = new osgViewer::View;
104
105 if (config->getNumberOfCameras()==1)
106 {
107 cm = config->getCamera(0);
108 rs = cm->getRenderSurface();
109 if (rs->getDrawableType() != osgProducer::RenderSurface::DrawableType_Window) return 0;
110
111 osg::ref_ptr<const osg::GraphicsContext::Traits> traits;
112 osg::ref_ptr<osg::GraphicsContext> gc;
113 if (surfaces.find(rs) != surfaces.end())
114 {
115 gc = surfaces[rs];
116 traits = gc.valid() ? gc->getTraits() : 0;
117 }
118 else
119 {
120 osg::GraphicsContext::Traits* newtraits = buildTrait(*rs);
121
122 #if 0
123 osg::GraphicsContext::ScreenIdentifier si;
124 si.readDISPLAY();
125
126 if (si.displayNum>=0) newtraits->displayNum = si.displayNum;
127 if (si.screenNum>=0) newtraits->screenNum = si.screenNum;
128 #endif
129
130 gc = osg::GraphicsContext::createGraphicsContext(newtraits);
131
132 surfaces[rs] = gc.get();
133 traits = gc.valid() ? gc->getTraits() : 0;
134 }
135
136 // std::cout << rs->getWindowName() << " " << rs->getWindowOriginX() << " " << rs->getWindowOriginY() << " " << rs->getWindowWidth() << " " << rs->getWindowHeight() << std::endl;
137
138 if (gc.valid())
139 {
140 OSG_INFO<<" GraphicsWindow has been created successfully."<<std::endl;
141
142 osg::ref_ptr<osg::Camera> camera = _view->getCamera();
143
144 camera->setGraphicsContext(gc.get());
145
146 int x,y;
147 unsigned int width,height;
148 cm->applyLens();
149 cm->getProjectionRectangle(x, y, width, height);
150 camera->setViewport(new osg::Viewport(x, y, width, height));
151
152 GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
153 camera->setDrawBuffer(buffer);
154 camera->setReadBuffer(buffer);
155 camera->setProjectionMatrix(osg::Matrixd(cm->getProjectionMatrix()));
156 camera->setViewMatrix(osg::Matrixd(cm->getPositionAndAttitudeMatrix()));
157
158 #if 0
159 std::cout << "Matrix Projection " << projection << std::endl;
160 std::cout << "Matrix Projection master " << _view->getCamera()->getProjectionMatrix() << std::endl;
161 // will work only if it's a post multyply in the producer camera
162 std::cout << "Matrix View " << view << std::endl;
163 std::cout << _view->getCamera()->getProjectionMatrix() * offsetProjection << std::endl;
164 #endif
165 }
166 else
167 {
168 OSG_INFO<<" GraphicsWindow has not been created successfully."<<std::endl;
169 return 0;
170 }
171
172 }
173 else
174 {
175 for (int i = 0; i < (int)config->getNumberOfCameras(); i++)
176 {
177 cm = config->getCamera(i);
178 rs = cm->getRenderSurface();
179 if (rs->getDrawableType() != osgProducer::RenderSurface::DrawableType_Window)
180 continue;
181
182 osg::ref_ptr<const osg::GraphicsContext::Traits> traits;
183 osg::ref_ptr<osg::GraphicsContext> gc;
184 if (surfaces.find(rs) != surfaces.end())
185 {
186 gc = surfaces[rs];
187 traits = gc.valid() ? gc->getTraits() : 0;
188 }
189 else
190 {
191 osg::GraphicsContext::Traits* newtraits = buildTrait(*rs);
192
193 #if 0
194 osg::GraphicsContext::ScreenIdentifier si;
195 si.readDISPLAY();
196
197 if (si.displayNum>=0) newtraits->displayNum = si.displayNum;
198 if (si.screenNum>=0) newtraits->screenNum = si.screenNum;
199 #endif
200
201 gc = osg::GraphicsContext::createGraphicsContext(newtraits);
202
203 surfaces[rs] = gc.get();
204 traits = gc.valid() ? gc->getTraits() : 0;
205 }
206
207 // std::cout << rs->getWindowName() << " " << rs->getWindowOriginX() << " " << rs->getWindowOriginY() << " " << rs->getWindowWidth() << " " << rs->getWindowHeight() << std::endl;
208
209 if (gc.valid())
210 {
211 OSG_INFO<<" GraphicsWindow has been created successfully."<<std::endl;
212
213 osg::ref_ptr<osg::Camera> camera = new osg::Camera;
214 camera->setGraphicsContext(gc.get());
215
216
217 int x,y;
218 unsigned int width,height;
219 cm->applyLens();
220 cm->getProjectionRectangle(x, y, width, height);
221 camera->setViewport(new osg::Viewport(x, y, width, height));
222
223 GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
224 camera->setDrawBuffer(buffer);
225 camera->setReadBuffer(buffer);
226
227 osg::Matrix projection(cm->getProjectionMatrix());
228
229 osg::Matrix offset = osg::Matrix::identity();
230 cm->setViewByMatrix(offset);
231 osg::Matrix view = osg::Matrix(cm->getPositionAndAttitudeMatrix());
232
233 // setup projection from parent
234 osg::Matrix offsetProjection = osg::Matrix::inverse(_view->getCamera()->getProjectionMatrix()) * projection;
235 _view->addSlave(camera.get(), offsetProjection, view);
236
237 #if 0
238 std::cout << "Matrix Projection " << projection << std::endl;
239 std::cout << "Matrix Projection master " << _view->getCamera()->getProjectionMatrix() << std::endl;
240 // will work only if it's a post multyply in the producer camera
241 std::cout << "Matrix View " << view << std::endl;
242 std::cout << _view->getCamera()->getProjectionMatrix() * offsetProjection << std::endl;
243 #endif
244 }
245 else
246 {
247 OSG_INFO<<" GraphicsWindow has not been created successfully."<<std::endl;
248 return 0;
249 }
250 }
251 }
252
253 // std::cout << "done" << std::endl;
254 return _view.release();
255 }
256
257 //
258 // OSG interface to read/write from/to a file.
259 //
260 class ReaderWriterProducerCFG : public osgDB::ReaderWriter
261 {
262 public:
263
ReaderWriterProducerCFG()264 ReaderWriterProducerCFG()
265 {
266 supportsExtension("cfg","Producer camera configuration file");
267 }
268
className()269 virtual const char* className() { return "Producer cfg object reader"; }
270
271
readObject(const std::string & fileName,const Options * options=NULL) const272 virtual ReadResult readObject(const std::string& fileName, const Options* options = NULL) const
273 {
274 std::string ext = osgDB::getLowerCaseFileExtension(fileName);
275 if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
276
277 osgDB::FilePathList* filePathList = 0;
278 if(options)
279 {
280 filePathList = const_cast<osgDB::FilePathList*>(&(options->getDatabasePathList()));
281 filePathList->push_back(DATADIR);
282 }
283
284 std::string path = osgDB::findDataFile(fileName);
285 if(path.empty()) return ReadResult::FILE_NOT_FOUND;
286
287 ReadResult result;
288 osg::ref_ptr<osg::View> view = load(path, options);
289 if(! view.valid())
290 result = ReadResult("Error: could not load " + path);
291 else
292 result = ReadResult(view.get());
293
294 if(options && filePathList)
295 filePathList->pop_back();
296
297 return result;
298 }
299
300 };
301
302
303 REGISTER_OSGPLUGIN(cfg, ReaderWriterProducerCFG)
304