Compare commits
31 Commits
OpenSceneG
...
OpenSceneG
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b02a5b85a6 | ||
|
|
45d5cc4745 | ||
|
|
54bafb9cc6 | ||
|
|
97b6099fa5 | ||
|
|
03b59e970b | ||
|
|
60746206f1 | ||
|
|
84f4ff1d96 | ||
|
|
c68440f3cb | ||
|
|
42d6b86530 | ||
|
|
866da7bdd5 | ||
|
|
14b8c242cf | ||
|
|
ad817735cf | ||
|
|
ede2f9d58a | ||
|
|
9a44ab4440 | ||
|
|
be9bd9cd08 | ||
|
|
4d19d54de5 | ||
|
|
83887b61d7 | ||
|
|
90afef26bb | ||
|
|
1753cad35f | ||
|
|
df098a3a8d | ||
|
|
87bf7980e2 | ||
|
|
5b4051d9e8 | ||
|
|
75bce7da0b | ||
|
|
b1045223f1 | ||
|
|
68a97a6424 | ||
|
|
419a228fe9 | ||
|
|
b970343c47 | ||
|
|
9529b14f3c | ||
|
|
902c4aa1e9 | ||
|
|
c0d2ccc017 | ||
|
|
0ce917d3bb |
18
AUTHORS.txt
18
AUTHORS.txt
@@ -1,6 +1,6 @@
|
||||
OpenSceneGraph Library 3.0.0
|
||||
OpenSceneGraph Library 3.0.1
|
||||
|
||||
464 Contributors:
|
||||
466 Contributors:
|
||||
|
||||
Firstname Surname
|
||||
-----------------
|
||||
@@ -14,9 +14,9 @@ Mike Weiblen
|
||||
Jean-S<>bastien Guay
|
||||
Farshid Lashkari
|
||||
Eric Wing
|
||||
Wang Rui
|
||||
Ulrich Hertlein
|
||||
Cedric Pinson
|
||||
Wang Rui
|
||||
Brede Johansen
|
||||
Sukender
|
||||
Michael Platings
|
||||
@@ -36,8 +36,8 @@ Roland Smeenk
|
||||
Roger James
|
||||
Jeremy Moles
|
||||
Chris Hanson
|
||||
Mattias Helsing
|
||||
Jason Beverage
|
||||
Mattias Helsing
|
||||
Jan Peciva
|
||||
Andy Skinner
|
||||
Paul Melis
|
||||
@@ -46,11 +46,11 @@ David Fries
|
||||
Tom Jolley
|
||||
Pavel Moloshtan
|
||||
Jason Daly
|
||||
Alberto Luaces
|
||||
Philip Lowman
|
||||
Per Fahlberg
|
||||
Norman Vine
|
||||
Art Tevs
|
||||
Alberto Luaces
|
||||
Serge Lages
|
||||
Magnus Kessler
|
||||
Laurens Voerman
|
||||
@@ -116,6 +116,7 @@ Loic Dachary
|
||||
Joseph Steel
|
||||
Jorge Izquierdo
|
||||
John Shue
|
||||
Johannes Baeuerle
|
||||
Chuck Seberino
|
||||
Brad Colbert
|
||||
Vivek Rajan
|
||||
@@ -133,7 +134,6 @@ Mihai Radu
|
||||
Michael Hartman
|
||||
Martins Innus
|
||||
Maciej Krol
|
||||
Johannes Baeuerle
|
||||
Johan Nouvel
|
||||
Hartwig Wiesmann
|
||||
Frederic Bouvier
|
||||
@@ -163,6 +163,7 @@ Bruce Clay
|
||||
Bradley Anderegg
|
||||
Andreas Goebel
|
||||
Alok Priyadarshi
|
||||
Alexander Irion
|
||||
Alberto Barbati
|
||||
Alan Dickinson
|
||||
Vladimir Shabanov
|
||||
@@ -172,6 +173,7 @@ Thomas Hogarth
|
||||
Sohey Yamamoto
|
||||
Sergey Leontyev
|
||||
Santosh Gaikwad
|
||||
Ryan Pavlik
|
||||
Rudolf Wiedemann
|
||||
Rene Molenaar
|
||||
Phil Atkin
|
||||
@@ -204,7 +206,6 @@ Andrew Bettison
|
||||
Anders Backman
|
||||
Ali Botorabi
|
||||
Alexander Wiebel
|
||||
Alexander Irion
|
||||
Zach Deedler
|
||||
Yuzhong Shen
|
||||
Warren Macchi
|
||||
@@ -217,7 +218,6 @@ Stephane Simon
|
||||
Stephan Eilemann
|
||||
Stanislav Blinov
|
||||
Sebastian Messerschmidt
|
||||
Ryan Pavlik
|
||||
Raymond de Vries
|
||||
Ralf Kern
|
||||
Piotr Gwiazdowski
|
||||
@@ -326,6 +326,7 @@ Pierre Bourdin
|
||||
Philipp Svehla
|
||||
Philipp Siemoleit
|
||||
Philipp M<>chler
|
||||
Philip Lamb
|
||||
Petr Salinger
|
||||
Peter Bear
|
||||
Peter Amstutz
|
||||
@@ -434,6 +435,7 @@ Dan Minor
|
||||
C<EFBFBD>sar L. B. Silveira
|
||||
Cyril Brulebois
|
||||
Clay Fowler
|
||||
Claus Scheiblauer
|
||||
Chuck Sembroski
|
||||
Christopher Blaesius
|
||||
Christian Kaser
|
||||
|
||||
@@ -31,7 +31,7 @@ PROJECT(OpenSceneGraph)
|
||||
|
||||
SET(OPENSCENEGRAPH_MAJOR_VERSION 3)
|
||||
SET(OPENSCENEGRAPH_MINOR_VERSION 0)
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION 0)
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION 1)
|
||||
SET(OPENSCENEGRAPH_SOVERSION 80)
|
||||
|
||||
# set to 0 when not a release candidate, non zero means that any generated
|
||||
|
||||
@@ -16,7 +16,7 @@ ELSEIF(MSVC80)
|
||||
SET(FBX_LIBDIR "vs2005")
|
||||
ELSEIF(MSVC90)
|
||||
SET(FBX_LIBDIR "vs2008")
|
||||
ELSEIF(MSVC100 OR MSVC_VER>1600)
|
||||
ELSEIF(MSVC10 OR MSVC_VERSION>1600)
|
||||
SET(FBX_LIBDIR "vs2010")
|
||||
ENDIF()
|
||||
|
||||
|
||||
252
ChangeLog
252
ChangeLog
@@ -1,3 +1,255 @@
|
||||
2011-07-31 07:50 robert
|
||||
|
||||
* CMakeLists.txt: Changed release candidate numbe for 3.0.1
|
||||
release.
|
||||
|
||||
2011-07-31 07:48 robert
|
||||
|
||||
* src/osgShadow/StandardShadowMap.cpp: Changed the handling of the
|
||||
ambient contribution of light to avoid lighting errors in the
|
||||
shadowed region outside a spointlight.
|
||||
|
||||
2011-07-29 07:44 robert
|
||||
|
||||
* src/osgViewer/ViewerEventHandlers.cpp: Merged from svn/trunk
|
||||
revision 12735, fixed console output of end of frame barrier
|
||||
position.
|
||||
|
||||
2011-07-28 16:59 robert
|
||||
|
||||
* AUTHORS.txt, CMakeLists.txt, ChangeLog: Updated ChangeLog and
|
||||
release candidate number for 3.0.1-rc3
|
||||
|
||||
2011-07-28 16:41 robert
|
||||
|
||||
* src/osgPlugins/dicom/ReaderWriterDICOM.cpp: Improved the handling
|
||||
of scaling of dicom imagery.
|
||||
|
||||
2011-07-28 12:08 robert
|
||||
|
||||
* src/osgViewer/GraphicsWindowX11.cpp: Merged from svn/trunk
|
||||
revision 12722. Refectored the EGL setup so that it's honours the
|
||||
Traits values.
|
||||
|
||||
2011-07-28 11:05 robert
|
||||
|
||||
* src/osg/Texture.cpp, src/osgWrappers/serializers/osg/Texture.cpp:
|
||||
Merged from svn/trunk, revision 12727, Reverted the change to the
|
||||
default setting of _resizeNonPowerOfTwoHint back to true for all
|
||||
platforms to ensure the
|
||||
same behaivour across platforms, something that can be achieved
|
||||
now thanks to the integrated GLU library.
|
||||
|
||||
Corrected the default of the ResizeNonPowerOfTwoHint to true to
|
||||
reflect the actual default setting set by the
|
||||
Texture default constructor.
|
||||
|
||||
2011-07-28 08:19 robert
|
||||
|
||||
* src/osgDB/ObjectWrapper.cpp: From Johannes Baeuerle, merged from
|
||||
svn/trunk revision 12725, "in the file
|
||||
src/osgDB/ObjectWrapper.cpp, where the GlobalLookupTable for gl
|
||||
enums for serialization purposes is defined, some of the
|
||||
compressed texture formats are missing. I added enums for the pvr
|
||||
and etc formats."
|
||||
|
||||
2011-07-28 07:47 robert
|
||||
|
||||
* src/osgViewer/View.cpp: From Jason Beverage, merged from
|
||||
svn/trunk revision 12723, "Here is a small fix for
|
||||
getCameraContainingPosition. getXMin was
|
||||
being used in a case where getYMin should be used instead."
|
||||
|
||||
2011-07-25 19:28 robert
|
||||
|
||||
* AUTHORS.txt, ChangeLog: Updated ChangeLog and AUTHORS file for
|
||||
3.0.1-rc2
|
||||
|
||||
2011-07-25 18:39 robert
|
||||
|
||||
* CMakeLists.txt: Updated release candidate number
|
||||
|
||||
2011-07-25 17:08 robert
|
||||
|
||||
* src/osgViewer/Renderer.cpp: Merged from svn/trunk revision 12818,
|
||||
"Fixed stats bug where not all stats fields were being collected
|
||||
by the cull_draw() method used in the SingleThreaded and
|
||||
CullDrawThreadPerContext threading models."
|
||||
|
||||
2011-07-22 09:28 robert
|
||||
|
||||
* src/osg/Texture.cpp: From Alexander Irion, merged from svn/trunk
|
||||
revision 12716, "Texture borders are not supported in ES.
|
||||
|
||||
_isTextureBorderClampSupported is set to "TRUE" in Texture.cpp,
|
||||
because of the version number check (GL VERSION >= 1.3).
|
||||
|
||||
This leads to an invalid enum error, when GL_TEXTURE_BORDER_COLOR
|
||||
is tried to set."
|
||||
|
||||
2011-07-22 08:26 robert
|
||||
|
||||
* src/osgViewer/ViewerEventHandlers.cpp: Merged from svn/trunk
|
||||
revision 12714, "In the RecordCameraPathhandler fixed the
|
||||
handling of pressing 'Z' before 'z' which was causing the view
|
||||
to be reset to 0,0,0 by AnimationPathManipualtor with an empty
|
||||
AnimationPath."
|
||||
|
||||
2011-07-21 09:54 robert
|
||||
|
||||
* AUTHORS.txt, CMakeLists.txt, ChangeLog,
|
||||
applications/osgversion/Contributors.cpp, include/osg/Version:
|
||||
Updated ChangeLog, Version and AUTHORS file for 3.0.1-rc1
|
||||
|
||||
2011-07-21 09:19 robert
|
||||
|
||||
* src/osgText/TextBase.cpp: Merged from svn/trunk, workaround to
|
||||
culling issues assocaited with text that is set to scale relative
|
||||
to screen coords or is rotated to the screen.
|
||||
|
||||
2011-07-21 09:10 robert
|
||||
|
||||
* src/osgPlugins/vrml/ReaderWriterVRML2.cpp: From Mathias
|
||||
Froehlich, merged from svn/trunk revision 12708, "I have attached
|
||||
an updated version of the VRML2 loader.
|
||||
That change is the result of the '[osgPlugins] VRML plugin -
|
||||
"file" url'
|
||||
discussion on osg-users.
|
||||
|
||||
The attached change avoids rewriting file names into some kind of
|
||||
file urls
|
||||
and then use the url for opening an fstream. Instead just use the
|
||||
given file
|
||||
name to open the stream.
|
||||
Also this change adds some Notify output for the error paths."
|
||||
|
||||
2011-07-21 08:53 robert
|
||||
|
||||
* CMakeModules/FindFBX.cmake: From Wang Rui, merged from svn/trunk
|
||||
revision 12706, "This fixes a small problem in the FindFBX file.
|
||||
In CMake scripts,
|
||||
VS2010 is not marked as MSVC100 but MSVC10. And CMake defines
|
||||
MSVC_VERSION instead of MSVC_VER to indicate the version number.
|
||||
The
|
||||
modification can find fbx sdk for VS2010 automatically now.
|
||||
"
|
||||
|
||||
2011-07-20 10:18 robert
|
||||
|
||||
* src/osgQt/GraphicsWindowQt.cpp: From Claus Scheiblauer, merged
|
||||
from svn/trunk revision 12704, fixed handling of horizontal mouse
|
||||
wheel event
|
||||
|
||||
2011-07-18 12:44 robert
|
||||
|
||||
* include/osgSim/ElevationSlice, include/osgSim/HeightAboveTerrain,
|
||||
include/osgSim/LineOfSight: Merged from svn/trunk revision 12701.
|
||||
Added doxygen comments explain read file callback functionality.
|
||||
|
||||
2011-07-18 09:42 robert
|
||||
|
||||
* src/osgPlugins/dicom/ReaderWriterDICOM.cpp: Merged from svn/trunk
|
||||
revision, 12699, build fix for Cygwin/Mingw builds of DCMTK.
|
||||
|
||||
2011-07-17 16:26 robert
|
||||
|
||||
* applications/osgarchive/osgarchive.cpp,
|
||||
applications/osgfilecache/osgfilecache.cpp,
|
||||
applications/present3D/Cluster.cpp,
|
||||
examples/osganalysis/osganalysis.cpp,
|
||||
examples/osgpagedlod/osgpagedlod.cpp,
|
||||
examples/osgparticleeffects/osgparticleeffects.cpp,
|
||||
examples/osgwidgetmenu/osgwidgetmenu.cpp,
|
||||
src/osgPlugins/ogr/ReaderWriterOGR.cpp,
|
||||
src/osgPlugins/quicktime/ReaderWriterQT.cpp,
|
||||
src/osgPlugins/stl/ReaderWriterSTL.cpp,
|
||||
src/osgPlugins/txp/trpage_header.cpp: From Alberto Luaces, merged
|
||||
from svn/trunk revision 12697, typo fixes
|
||||
|
||||
2011-07-17 10:33 robert
|
||||
|
||||
* src/osgPlugins/osg/AsciiStreamOperator.h: From Wang Rui, merged
|
||||
from svn/trunk revision 12695. "improved the handling of the
|
||||
_preReadString within the readWrappedString method by factoring
|
||||
the
|
||||
reading of the next character into a dedicated getCharacter(..)
|
||||
method."
|
||||
|
||||
2011-07-15 10:25 robert
|
||||
|
||||
* src/osgPlugins/ffmpeg/FFmpegDecoder.cpp,
|
||||
src/osgPlugins/ffmpeg/FFmpegParameters.cpp: From Wang Rui, merged
|
||||
from svn/trunk revision 12693, "I've found that the latest ffmpeg
|
||||
made some functions and macros
|
||||
deprecated, which led to compilation errors in the OSG plugin. I
|
||||
tried
|
||||
fixing them and tested with the version ffmpeg-git-5d4fd1d
|
||||
(ffmpeg
|
||||
version > 0.8, libavcodec = 53.7.0) under Windows."
|
||||
|
||||
2011-07-15 09:48 robert
|
||||
|
||||
* include/osg/ValueObject: From Sukender, merged from svn/trunk
|
||||
revision 12690. Fixed compiler error "public: static char const *
|
||||
const osg::ValueObjectClassNameTrait< xxx >::s_className" already
|
||||
defined in xxx.obj"
|
||||
|
||||
2011-07-15 09:16 robert
|
||||
|
||||
* src/osgPlugins/osg/AsciiStreamOperator.h,
|
||||
src/osgWrappers/serializers/osgSim/LightPointNode.cpp,
|
||||
src/osgWrappers/serializers/osgSim/MultiSwitch.cpp: From Wang
|
||||
Rui, merged from svn/trunk revision 12688. "The files attached
|
||||
should be separately put into the directories
|
||||
src/osgPlugins/osg and src/osgWrappers/serializers/osgSim. They
|
||||
fix a
|
||||
serious infinite loop problem that may be caused by the stream
|
||||
buffer
|
||||
mechanism under Windows and some osgSim wrapper bugs pointed by
|
||||
Andreas. I've asked the community to help test them and hope now
|
||||
we
|
||||
can solve these recent .osgt file reading issues."
|
||||
|
||||
2011-07-15 08:45 robert
|
||||
|
||||
* src/osgPlugins/Inventor/ConvertToInventor.h: From Ryan Pavlik,
|
||||
Merged from svn/trunk revision 12686. "Fix inventor state copy
|
||||
constructor.
|
||||
|
||||
Clang warning:
|
||||
In file included from
|
||||
src/osgPlugins/Inventor/ConvertToInventor.cpp:80:
|
||||
src/osgPlugins/Inventor/ConvertToInventor.h:117:71: warning:
|
||||
field is uninitialized when used here [-Wuninitialized]
|
||||
osgTexGenS(s.osgTexGenS), osgTexGenT(s.osgTexGenT),
|
||||
osgTexGen(osgTexGen),
|
||||
^"
|
||||
|
||||
2011-07-15 08:37 robert
|
||||
|
||||
* src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp: From Philip
|
||||
Lamp, Merged from svn/trunk revision 12683. "Modify the
|
||||
ReaderWriteImageIO_IOS to correctly handle relative paths
|
||||
when reading from a file. This means that no longer do all image
|
||||
files
|
||||
have to live at the root of the Resources folder inside the app
|
||||
bundle,
|
||||
but can now be organized inside folders. Also improved error
|
||||
handling
|
||||
and fixed a potential leak of a CGColorSpaceRef each once per
|
||||
image load."
|
||||
|
||||
2011-07-15 08:35 robert
|
||||
|
||||
* src/osgPlugins/imageio/ReaderWriterImageIO.cpp,
|
||||
src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp: Removed
|
||||
redudent lines and changes tabs to four spaces
|
||||
|
||||
2011-06-28 07:52 robert
|
||||
|
||||
* ChangeLog, applications/osgversion/Contributors.cpp: Updated
|
||||
ChangeLog and add fix for typo of name
|
||||
|
||||
2011-06-28 07:37 robert
|
||||
|
||||
* NEWS.txt: Fixed typo and added entry about osgParticle.
|
||||
|
||||
@@ -27,7 +27,7 @@ more indepth instructions.
|
||||
|
||||
Robert Osfield.
|
||||
Project Lead.
|
||||
28th June 2011.
|
||||
31st July 2011.
|
||||
|
||||
--
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ int main( int argc, char **argv )
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an application for collecting a set of seperate files into a single archive file that can be later read in OSG applications..");
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an application for collecting a set of separate files into a single archive file that can be later read in OSG applications..");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
|
||||
// if user request help write it out to cout.
|
||||
|
||||
@@ -451,7 +451,7 @@ int main( int argc, char **argv )
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an application for collecting a set of seperate files into a single archive file that can be later read in OSG applications..");
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an application for collecting a set of separate files into a single archive file that can be later read in OSG applications..");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-l level","Read down to level across the whole database.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-e level minX minY maxX maxY","Read down to <level> across the extents minX, minY to maxY, maxY. Note, for geocentric datase X and Y are longitude and latitude respectively.");
|
||||
|
||||
@@ -454,6 +454,8 @@ struct NameCorrection
|
||||
|
||||
NameCorrection nameCorrections[] =
|
||||
{
|
||||
{"Philip","Lamp",
|
||||
"Philip", "Lamb"},
|
||||
{"Dimi","Christop",
|
||||
"Dimi", "Christopoulos"},
|
||||
{"Jorge","Ciges",
|
||||
|
||||
@@ -240,7 +240,7 @@ void CameraPacket::readEventQueue(osgViewer::Viewer& viewer)
|
||||
|
||||
void CameraPacket::writeEventQueue(osgViewer::Viewer& viewer)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"recieved events = "<<_events.size()<<std::endl;
|
||||
osg::notify(osg::INFO)<<"received events = "<<_events.size()<<std::endl;
|
||||
|
||||
// copy the events to osgProducer style events.
|
||||
viewer.getEventQueue()->appendEvents(_events);
|
||||
|
||||
@@ -134,11 +134,11 @@ public:
|
||||
|
||||
if (_imageProcessor.valid())
|
||||
{
|
||||
OSG_NOTICE<<"Will be using ImageProcessor to proces image "<<image->getFileName()<<std::endl;
|
||||
OSG_NOTICE<<"Will be using ImageProcessor to process image "<<image->getFileName()<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"No ImageProcessor to proces image "<<image->getFileName()<<std::endl;
|
||||
OSG_NOTICE<<"No ImageProcessor to process image "<<image->getFileName()<<std::endl;
|
||||
}
|
||||
OSG_NOTICE<<" compressImage "<<_compressImages<<std::endl;
|
||||
OSG_NOTICE<<" generateMipmaps "<<_generateMipmaps<<std::endl;
|
||||
|
||||
@@ -217,7 +217,7 @@ int main( int argc, char **argv )
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" creates a hierachy of files for paging which can be later loaded by viewers.");
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" creates a hierarchy of files for paging which can be later loaded by viewers.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-o","set the output file (defaults to output.ive)");
|
||||
|
||||
@@ -316,7 +316,7 @@ public:
|
||||
{
|
||||
// insert particle effects alongside the hit node, therefore able to track that nodes movement,
|
||||
// however, this does require us to insert the ParticleSystem itself into the root of the scene graph
|
||||
// seperately from the the main particle effects group which contains the emitters and programs.
|
||||
// separately from the the main particle effects group which contains the emitters and programs.
|
||||
// the follow code block implements this, note the path for handling particle effects which arn't attached to
|
||||
// moving models is easy - just a single line of code!
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
menu->addWidget(new ColorLabelMenu("Pick me!"));
|
||||
menu->addWidget(new ColorLabelMenu("No, wait, pick me!"));
|
||||
menu->addWidget(new ColorLabelMenu("Dont pick them..."));
|
||||
menu->addWidget(new ColorLabelMenu("Don't pick them..."));
|
||||
menu->addWidget(new ColorLabelMenu("Grarar!?!"));
|
||||
|
||||
wm->addChild(menu);
|
||||
|
||||
@@ -98,12 +98,9 @@ class ValueObject : public Object
|
||||
template< typename T >
|
||||
struct ValueObjectClassNameTrait
|
||||
{
|
||||
static const char* s_className;
|
||||
static const char* className() { return "TemplateValueObject"; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
const char* ValueObjectClassNameTrait<T>::s_className = "TemplateValueObject";
|
||||
|
||||
|
||||
template< typename T >
|
||||
class TemplateValueObject : public ValueObject
|
||||
@@ -126,7 +123,7 @@ class TemplateValueObject : public ValueObject
|
||||
virtual Object* clone(const CopyOp& copyop) const { return new TemplateValueObject(*this, copyop); }
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const TemplateValueObject*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return ValueObjectClassNameTrait<T>::s_className; }
|
||||
virtual const char* className() const { return ValueObjectClassNameTrait<T>::className(); }
|
||||
|
||||
void setValue(const T& value) { _value = value; }
|
||||
const T& getValue() const { return _value; }
|
||||
@@ -142,8 +139,7 @@ protected:
|
||||
};
|
||||
|
||||
#define META_ValueObject(TYPE,NAME) \
|
||||
template<> struct ValueObjectClassNameTrait<TYPE> { static const char* s_className; }; \
|
||||
const char* ValueObjectClassNameTrait<TYPE>::s_className = #NAME; \
|
||||
template<> struct ValueObjectClassNameTrait<TYPE> { static const char* className() { return #NAME; } }; \
|
||||
typedef TemplateValueObject<TYPE> NAME;
|
||||
|
||||
META_ValueObject(std::string, StringValueObject)
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
|
||||
#define OPENSCENEGRAPH_MAJOR_VERSION 3
|
||||
#define OPENSCENEGRAPH_MINOR_VERSION 0
|
||||
#define OPENSCENEGRAPH_PATCH_VERSION 0
|
||||
#define OPENSCENEGRAPH_PATCH_VERSION 1
|
||||
#define OPENSCENEGRAPH_SOVERSION 80
|
||||
|
||||
/* Convenience macro that can be used to decide whether a feature is present or not i.e.
|
||||
|
||||
@@ -21,7 +21,14 @@
|
||||
|
||||
namespace osgSim {
|
||||
|
||||
/** Helper class for setting up and acquiring height above terrain intersections with terrain.*/
|
||||
/** Helper class for setting up and acquiring height above terrain intersections with terrain.
|
||||
* By default assigns a osgSim::DatabaseCacheReadCallback that enables automatic loading
|
||||
* of external PagedLOD tiles to ensure that the highest level of detail is used in intersections.
|
||||
* This automatic loading of tiles is done by the intersection traversal that is done within
|
||||
* the computeIntersections(..) method, so can result in long intersection times when external
|
||||
* tiles have to be loaded.
|
||||
* The external loading of tiles can be disabled by removing the read callback, this is done by
|
||||
* calling the setDatabaseCacheReadCallback(DatabaseCacheReadCallback*) method with a value of 0.*/
|
||||
class OSGSIM_EXPORT ElevationSlice
|
||||
{
|
||||
public :
|
||||
|
||||
@@ -21,7 +21,14 @@
|
||||
|
||||
namespace osgSim {
|
||||
|
||||
/** Helper class for setting up and acquiring height above terrain intersections with terrain.*/
|
||||
/** Helper class for setting up and acquiring height above terrain intersections with terrain.
|
||||
* By default assigns a osgSim::DatabaseCacheReadCallback that enables automatic loading
|
||||
* of external PagedLOD tiles to ensure that the highest level of detail is used in intersections.
|
||||
* This automatic loading of tiles is done by the intersection traversal that is done within
|
||||
* the computeIntersections(..) method, so can result in long intersection times when external
|
||||
* tiles have to be loaded.
|
||||
* The external loading of tiles can be disabled by removing the read callback, this is done by
|
||||
* calling the setDatabaseCacheReadCallback(DatabaseCacheReadCallback*) method with a value of 0.*/
|
||||
class OSGSIM_EXPORT HeightAboveTerrain
|
||||
{
|
||||
public :
|
||||
|
||||
@@ -44,7 +44,13 @@ class OSGSIM_EXPORT DatabaseCacheReadCallback : public osgUtil::IntersectionVisi
|
||||
};
|
||||
|
||||
/** Helper class for setting up and acquiring line of sight intersections with terrain.
|
||||
* Supports automatic paging in of PagedLOD tiles. */
|
||||
* By default assigns a osgSim::DatabaseCacheReadCallback that enables automatic loading
|
||||
* of external PagedLOD tiles to ensure that the highest level of detail is used in intersections.
|
||||
* This automatic loading of tiles is done by the intersection traversal that is done within
|
||||
* the computeIntersections(..) method, so can result in long intersection times when external
|
||||
* tiles have to be loaded.
|
||||
* The external loading of tiles can be disabled by removing the read callback, this is done by
|
||||
* calling the setDatabaseCacheReadCallback(DatabaseCacheReadCallback*) method with a value of 0.*/
|
||||
class OSGSIM_EXPORT LineOfSight
|
||||
{
|
||||
public :
|
||||
|
||||
@@ -94,7 +94,7 @@ void Texture::TextureObject::setAllocated(GLint numMipmapLevels,
|
||||
// Update texture pool size
|
||||
_set->getParent()->getCurrTexturePoolSize() -= previousSize;
|
||||
_set->getParent()->getCurrTexturePoolSize() += _profile._size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,7 +1078,7 @@ Texture::Texture():
|
||||
_useHardwareMipMapGeneration(true),
|
||||
_unrefImageDataAfterApply(false),
|
||||
_clientStorageHint(false),
|
||||
_resizeNonPowerOfTwoHint(!OSG_GLES2_FEATURES && !OSG_GL3_FEATURES),
|
||||
_resizeNonPowerOfTwoHint(true),
|
||||
_borderColor(0.0, 0.0, 0.0, 0.0),
|
||||
_borderWidth(0),
|
||||
_internalFormatMode(USE_IMAGE_DATA_FORMAT),
|
||||
@@ -2479,7 +2479,9 @@ Texture::Extensions::Extensions(unsigned int contextID)
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2f) ||
|
||||
isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f);
|
||||
|
||||
_isTextureBorderClampSupported = OSG_GL3_FEATURES || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f);
|
||||
|
||||
_isTextureBorderClampSupported = OSG_GL3_FEATURES ||
|
||||
((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f));
|
||||
|
||||
_isGenerateMipMapSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f);
|
||||
|
||||
|
||||
@@ -409,7 +409,12 @@ ObjectWrapperManager::ObjectWrapperManager()
|
||||
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", GL_COMPRESSED_RGBA_S3TC_DXT1_EXT );
|
||||
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT", GL_COMPRESSED_RGBA_S3TC_DXT3_EXT );
|
||||
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT", GL_COMPRESSED_RGBA_S3TC_DXT5_EXT );
|
||||
|
||||
glTable.add( "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG",GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG );
|
||||
glTable.add( "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG",GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG );
|
||||
glTable.add( "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG );
|
||||
glTable.add( "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG );
|
||||
glTable.add( "GL_ETC1_RGB8_OES",GL_ETC1_RGB8_OES );
|
||||
|
||||
// Texture source types
|
||||
glTable.add( "GL_BYTE", GL_BYTE );
|
||||
glTable.add( "GL_SHORT", GL_SHORT );
|
||||
|
||||
@@ -114,7 +114,7 @@ protected:
|
||||
InventorState(const InventorState &s) : ivHead(s.ivHead), ivTexture(s.ivTexture),
|
||||
ivMaterial(s.ivMaterial), osgMaterial(s.osgMaterial),
|
||||
osgTexture2Enabled(s.osgTexture2Enabled), osgTexture(s.osgTexture), osgTexEnv(s.osgTexEnv),
|
||||
osgTexGenS(s.osgTexGenS), osgTexGenT(s.osgTexGenT), osgTexGen(osgTexGen),
|
||||
osgTexGenS(s.osgTexGenS), osgTexGenT(s.osgTexGenT), osgTexGen(s.osgTexGen),
|
||||
osgLighting(s.osgLighting), osgTwoSided(s.osgTwoSided), osgFrontFace(s.osgFrontFace),
|
||||
osgCullFaceEnabled(s.osgCullFaceEnabled), osgCullFace(s.osgCullFace),
|
||||
osgBlendEnabled(s.osgBlendEnabled), osgBlendFunc(s.osgBlendFunc) {}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <osgVolume/RayTracedTechnique>
|
||||
|
||||
#ifdef USE_DCMTK
|
||||
#ifndef _WIN32
|
||||
#ifndef _MSC_VER
|
||||
#define HAVE_CONFIG_H
|
||||
#endif
|
||||
|
||||
@@ -559,8 +559,6 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
osg::ref_ptr<osgVolume::ImageDetails> details = new osgVolume::ImageDetails;
|
||||
details->setMatrix(new osg::RefMatrix);
|
||||
|
||||
osg::ref_ptr<osg::Image> image;
|
||||
|
||||
unsigned int imageNum = 0;
|
||||
EP_Representation pixelRep = EPR_Uint8;
|
||||
int numPlanes = 0;
|
||||
@@ -575,8 +573,6 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap;
|
||||
OrientationFileInfoMap orientationFileInfoMap;
|
||||
|
||||
unsigned int totalNumSlices = 0;
|
||||
|
||||
typedef std::map<std::string, ReadResult> ErrorMap;
|
||||
ErrorMap errorMap;
|
||||
|
||||
@@ -596,13 +592,6 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
FileInfo fileInfo;
|
||||
fileInfo.filename = *itr;
|
||||
|
||||
double pixelSize_y = 1.0;
|
||||
double pixelSize_x = 1.0;
|
||||
double sliceThickness = 1.0;
|
||||
double imagePositionPatient[3] = {0, 0, 0};
|
||||
double imageOrientationPatient[6] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
|
||||
Uint16 numOfSlices = 1;
|
||||
|
||||
// code for reading the intercept and scale that is required to convert to Hounsfield units.
|
||||
bool rescaling = false;
|
||||
double rescaleIntercept = 0.0;
|
||||
@@ -632,28 +621,33 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
double value = 0.0;
|
||||
if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,0).good())
|
||||
{
|
||||
pixelSize_y = value;
|
||||
fileInfo.matrix(1,1) = pixelSize_y;
|
||||
fileInfo.pixelSize_x = value;
|
||||
}
|
||||
|
||||
if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,1).good())
|
||||
{
|
||||
pixelSize_x = value;
|
||||
fileInfo.matrix(0,0) = pixelSize_x;
|
||||
fileInfo.pixelSize_y = value;
|
||||
}
|
||||
|
||||
if (fileformat.getDataset()->findAndGetFloat64(DCM_SpacingBetweenSlices, value,0).good())
|
||||
{
|
||||
info()<<"DCM_SpacingBetweenSlices = "<<value<<std::endl;
|
||||
fileInfo.sliceThickness = value;
|
||||
}
|
||||
|
||||
|
||||
// Get slice thickness
|
||||
if (fileformat.getDataset()->findAndGetFloat64(DCM_SliceThickness, value).good())
|
||||
{
|
||||
sliceThickness = value;
|
||||
info()<<"sliceThickness = "<<sliceThickness<<std::endl;
|
||||
fileInfo.sliceThickness = sliceThickness;
|
||||
info()<<"DCM_SliceThickness = "<<value<<std::endl;
|
||||
fileInfo.sliceThickness = value;
|
||||
}
|
||||
|
||||
info()<<"tagExistsWithValue(DCM_NumberOfFrames)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfFrames)<<std::endl;
|
||||
info()<<"tagExistsWithValue(DCM_NumberOfSlices)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfSlices)<<std::endl;
|
||||
|
||||
Uint32 numFrames;
|
||||
Uint16 numOfSlices = 1;
|
||||
Uint32 numFrames = 1;
|
||||
if (fileformat.getDataset()->findAndGetUint32(DCM_NumberOfFrames, numFrames).good())
|
||||
{
|
||||
fileInfo.numSlices = numFrames;
|
||||
@@ -681,8 +675,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
}
|
||||
|
||||
|
||||
|
||||
// patient position
|
||||
double imagePositionPatient[3] = {0.0, 0.0, 0.0};
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
if (fileformat.getDataset()->findAndGetFloat64(DCM_ImagePositionPatient, imagePositionPatient[i],i).good())
|
||||
@@ -694,10 +688,9 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
info()<<"Have not read DCM_ImagePositionPatient["<<i<<"]"<<std::endl;
|
||||
}
|
||||
}
|
||||
//info()<<"imagePositionPatient[2]="<<imagePositionPatient[2]<<std::endl;
|
||||
|
||||
fileInfo.matrix.setTrans(imagePositionPatient[0],imagePositionPatient[1],imagePositionPatient[2]);
|
||||
fileInfo.position.set(imagePositionPatient[0],imagePositionPatient[1],imagePositionPatient[2]);
|
||||
|
||||
double imageOrientationPatient[6] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
|
||||
for(int i=0; i<6; ++i)
|
||||
{
|
||||
double value = 0.0;
|
||||
@@ -712,232 +705,240 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
}
|
||||
}
|
||||
|
||||
osg::Vec3d dirX(imageOrientationPatient[0],imageOrientationPatient[1],imageOrientationPatient[2]);
|
||||
osg::Vec3d dirY(imageOrientationPatient[3],imageOrientationPatient[4],imageOrientationPatient[5]);
|
||||
osg::Vec3d dirZ = dirX ^ dirY;
|
||||
dirZ.normalize();
|
||||
fileInfo.dirX.set(imageOrientationPatient[0],imageOrientationPatient[1],imageOrientationPatient[2]);
|
||||
fileInfo.dirY.set(imageOrientationPatient[3],imageOrientationPatient[4],imageOrientationPatient[5]);
|
||||
fileInfo.dirZ = fileInfo.dirX ^ fileInfo.dirY;
|
||||
fileInfo.dirZ.normalize();
|
||||
fileInfo.distance = fileInfo.dirZ * fileInfo.position;
|
||||
|
||||
dirX *= pixelSize_x;
|
||||
dirY *= pixelSize_y;
|
||||
|
||||
fileInfo.matrix(0,0) = dirX[0];
|
||||
fileInfo.matrix(1,0) = dirX[1];
|
||||
fileInfo.matrix(2,0) = dirX[2];
|
||||
info()<<"pixelSize_x="<<fileInfo.pixelSize_x<<std::endl;
|
||||
info()<<"pixelSize_y="<<fileInfo.pixelSize_x<<std::endl;
|
||||
|
||||
fileInfo.matrix(0,1) = dirY[0];
|
||||
fileInfo.matrix(1,1) = dirY[1];
|
||||
fileInfo.matrix(2,1) = dirY[2];
|
||||
|
||||
fileInfo.matrix(0,2) = dirZ[0];
|
||||
fileInfo.matrix(1,2) = dirZ[1];
|
||||
fileInfo.matrix(2,2) = dirZ[2];
|
||||
|
||||
fileInfo.distance = dirZ * (osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix);
|
||||
|
||||
info()<<"dirX = "<<dirX<<std::endl;
|
||||
info()<<"dirY = "<<dirY<<std::endl;
|
||||
info()<<"dirZ = "<<dirZ<<std::endl;
|
||||
info()<<"matrix = "<<fileInfo.matrix<<std::endl;
|
||||
info()<<"pos = "<<osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix<<std::endl;
|
||||
info()<<"dirX.length() = "<<fileInfo.dirX.length()<<std::endl;
|
||||
info()<<"dirY.length() = "<<fileInfo.dirY.length()<<std::endl;
|
||||
info()<<"dot_product = "<<fileInfo.dirX*fileInfo.dirY<<std::endl;
|
||||
info()<<"dirX = "<<fileInfo.dirX<<std::endl;
|
||||
info()<<"dirY = "<<fileInfo.dirY<<std::endl;
|
||||
info()<<"dirZ = "<<fileInfo.dirZ<<std::endl;
|
||||
info()<<"pos = "<<fileInfo.position<<std::endl;
|
||||
info()<<"dist = "<<fileInfo.distance<<std::endl;
|
||||
info()<<std::endl;
|
||||
|
||||
(orientationFileInfoMap[dirZ])[fileInfo.distance] = fileInfo;
|
||||
|
||||
totalNumSlices += fileInfo.numSlices;
|
||||
(orientationFileInfoMap[fileInfo.dirZ])[fileInfo.distance] = fileInfo;
|
||||
|
||||
}
|
||||
|
||||
if (orientationFileInfoMap.empty()) return 0;
|
||||
|
||||
typedef std::map<double, FileInfo> DistanceFileInfoMap;
|
||||
typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap;
|
||||
for(OrientationFileInfoMap::iterator itr = orientationFileInfoMap.begin();
|
||||
itr != orientationFileInfoMap.end();
|
||||
++itr)
|
||||
{
|
||||
info()<<"Orientation = "<<itr->first<<std::endl;
|
||||
|
||||
unsigned int totalNumSlices = 0;
|
||||
|
||||
DistanceFileInfoMap& dfim = itr->second;
|
||||
for(DistanceFileInfoMap::iterator ditr = dfim.begin();
|
||||
ditr != dfim.end();
|
||||
++ditr)
|
||||
{
|
||||
FileInfo& fileInfo = ditr->second;
|
||||
totalNumSlices += fileInfo.numSlices;
|
||||
info()<<" d = "<<fileInfo.distance<<" "<<fileInfo.filename<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (dfim.empty()) continue;
|
||||
|
||||
DistanceFileInfoMap& dfim = orientationFileInfoMap.begin()->second;
|
||||
if (dfim.empty()) return 0;
|
||||
osg::ref_ptr<osg::Image> image;
|
||||
|
||||
double totalDistance = 0.0;
|
||||
if (dfim.size()>1)
|
||||
{
|
||||
totalDistance = fabs(dfim.rbegin()->first - dfim.begin()->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalDistance = dfim.begin()->second.sliceThickness * double(dfim.begin()->second.numSlices);
|
||||
}
|
||||
|
||||
info()<<"Total Distance including ends "<<totalDistance<<std::endl;
|
||||
|
||||
double averageThickness = totalNumSlices<=1 ? 1.0 : totalDistance / double(totalNumSlices-1);
|
||||
|
||||
info()<<"Average thickness "<<averageThickness<<std::endl;
|
||||
|
||||
for(DistanceFileInfoMap::iterator ditr = dfim.begin();
|
||||
ditr != dfim.end();
|
||||
++ditr)
|
||||
{
|
||||
FileInfo& fileInfo = ditr->second;
|
||||
|
||||
std::auto_ptr<DicomImage> dcmImage(new DicomImage(fileInfo.filename.c_str()));
|
||||
if (dcmImage.get())
|
||||
double totalDistance = 0.0;
|
||||
if (dfim.size()>1)
|
||||
{
|
||||
if (dcmImage->getStatus()==EIS_Normal)
|
||||
totalDistance = fabs(dfim.rbegin()->first - dfim.begin()->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalDistance = dfim.begin()->second.sliceThickness * double(dfim.begin()->second.numSlices);
|
||||
}
|
||||
|
||||
info()<<"Total Number slices "<<totalNumSlices<<std::endl;
|
||||
info()<<"Total Distance including ends "<<totalDistance<<std::endl;
|
||||
|
||||
double averageThickness = totalNumSlices<=1 ? 1.0 : totalDistance / double(totalNumSlices-1);
|
||||
|
||||
info()<<"Average thickness "<<averageThickness<<std::endl;
|
||||
|
||||
for(DistanceFileInfoMap::iterator ditr = dfim.begin();
|
||||
ditr != dfim.end();
|
||||
++ditr)
|
||||
{
|
||||
FileInfo& fileInfo = ditr->second;
|
||||
|
||||
std::auto_ptr<DicomImage> dcmImage(new DicomImage(fileInfo.filename.c_str()));
|
||||
if (dcmImage.get())
|
||||
{
|
||||
|
||||
EP_Representation curr_pixelRep;
|
||||
int curr_numPlanes;
|
||||
GLenum curr_pixelFormat;
|
||||
GLenum curr_dataType;
|
||||
unsigned int curr_pixelSize;
|
||||
|
||||
// get the pixel data
|
||||
const DiPixel* pixelData = dcmImage->getInterData();
|
||||
if(!pixelData)
|
||||
if (dcmImage->getStatus()==EIS_Normal)
|
||||
{
|
||||
warning()<<"Error: no data in DicomImage object."<<std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
// create the new image
|
||||
convertPixelTypes(pixelData,
|
||||
curr_pixelRep, curr_numPlanes,
|
||||
curr_dataType, curr_pixelFormat, curr_pixelSize);
|
||||
EP_Representation curr_pixelRep;
|
||||
int curr_numPlanes;
|
||||
GLenum curr_pixelFormat;
|
||||
GLenum curr_dataType;
|
||||
unsigned int curr_pixelSize;
|
||||
|
||||
// dcmImage->getFrameCount()
|
||||
|
||||
osg::ref_ptr<osg::Image> imageAdapter = new osg::Image;
|
||||
|
||||
if (dcmImage->isMonochrome())
|
||||
{
|
||||
imageAdapter->setImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(),
|
||||
curr_pixelFormat,
|
||||
curr_pixelFormat,
|
||||
curr_dataType,
|
||||
(unsigned char*)(pixelData->getData()),
|
||||
osg::Image::NO_DELETE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
imageAdapter->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(),
|
||||
curr_pixelFormat, curr_dataType);
|
||||
|
||||
void* data = imageAdapter->data(0,0,0);
|
||||
unsigned long size = dcmImage->createWindowsDIB( data,
|
||||
imageAdapter->getTotalDataSize(),
|
||||
0,
|
||||
imageAdapter->getPixelSizeInBits(),
|
||||
0,
|
||||
0);
|
||||
|
||||
if (size==0)
|
||||
// get the pixel data
|
||||
const DiPixel* pixelData = dcmImage->getInterData();
|
||||
if(!pixelData)
|
||||
{
|
||||
info()<<" dcmImage->createWindowsDIB() failed to create required imagery."<<std::endl;
|
||||
continue;
|
||||
warning()<<"Error: no data in DicomImage object."<<std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
pixelRep = curr_pixelRep;
|
||||
numPlanes = curr_numPlanes;
|
||||
dataType = curr_dataType;
|
||||
pixelFormat = curr_pixelFormat;
|
||||
pixelSize = curr_pixelSize;
|
||||
|
||||
osg::RefMatrix* matrix = details->getMatrix();
|
||||
|
||||
(*matrix)(0,0) = fileInfo.matrix(0,0);
|
||||
(*matrix)(1,0) = fileInfo.matrix(1,0);
|
||||
(*matrix)(2,0) = fileInfo.matrix(2,0);
|
||||
(*matrix)(0,1) = fileInfo.matrix(0,1);
|
||||
(*matrix)(1,1) = fileInfo.matrix(1,1);
|
||||
(*matrix)(2,1) = fileInfo.matrix(2,1);
|
||||
(*matrix)(0,2) = fileInfo.matrix(0,2) * averageThickness;
|
||||
(*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness;
|
||||
(*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness;
|
||||
|
||||
// note from Robert Osfield, testing various dicom files I have found that the rescaleIntercept
|
||||
// for CT data doesn't look to be applicable as an straight value offset, so we'll ignore for now.
|
||||
// details->setTexelOffset(fileInfo.rescaleIntercept);
|
||||
double s = fileInfo.rescaleSlope;
|
||||
switch(dataType)
|
||||
{
|
||||
case(GL_BYTE): s *= 128.0; break;
|
||||
case(GL_UNSIGNED_BYTE): s *= 255.0; break;
|
||||
case(GL_SHORT): s *= 32768.0; break;
|
||||
case(GL_UNSIGNED_SHORT): s *= 65535.0; break;
|
||||
case(GL_INT): s *= 2147483648.0; break;
|
||||
case(GL_UNSIGNED_INT): s *= 4294967295.0; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
details->setTexelScale(osg::Vec4(s,s,s,s));
|
||||
|
||||
image = new osg::Image;
|
||||
image->setUserData(details.get());
|
||||
image->setFileName(fileName.c_str());
|
||||
image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices,
|
||||
pixelFormat, dataType);
|
||||
|
||||
|
||||
matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r())));
|
||||
|
||||
info()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::dec<<std::endl;
|
||||
}
|
||||
else if (pixelData->getPlanes()>numPlanes ||
|
||||
pixelData->getRepresentation()>pixelRep)
|
||||
{
|
||||
info()<<"Need to reallocated "<<image->s()<<", "<<image->t()<<", "<<image->r()<<std::endl;
|
||||
|
||||
// record the previous image settings to use when we copy back the content.
|
||||
osg::ref_ptr<osg::Image> previous_image = image;
|
||||
|
||||
// create the new image
|
||||
convertPixelTypes(pixelData,
|
||||
pixelRep, numPlanes,
|
||||
dataType, pixelFormat, pixelSize);
|
||||
curr_pixelRep, curr_numPlanes,
|
||||
curr_dataType, curr_pixelFormat, curr_pixelSize);
|
||||
|
||||
image = new osg::Image;
|
||||
image->setUserData(previous_image->getUserData());
|
||||
image->setFileName(fileName.c_str());
|
||||
image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices,
|
||||
pixelFormat, dataType);
|
||||
// dcmImage->getFrameCount()
|
||||
|
||||
osg::copyImage(previous_image.get(), 0,0,0, previous_image->s(), previous_image->t(), imageNum,
|
||||
image.get(), 0, 0, 0,
|
||||
osg::ref_ptr<osg::Image> imageAdapter = new osg::Image;
|
||||
|
||||
if (dcmImage->isMonochrome())
|
||||
{
|
||||
imageAdapter->setImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(),
|
||||
curr_pixelFormat,
|
||||
curr_pixelFormat,
|
||||
curr_dataType,
|
||||
(unsigned char*)(pixelData->getData()),
|
||||
osg::Image::NO_DELETE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
imageAdapter->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(),
|
||||
curr_pixelFormat, curr_dataType);
|
||||
|
||||
void* data = imageAdapter->data(0,0,0);
|
||||
unsigned long size = dcmImage->createWindowsDIB( data,
|
||||
imageAdapter->getTotalDataSize(),
|
||||
0,
|
||||
imageAdapter->getPixelSizeInBits(),
|
||||
0,
|
||||
0);
|
||||
|
||||
if (size==0)
|
||||
{
|
||||
info()<<" dcmImage->createWindowsDIB() failed to create required imagery."<<std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
pixelRep = curr_pixelRep;
|
||||
numPlanes = curr_numPlanes;
|
||||
dataType = curr_dataType;
|
||||
pixelFormat = curr_pixelFormat;
|
||||
pixelSize = curr_pixelSize;
|
||||
|
||||
osg::RefMatrix* matrix = details->getMatrix();
|
||||
|
||||
(*matrix)(0,0) = fileInfo.dirX.x();
|
||||
(*matrix)(1,0) = fileInfo.dirX.y();
|
||||
(*matrix)(2,0) = fileInfo.dirX.z();
|
||||
|
||||
(*matrix)(0,1) = fileInfo.dirY.x();
|
||||
(*matrix)(1,1) = fileInfo.dirY.y();
|
||||
(*matrix)(2,1) = fileInfo.dirY.z();
|
||||
|
||||
(*matrix)(0,2) = fileInfo.dirZ.x();
|
||||
(*matrix)(1,2) = fileInfo.dirZ.y();
|
||||
(*matrix)(2,2) = fileInfo.dirZ.z();
|
||||
|
||||
matrix->preMultScale(osg::Vec3d(
|
||||
fileInfo.pixelSize_x * dcmImage->getWidth(),
|
||||
fileInfo.pixelSize_y * dcmImage->getHeight(),
|
||||
averageThickness * totalNumSlices));
|
||||
|
||||
(*matrix)(3,0) = fileInfo.position.x();
|
||||
(*matrix)(3,1) = fileInfo.position.y();
|
||||
(*matrix)(3,2) = fileInfo.position.z();
|
||||
|
||||
(*matrix)(3,3) = 1.0;
|
||||
|
||||
// note from Robert Osfield, testing various dicom files I have found that the rescaleIntercept
|
||||
// for CT data doesn't look to be applicable as an straight value offset, so we'll ignore for now.
|
||||
// details->setTexelOffset(fileInfo.rescaleIntercept);
|
||||
double s = fileInfo.rescaleSlope;
|
||||
switch(dataType)
|
||||
{
|
||||
case(GL_BYTE): s *= 128.0; break;
|
||||
case(GL_UNSIGNED_BYTE): s *= 255.0; break;
|
||||
case(GL_SHORT): s *= 32768.0; break;
|
||||
case(GL_UNSIGNED_SHORT): s *= 65535.0; break;
|
||||
case(GL_INT): s *= 2147483648.0; break;
|
||||
case(GL_UNSIGNED_INT): s *= 4294967295.0; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
details->setTexelScale(osg::Vec4(s,s,s,s));
|
||||
|
||||
image = new osg::Image;
|
||||
image->setUserData(details.get());
|
||||
image->setFileName(fileName.c_str());
|
||||
image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices,
|
||||
pixelFormat, dataType);
|
||||
|
||||
|
||||
//matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r())));
|
||||
|
||||
info()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::dec<<std::endl;
|
||||
}
|
||||
else if (pixelData->getPlanes()>numPlanes ||
|
||||
pixelData->getRepresentation()>pixelRep)
|
||||
{
|
||||
info()<<"Need to reallocated "<<image->s()<<", "<<image->t()<<", "<<image->r()<<std::endl;
|
||||
|
||||
// record the previous image settings to use when we copy back the content.
|
||||
osg::ref_ptr<osg::Image> previous_image = image;
|
||||
|
||||
// create the new image
|
||||
convertPixelTypes(pixelData,
|
||||
pixelRep, numPlanes,
|
||||
dataType, pixelFormat, pixelSize);
|
||||
|
||||
image = new osg::Image;
|
||||
image->setUserData(previous_image->getUserData());
|
||||
image->setFileName(fileName.c_str());
|
||||
image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices,
|
||||
pixelFormat, dataType);
|
||||
osg::copyImage(previous_image.get(), 0,0,0, previous_image->s(), previous_image->t(), imageNum,
|
||||
image.get(), 0, 0, 0,
|
||||
false);
|
||||
}
|
||||
|
||||
info()<<"copyImage(, fileInfo.distance"<<fileInfo.distance<<", imageNum="<<imageNum<<std::endl;
|
||||
|
||||
osg::copyImage(imageAdapter.get(), 0,0,0, imageAdapter->s(), imageAdapter->t(), imageAdapter->r(),
|
||||
image.get(), 0, 0, imageNum,
|
||||
false);
|
||||
|
||||
imageNum += dcmImage->getFrameCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
warning()<<"Error in reading dicom file "<<fileInfo.filename<<", error = "<<DicomImage::getString(dcmImage->getStatus())<<std::endl;
|
||||
info()<<" dcmImage->getPhotometricInterpretation()="<<DicomImage::getString(dcmImage->getPhotometricInterpretation())<<std::endl;
|
||||
info()<<" dcmImage->width="<<dcmImage->getWidth()<<", height="<<dcmImage->getHeight()<<" FrameCount="<< dcmImage->getFrameCount()<<std::endl;
|
||||
}
|
||||
|
||||
osg::copyImage(imageAdapter.get(), 0,0,0, imageAdapter->s(), imageAdapter->t(), imageAdapter->r(),
|
||||
image.get(), 0, 0, imageNum,
|
||||
false);
|
||||
|
||||
imageNum += dcmImage->getFrameCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
warning()<<"Error in reading dicom file "<<fileInfo.filename<<", error = "<<DicomImage::getString(dcmImage->getStatus())<<std::endl;
|
||||
info()<<" dcmImage->getPhotometricInterpretation()="<<DicomImage::getString(dcmImage->getPhotometricInterpretation())<<std::endl;
|
||||
info()<<" dcmImage->width="<<dcmImage->getWidth()<<", height="<<dcmImage->getHeight()<<" FrameCount="<< dcmImage->getFrameCount()<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
info()<<"Image matrix = "<<*(details->getMatrix())<<std::endl;
|
||||
|
||||
return image.get();
|
||||
}
|
||||
|
||||
if (!errorMap.empty())
|
||||
@@ -950,14 +951,7 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
}
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
info()<<"Spacing = "<<*(details->getMatrix())<<std::endl;
|
||||
|
||||
return image.get();
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -969,46 +963,67 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
|
||||
numX(0),
|
||||
numY(0),
|
||||
numSlices(1),
|
||||
pixelSize_x(0.0),
|
||||
pixelSize_y(0.0),
|
||||
sliceThickness(0.0),
|
||||
distance(0.0) {}
|
||||
distance(0.0),
|
||||
position(0.0,0.0,0.0),
|
||||
dirX(1.0,0.0,0.0),
|
||||
dirY(0.0,1.0,0.0),
|
||||
dirZ(0.0,0.0,1.0) {}
|
||||
|
||||
FileInfo(const FileInfo& rhs):
|
||||
filename(rhs.filename),
|
||||
matrix(rhs.matrix),
|
||||
rescaleIntercept(rhs.rescaleIntercept),
|
||||
rescaleSlope(rhs.rescaleSlope),
|
||||
numX(rhs.numX),
|
||||
numY(rhs.numY),
|
||||
numSlices(rhs.numSlices),
|
||||
pixelSize_x(rhs.pixelSize_x),
|
||||
pixelSize_y(rhs.pixelSize_y),
|
||||
sliceThickness(rhs.sliceThickness),
|
||||
distance(distance) {}
|
||||
distance(distance),
|
||||
position(rhs.position),
|
||||
dirX(rhs.dirX),
|
||||
dirY(rhs.dirY),
|
||||
dirZ(rhs.dirZ) {}
|
||||
|
||||
FileInfo& operator = (const FileInfo& rhs)
|
||||
{
|
||||
if (&rhs == this) return *this;
|
||||
|
||||
filename = rhs.filename;
|
||||
matrix = rhs.matrix;
|
||||
rescaleIntercept = rhs.rescaleIntercept;
|
||||
rescaleSlope = rhs.rescaleSlope;
|
||||
numX = rhs.numX;
|
||||
numY = rhs.numY;
|
||||
pixelSize_x = rhs.pixelSize_x;
|
||||
pixelSize_y = rhs.pixelSize_y;
|
||||
sliceThickness = rhs.sliceThickness;
|
||||
numSlices = rhs.numSlices;
|
||||
distance = rhs.distance;
|
||||
position = rhs.position;
|
||||
dirX = rhs.dirX;
|
||||
dirY = rhs.dirY;
|
||||
dirZ = rhs.dirZ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string filename;
|
||||
osg::Matrixd matrix;
|
||||
double rescaleIntercept;
|
||||
double rescaleSlope;
|
||||
unsigned int numX;
|
||||
unsigned int numY;
|
||||
unsigned int numSlices;
|
||||
double pixelSize_x;
|
||||
double pixelSize_y;
|
||||
double sliceThickness;
|
||||
double distance;
|
||||
osg::Vec3d position;
|
||||
osg::Vec3d dirX;
|
||||
osg::Vec3d dirY;
|
||||
osg::Vec3d dirZ;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -11,6 +11,20 @@
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
||||
// Changes for FFMpeg version greater than 0.6
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
|
||||
#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
|
||||
#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
|
||||
#endif
|
||||
|
||||
#ifdef AVERROR
|
||||
#define AVERROR_IO AVERROR(EIO)
|
||||
#define AVERROR_NUMEXPECTED AVERROR(EDOM)
|
||||
#define AVERROR_NOMEM AVERROR(ENOMEM)
|
||||
#define AVERROR_NOFMT AVERROR(EILSEQ)
|
||||
#define AVERROR_NOTSUPP AVERROR(ENOSYS)
|
||||
#define AVERROR_NOENT AVERROR(ENOENT)
|
||||
#endif
|
||||
|
||||
namespace osgFFmpeg {
|
||||
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 53
|
||||
extern "C"
|
||||
{
|
||||
#include <parseutils.h>
|
||||
}
|
||||
#define av_parse_video_frame_size av_parse_video_size
|
||||
#define av_parse_video_frame_rate av_parse_video_rate
|
||||
#endif
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 53 || \
|
||||
(LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR>=49)
|
||||
|
||||
|
||||
@@ -1285,7 +1285,3 @@ public:
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
REGISTER_OSGPLUGIN(imageio, ReaderWriterImageIO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
#include <osg/GL>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Image>
|
||||
@@ -23,33 +22,33 @@
|
||||
// to a Quartz buffer (supplied by Apple framework).
|
||||
size_t MyProviderGetBytesCallback(void* istream_userdata, void* quartz_buffer, size_t the_count)
|
||||
{
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
the_istream->read((char*)quartz_buffer, the_count);
|
||||
return the_istream->gcount(); // return the actual number of bytes read
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
the_istream->read((char*)quartz_buffer, the_count);
|
||||
return the_istream->gcount(); // return the actual number of bytes read
|
||||
}
|
||||
|
||||
// This callback is triggered when the data provider is released
|
||||
// so you can clean up any resources.
|
||||
void MyProviderReleaseInfoCallback(void* istream_userdata)
|
||||
{
|
||||
// What should I put here? Do I need to close the istream?
|
||||
// The png and tga don't seem to.
|
||||
// std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
// What should I put here? Do I need to close the istream?
|
||||
// The png and tga don't seem to.
|
||||
// std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
}
|
||||
|
||||
void MyProviderRewindCallback(void* istream_userdata)
|
||||
{
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
the_istream->seekg(0, std::ios::beg);
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
the_istream->seekg(0, std::ios::beg);
|
||||
}
|
||||
|
||||
off_t MyProviderSkipForwardBytesCallback(void* istream_userdata, off_t the_count)
|
||||
{
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
off_t start_position = the_istream->tellg();
|
||||
the_istream->seekg(the_count, std::ios::cur);
|
||||
off_t end_position = the_istream->tellg();
|
||||
return (end_position - start_position);
|
||||
std::istream* the_istream = (std::istream*)istream_userdata;
|
||||
off_t start_position = the_istream->tellg();
|
||||
the_istream->seekg(the_count, std::ios::cur);
|
||||
off_t end_position = the_istream->tellg();
|
||||
return (end_position - start_position);
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
@@ -62,17 +61,17 @@ off_t MyProviderSkipForwardBytesCallback(void* istream_userdata, off_t the_count
|
||||
**************************************************************/
|
||||
size_t MyConsumerPutBytesCallback(void* ostream_userdata, const void* quartz_buffer, size_t the_count)
|
||||
{
|
||||
std::ostream* the_ostream = (std::ostream*)ostream_userdata;
|
||||
the_ostream->write((char*)quartz_buffer, the_count);
|
||||
// Don't know how to get number of bytes actually written, so
|
||||
// just returning the_count.
|
||||
return the_count;
|
||||
std::ostream* the_ostream = (std::ostream*)ostream_userdata;
|
||||
the_ostream->write((char*)quartz_buffer, the_count);
|
||||
// Don't know how to get number of bytes actually written, so
|
||||
// just returning the_count.
|
||||
return the_count;
|
||||
}
|
||||
|
||||
void MyConsumerReleaseInfoCallback(void* ostream_userdata)
|
||||
{
|
||||
std::ostream* the_ostream = (std::ostream*)ostream_userdata;
|
||||
the_ostream->flush();
|
||||
std::ostream* the_ostream = (std::ostream*)ostream_userdata;
|
||||
the_ostream->flush();
|
||||
}
|
||||
/**************************************************************
|
||||
***** End Callback functions for ostream block writing ********
|
||||
@@ -86,49 +85,49 @@ void MyConsumerReleaseInfoCallback(void* ostream_userdata)
|
||||
/* Create a CGImageSourceRef from raw data */
|
||||
CGImageRef CreateCGImageFromDataStream(std::istream& fin)
|
||||
{
|
||||
CGImageRef image_ref = NULL;
|
||||
CGImageSourceRef source_ref;
|
||||
/* The easy way would be to use CGImageSourceCreateWithData,
|
||||
* but this presumes you have a known fixed-length buffer of data.
|
||||
* The istream makes this harder to know, so we use the ProviderCallbacks APIs
|
||||
CFDataRef the_cf_data = CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
(const UInt8*)the_data,
|
||||
CFIndex length,
|
||||
kCFAllocatorNull // do not free data buffer, must do it yourself
|
||||
);
|
||||
source_ref = CGImageSourceCreateWithData(the_cf_data, NULL);
|
||||
*/
|
||||
|
||||
CGDataProviderSequentialCallbacks provider_callbacks =
|
||||
{
|
||||
0,
|
||||
MyProviderGetBytesCallback,
|
||||
MyProviderSkipForwardBytesCallback,
|
||||
MyProviderRewindCallback,
|
||||
MyProviderReleaseInfoCallback
|
||||
};
|
||||
|
||||
CGDataProviderRef data_provider = CGDataProviderCreateSequential(&fin, &provider_callbacks);
|
||||
|
||||
// If we had a way of hinting at what the data type is, we could
|
||||
// pass this hint in the second parameter.
|
||||
source_ref = CGImageSourceCreateWithDataProvider(data_provider, NULL);
|
||||
|
||||
CGDataProviderRelease(data_provider);
|
||||
|
||||
|
||||
if(!source_ref)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_ref = CGImageSourceCreateImageAtIndex(source_ref, 0, NULL);
|
||||
|
||||
/* Don't need the SourceRef any more (error or not) */
|
||||
CFRelease(source_ref);
|
||||
|
||||
return image_ref;
|
||||
CGImageRef image_ref = NULL;
|
||||
CGImageSourceRef source_ref;
|
||||
/* The easy way would be to use CGImageSourceCreateWithData,
|
||||
* but this presumes you have a known fixed-length buffer of data.
|
||||
* The istream makes this harder to know, so we use the ProviderCallbacks APIs
|
||||
CFDataRef the_cf_data = CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
(const UInt8*)the_data,
|
||||
CFIndex length,
|
||||
kCFAllocatorNull // do not free data buffer, must do it yourself
|
||||
);
|
||||
source_ref = CGImageSourceCreateWithData(the_cf_data, NULL);
|
||||
*/
|
||||
|
||||
CGDataProviderSequentialCallbacks provider_callbacks =
|
||||
{
|
||||
0,
|
||||
MyProviderGetBytesCallback,
|
||||
MyProviderSkipForwardBytesCallback,
|
||||
MyProviderRewindCallback,
|
||||
MyProviderReleaseInfoCallback
|
||||
};
|
||||
|
||||
CGDataProviderRef data_provider = CGDataProviderCreateSequential(&fin, &provider_callbacks);
|
||||
|
||||
// If we had a way of hinting at what the data type is, we could
|
||||
// pass this hint in the second parameter.
|
||||
source_ref = CGImageSourceCreateWithDataProvider(data_provider, NULL);
|
||||
|
||||
CGDataProviderRelease(data_provider);
|
||||
|
||||
|
||||
if(!source_ref)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_ref = CGImageSourceCreateImageAtIndex(source_ref, 0, NULL);
|
||||
|
||||
/* Don't need the SourceRef any more (error or not) */
|
||||
CFRelease(source_ref);
|
||||
|
||||
return image_ref;
|
||||
}
|
||||
|
||||
static NSString* toNSString(const std::string& text, NSStringEncoding nsse)
|
||||
@@ -138,7 +137,7 @@ static NSString* toNSString(const std::string& text, NSStringEncoding nsse)
|
||||
if (!text.empty())
|
||||
{
|
||||
nstr = [NSString stringWithCString:text.c_str() encoding:nsse];
|
||||
//nstr = [NSString stringWithUTF8String:text.c_str()];// encoding:nsse]
|
||||
//nstr = [NSString stringWithUTF8String:text.c_str()];// encoding:nsse]
|
||||
}
|
||||
|
||||
if (nstr == nil)
|
||||
@@ -161,74 +160,92 @@ static NSString* toNSString(const std::string& text)
|
||||
//
|
||||
osg::Image* ReadCoreGraphicsImageFromFile(std::string file)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
//chop the extension off
|
||||
std::string strExt = osgDB::getFileExtension(file);
|
||||
std::string strPath = osgDB::getFilePath(file);
|
||||
std::string strName = osgDB::getStrippedName(file);
|
||||
std::string strFile = strPath+"/"+strName;
|
||||
|
||||
NSString* path = [NSString stringWithCString:strName.c_str() length:strlen(strName.c_str())];
|
||||
NSString* ext = [NSString stringWithCString:strExt.c_str() length:strlen(strExt.c_str())];
|
||||
|
||||
//CGImageRef textureImage = [UIImage imageNamed:path].CGImage;
|
||||
CGImageRef textureImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:ext]].CGImage;
|
||||
|
||||
if (textureImage == nil) {
|
||||
|
||||
NSLog(@"imageio: failed to load CGImageRef image '%@'", path );
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
NSInteger texWidth = CGImageGetWidth(textureImage);
|
||||
NSInteger texHeight = CGImageGetHeight(textureImage);
|
||||
|
||||
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
|
||||
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
//chop the extension off
|
||||
//std::string strExt = osgDB::getFileExtension(file);
|
||||
//std::string strPath = osgDB::getFilePath(file);
|
||||
//std::string strName = osgDB::getStrippedName(file);
|
||||
//std::string strFile = strPath + "/" + strName;
|
||||
|
||||
//NSString* path = [NSString stringWithCString:strName.c_str() encoding:NSUTF8StringEncoding];
|
||||
//NSString* ext = [NSString stringWithCString:strExt.c_str() encoding:NSUTF8StringEncoding];
|
||||
|
||||
//CGImageRef textureImage = [UIImage imageNamed:path].CGImage;
|
||||
//CGImageRef textureImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:path ofType:ext]].CGImage;
|
||||
NSString* path = [NSString stringWithCString:file.c_str() encoding:NSUTF8StringEncoding];
|
||||
//NSLog(@"imageio: About to open %@.\n", path);
|
||||
UIImage *img = [UIImage imageWithContentsOfFile:path];
|
||||
if (!img) {
|
||||
NSLog(@"imageio: failed to load UIImage image '%@'.\n", path);
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
CGImageRef textureImage = img.CGImage;
|
||||
if (!textureImage) {
|
||||
NSLog(@"imageio: failed to create CGImageRef.\n");
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t texWidth = CGImageGetWidth(textureImage);
|
||||
size_t texHeight = CGImageGetHeight(textureImage);
|
||||
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
|
||||
if (!textureData) {
|
||||
NSLog(@"imageio: out of memory.\n");
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGColorSpaceRef csref = CGColorSpaceCreateDeviceRGB();
|
||||
if (!csref) {
|
||||
NSLog(@"imageio: failed to create CGColorSpaceRef.\n");
|
||||
free(textureData);
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGContextRef textureContext = CGBitmapContextCreate(textureData,
|
||||
texWidth, texHeight,
|
||||
8, texWidth * 4,
|
||||
CGColorSpaceCreateDeviceRGB(),
|
||||
kCGImageAlphaPremultipliedLast);
|
||||
|
||||
//copy into texturedata
|
||||
CGContextDrawImage(textureContext,
|
||||
CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
|
||||
textureImage);
|
||||
|
||||
CGContextRelease(textureContext);
|
||||
|
||||
|
||||
//create the osg image
|
||||
unsigned int dataType = GL_UNSIGNED_BYTE;
|
||||
int s = texWidth;
|
||||
int t = texHeight;
|
||||
|
||||
|
||||
osg::Image* image = new osg::Image();
|
||||
image->setImage(s, t, 1,
|
||||
GL_RGBA,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
textureData,
|
||||
osg::Image::USE_MALLOC_FREE);
|
||||
|
||||
//flip vertical
|
||||
image->flipVertical();
|
||||
texWidth, texHeight,
|
||||
8, texWidth * 4,
|
||||
csref,
|
||||
kCGImageAlphaPremultipliedLast);
|
||||
CGColorSpaceRelease(csref);
|
||||
if (!textureContext) {
|
||||
NSLog(@"imageio: failed to create CGContextRef.\n");
|
||||
free(textureData);
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//copy into texturedata
|
||||
CGContextDrawImage(textureContext,
|
||||
CGRectMake(0.0f, 0.0f, (float)texWidth, (float)texHeight),
|
||||
textureImage);
|
||||
CGContextRelease(textureContext);
|
||||
|
||||
//create the osg image
|
||||
int s = texWidth;
|
||||
int t = texHeight;
|
||||
osg::Image* image = new osg::Image();
|
||||
image->setImage(s, t, 1,
|
||||
GL_RGBA,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
textureData,
|
||||
osg::Image::USE_MALLOC_FREE);
|
||||
|
||||
//flip vertical
|
||||
image->flipVertical();
|
||||
|
||||
//
|
||||
// Reverse the premultiplied alpha for avoiding unexpected darker edges
|
||||
// by Tatsuhiro Nishioka (based on SDL's workaround on the similar issue)
|
||||
// http://bugzilla.libsdl.org/show_bug.cgi?id=868
|
||||
//
|
||||
|
||||
|
||||
int i, j;
|
||||
GLubyte *pixels = (GLubyte *)image->data();
|
||||
for (i = image->t() * image->s(); i--; ) {
|
||||
|
||||
|
||||
GLubyte alpha = pixels[3];
|
||||
if (alpha && (alpha < 255)) {
|
||||
for (j = 0; j < 3; ++j) {
|
||||
@@ -237,61 +254,72 @@ osg::Image* ReadCoreGraphicsImageFromFile(std::string file)
|
||||
}
|
||||
pixels += 4;
|
||||
}
|
||||
|
||||
|
||||
[pool release];
|
||||
return image;
|
||||
|
||||
|
||||
|
||||
[pool release];
|
||||
return image;
|
||||
}
|
||||
|
||||
osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
if (textureImage == nil) {
|
||||
[pool release];
|
||||
NSLog(@"imageio: failed to load CGImageRef image");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NSInteger texWidth = CGImageGetWidth(textureImage);
|
||||
NSInteger texHeight = CGImageGetHeight(textureImage);
|
||||
|
||||
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
|
||||
|
||||
CGContextRef textureContext = CGBitmapContextCreate(textureData,
|
||||
texWidth, texHeight,
|
||||
8, texWidth * 4,
|
||||
CGColorSpaceCreateDeviceRGB(),
|
||||
kCGImageAlphaPremultipliedLast);
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
if (textureImage == nil) {
|
||||
[pool release];
|
||||
NSLog(@"imageio: failed to load CGImageRef image");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//copy into texturedata
|
||||
CGContextDrawImage(textureContext,
|
||||
CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
|
||||
textureImage);
|
||||
CGContextFlush(textureContext);
|
||||
CGContextRelease(textureContext);
|
||||
|
||||
|
||||
//create the osg image
|
||||
unsigned int dataType = GL_UNSIGNED_BYTE;
|
||||
int s = texWidth;
|
||||
int t = texHeight;
|
||||
|
||||
|
||||
osg::Image* image = new osg::Image();
|
||||
image->setImage(s, t, 1,
|
||||
GL_RGBA,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
textureData,
|
||||
osg::Image::USE_MALLOC_FREE);
|
||||
|
||||
//flip vertical
|
||||
image->flipVertical();
|
||||
size_t texWidth = CGImageGetWidth(textureImage);
|
||||
size_t texHeight = CGImageGetHeight(textureImage);
|
||||
|
||||
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
|
||||
if (!textureData) {
|
||||
NSLog(@"imageio: out of memory.\n");
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGColorSpaceRef csref = CGColorSpaceCreateDeviceRGB();
|
||||
if (!csref) {
|
||||
NSLog(@"imageio: failed to create CGColorSpaceRef.\n");
|
||||
free(textureData);
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGContextRef textureContext = CGBitmapContextCreate(textureData,
|
||||
texWidth, texHeight,
|
||||
8, texWidth * 4,
|
||||
csref,
|
||||
kCGImageAlphaPremultipliedLast);
|
||||
CGColorSpaceRelease(csref);
|
||||
if (!textureContext) {
|
||||
NSLog(@"imageio: failed to create CGContextRef.\n");
|
||||
free(textureData);
|
||||
[pool release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//copy into texturedata
|
||||
CGContextDrawImage(textureContext,
|
||||
CGRectMake(0.0f, 0.0f, (float)texWidth, (float)texHeight),
|
||||
textureImage);
|
||||
CGContextFlush(textureContext);
|
||||
CGContextRelease(textureContext);
|
||||
|
||||
|
||||
//create the osg image
|
||||
int s = texWidth;
|
||||
int t = texHeight;
|
||||
osg::Image* image = new osg::Image();
|
||||
image->setImage(s, t, 1,
|
||||
GL_RGBA,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
textureData,
|
||||
osg::Image::USE_MALLOC_FREE);
|
||||
|
||||
//flip vertical
|
||||
image->flipVertical();
|
||||
|
||||
//
|
||||
// Reverse the premultiplied alpha for avoiding unexpected darker edges
|
||||
@@ -303,7 +331,7 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage)
|
||||
int i, j;
|
||||
GLubyte *pixels = (GLubyte *)image->data();
|
||||
for (i = image->t() * image->s(); i--; ) {
|
||||
|
||||
|
||||
GLubyte alpha = pixels[3];
|
||||
if (alpha && (alpha < 255)) {
|
||||
for (j = 0; j < 3; ++j) {
|
||||
@@ -312,13 +340,9 @@ osg::Image* CreateOSGImageFromCGImage(CGImageRef textureImage)
|
||||
}
|
||||
pixels += 4;
|
||||
}
|
||||
|
||||
|
||||
[pool release];
|
||||
return image;
|
||||
|
||||
|
||||
|
||||
|
||||
[pool release];
|
||||
return image;
|
||||
}
|
||||
|
||||
class ReaderWriterImageIO : public osgDB::ReaderWriter
|
||||
@@ -327,73 +351,73 @@ class ReaderWriterImageIO : public osgDB::ReaderWriter
|
||||
public:
|
||||
ReaderWriterImageIO()
|
||||
{
|
||||
|
||||
supportsExtension("jpg", "jpg image file");
|
||||
supportsExtension("jpeg", "jpeg image file");
|
||||
supportsExtension("jpe", "jpe image file");
|
||||
supportsExtension("jp2", "jp2 image file");
|
||||
supportsExtension("tiff", "tiff image file");
|
||||
supportsExtension("tif", "tif image file");
|
||||
supportsExtension("gif", "gif image file");
|
||||
supportsExtension("png", "png image file");
|
||||
supportsExtension("pict", "pict image file");
|
||||
supportsExtension("pct", "pct image file");
|
||||
supportsExtension("pic", "pic image file");
|
||||
supportsExtension("bmp", "bmp image file");
|
||||
supportsExtension("BMPf", "BMPf image file");
|
||||
supportsExtension("ico", "ico image file");
|
||||
supportsExtension("icns", "icns image file");
|
||||
supportsExtension("tga", "tga image file");
|
||||
supportsExtension("targa", "targa image file");
|
||||
supportsExtension("psd", "psd image file");
|
||||
|
||||
supportsExtension("pdf", "pdf image file");
|
||||
supportsExtension("eps", "eps image file");
|
||||
supportsExtension("epi", "epi image file");
|
||||
supportsExtension("epsf", "epsf image file");
|
||||
supportsExtension("epsi", "epsi image file");
|
||||
supportsExtension("ps", "postscript image file");
|
||||
|
||||
supportsExtension("dng", "dng image file");
|
||||
supportsExtension("cr2", "cr2 image file");
|
||||
supportsExtension("crw", "crw image file");
|
||||
supportsExtension("fpx", "fpx image file");
|
||||
supportsExtension("fpxi", "fpxi image file");
|
||||
supportsExtension("raf", "raf image file");
|
||||
supportsExtension("dcr", "dcr image file");
|
||||
supportsExtension("ptng", "ptng image file");
|
||||
supportsExtension("pnt", "pnt image file");
|
||||
supportsExtension("mac", "mac image file");
|
||||
supportsExtension("mrw", "mrw image file");
|
||||
supportsExtension("nef", "nef image file");
|
||||
supportsExtension("orf", "orf image file");
|
||||
supportsExtension("exr", "exr image file");
|
||||
supportsExtension("qti", "qti image file");
|
||||
supportsExtension("qtif", "qtif image file");
|
||||
supportsExtension("hdr", "hdr image file");
|
||||
supportsExtension("sgi", "sgi image file");
|
||||
supportsExtension("srf", "srf image file");
|
||||
supportsExtension("cur", "cur image file");
|
||||
supportsExtension("xbm", "xbm image file");
|
||||
|
||||
supportsExtension("raw", "raw image file");
|
||||
|
||||
supportsExtension("jpg", "jpg image file");
|
||||
supportsExtension("jpeg", "jpeg image file");
|
||||
supportsExtension("jpe", "jpe image file");
|
||||
supportsExtension("jp2", "jp2 image file");
|
||||
supportsExtension("tiff", "tiff image file");
|
||||
supportsExtension("tif", "tif image file");
|
||||
supportsExtension("gif", "gif image file");
|
||||
supportsExtension("png", "png image file");
|
||||
supportsExtension("pict", "pict image file");
|
||||
supportsExtension("pct", "pct image file");
|
||||
supportsExtension("pic", "pic image file");
|
||||
supportsExtension("bmp", "bmp image file");
|
||||
supportsExtension("BMPf", "BMPf image file");
|
||||
supportsExtension("ico", "ico image file");
|
||||
supportsExtension("icns", "icns image file");
|
||||
supportsExtension("tga", "tga image file");
|
||||
supportsExtension("targa", "targa image file");
|
||||
supportsExtension("psd", "psd image file");
|
||||
|
||||
supportsExtension("pdf", "pdf image file");
|
||||
supportsExtension("eps", "eps image file");
|
||||
supportsExtension("epi", "epi image file");
|
||||
supportsExtension("epsf", "epsf image file");
|
||||
supportsExtension("epsi", "epsi image file");
|
||||
supportsExtension("ps", "postscript image file");
|
||||
|
||||
supportsExtension("dng", "dng image file");
|
||||
supportsExtension("cr2", "cr2 image file");
|
||||
supportsExtension("crw", "crw image file");
|
||||
supportsExtension("fpx", "fpx image file");
|
||||
supportsExtension("fpxi", "fpxi image file");
|
||||
supportsExtension("raf", "raf image file");
|
||||
supportsExtension("dcr", "dcr image file");
|
||||
supportsExtension("ptng", "ptng image file");
|
||||
supportsExtension("pnt", "pnt image file");
|
||||
supportsExtension("mac", "mac image file");
|
||||
supportsExtension("mrw", "mrw image file");
|
||||
supportsExtension("nef", "nef image file");
|
||||
supportsExtension("orf", "orf image file");
|
||||
supportsExtension("exr", "exr image file");
|
||||
supportsExtension("qti", "qti image file");
|
||||
supportsExtension("qtif", "qtif image file");
|
||||
supportsExtension("hdr", "hdr image file");
|
||||
supportsExtension("sgi", "sgi image file");
|
||||
supportsExtension("srf", "srf image file");
|
||||
supportsExtension("cur", "cur image file");
|
||||
supportsExtension("xbm", "xbm image file");
|
||||
|
||||
supportsExtension("raw", "raw image file");
|
||||
}
|
||||
|
||||
virtual const char* className() const { return "Mac OS X ImageIO based Image Reader/Writer"; }
|
||||
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension) const
|
||||
{
|
||||
// ImageIO speaks in UTIs.
|
||||
// http://developer.apple.com/graphicsimaging/workingwithimageio.html
|
||||
// The Cocoa drawing guide lists these and says to use the
|
||||
// imageFileTypes class method of NSImage to get a complete
|
||||
// list of extensions. But remember ImageIO may support more formats
|
||||
// than Cocoa.
|
||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Images/chapter_7_section_3.html
|
||||
// Apple's UTI guide:
|
||||
// http://developer.apple.com/documentation/Carbon/Conceptual/understanding_utis/utilist/chapter_4_section_1.html
|
||||
return
|
||||
|
||||
virtual const char* className() const { return "Mac OS X ImageIO based Image Reader/Writer"; }
|
||||
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension) const
|
||||
{
|
||||
// ImageIO speaks in UTIs.
|
||||
// http://developer.apple.com/graphicsimaging/workingwithimageio.html
|
||||
// The Cocoa drawing guide lists these and says to use the
|
||||
// imageFileTypes class method of NSImage to get a complete
|
||||
// list of extensions. But remember ImageIO may support more formats
|
||||
// than Cocoa.
|
||||
// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Images/chapter_7_section_3.html
|
||||
// Apple's UTI guide:
|
||||
// http://developer.apple.com/documentation/Carbon/Conceptual/understanding_utis/utilist/chapter_4_section_1.html
|
||||
return
|
||||
osgDB::equalCaseInsensitive(extension,"jpg") ||
|
||||
osgDB::equalCaseInsensitive(extension,"jpeg") ||
|
||||
osgDB::equalCaseInsensitive(extension,"jpe") ||
|
||||
@@ -443,110 +467,106 @@ public:
|
||||
osgDB::equalCaseInsensitive(extension,"xbm") ||
|
||||
|
||||
osgDB::equalCaseInsensitive(extension,"raw");
|
||||
}
|
||||
|
||||
|
||||
|
||||
ReadResult readImageStream(std::istream& fin) const
|
||||
{
|
||||
// Call ImageIO to load the image.
|
||||
CGImageRef cg_image_ref = CreateCGImageFromDataStream(fin);
|
||||
if (NULL == cg_image_ref) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
// Create an osg::Image from the CGImageRef.
|
||||
osg::Image* osg_image = CreateOSGImageFromCGImage(cg_image_ref);
|
||||
|
||||
CFRelease(cg_image_ref);
|
||||
return osg_image;
|
||||
}
|
||||
|
||||
virtual ReadResult readImage(std::istream& fin, const osgDB::ReaderWriter::Options* the_options = NULL) const
|
||||
{
|
||||
ReadResult read_result = readImageStream(fin);
|
||||
return read_result;
|
||||
}
|
||||
|
||||
ReadResult readImageFile(const std::string& file_name) const
|
||||
{
|
||||
//osg::notify(osg::INFO) << "imageio readImageFile: " << file_name << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ReadResult readImageStream(std::istream& fin) const
|
||||
{
|
||||
// Call ImageIO to load the image.
|
||||
CGImageRef cg_image_ref = CreateCGImageFromDataStream(fin);
|
||||
if (NULL == cg_image_ref) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
// Create an osg::Image from the CGImageRef.
|
||||
osg::Image* osg_image = ReadCoreGraphicsImageFromFile(file_name);
|
||||
// Create an osg::Image from the CGImageRef.
|
||||
osg::Image* osg_image = CreateOSGImageFromCGImage(cg_image_ref);
|
||||
|
||||
CFRelease(cg_image_ref);
|
||||
return osg_image;
|
||||
}
|
||||
|
||||
virtual ReadResult readImage(std::istream& fin, const osgDB::ReaderWriter::Options* the_options = NULL) const
|
||||
{
|
||||
ReadResult read_result = readImageStream(fin);
|
||||
return read_result;
|
||||
}
|
||||
|
||||
ReadResult readImageFile(const std::string& file_name) const
|
||||
{
|
||||
//osg::notify(osg::INFO) << "imageio readImageFile: " << file_name << std::endl;
|
||||
|
||||
// Create an osg::Image from the CGImageRef.
|
||||
osg::Image* osg_image = ReadCoreGraphicsImageFromFile(file_name);
|
||||
|
||||
return osg_image;
|
||||
}
|
||||
return osg_image;
|
||||
}
|
||||
|
||||
virtual ReadResult readImage(const std::string& file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file_name);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
virtual ReadResult readImage(const std::string& file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file_name);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
std::string full_file_name = osgDB::findDataFile( file_name, the_options );
|
||||
if (full_file_name.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
std::string full_file_name = osgDB::findDataFile( file_name, the_options );
|
||||
if (full_file_name.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
#if 1
|
||||
ReadResult read_result = readImageFile(full_file_name);
|
||||
ReadResult read_result = readImageFile(full_file_name);
|
||||
#else
|
||||
// Only here to help test istream backend. The file version is better because
|
||||
// the filenname.extension could potentially be used by ImageIO to hint what the format type is.
|
||||
std::ifstream istream(full_file_name.c_str(), std::ios::in | std::ios::binary);
|
||||
if(!istream) return ReadResult::FILE_NOT_HANDLED;
|
||||
ReadResult read_result = readImage(istream);
|
||||
// Only here to help test istream backend. The file version is better because
|
||||
// the filenname.extension could potentially be used by ImageIO to hint what the format type is.
|
||||
std::ifstream istream(full_file_name.c_str(), std::ios::in | std::ios::binary);
|
||||
if(!istream) return ReadResult::FILE_NOT_HANDLED;
|
||||
ReadResult read_result = readImage(istream);
|
||||
#endif
|
||||
|
||||
if(read_result.validImage())
|
||||
{
|
||||
read_result.getImage()->setFileName(full_file_name);
|
||||
}
|
||||
return read_result;
|
||||
}
|
||||
if(read_result.validImage())
|
||||
{
|
||||
read_result.getImage()->setFileName(full_file_name);
|
||||
}
|
||||
return read_result;
|
||||
}
|
||||
|
||||
|
||||
WriteResult writeImageStream(const osg::Image& osg_image, std::ostream& fout, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE;
|
||||
WriteResult writeImageStream(const osg::Image& osg_image, std::ostream& fout, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE;
|
||||
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
|
||||
virtual WriteResult writeImage(const osg::Image& osg_image, std::ostream& fout, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult write_result = writeImageStream(osg_image, fout, the_options);
|
||||
return write_result;
|
||||
}
|
||||
virtual WriteResult writeImage(const osg::Image& osg_image, std::ostream& fout, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult write_result = writeImageStream(osg_image, fout, the_options);
|
||||
return write_result;
|
||||
}
|
||||
|
||||
WriteResult writeImageFile(const osg::Image& osg_image, const std::string& full_file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE;
|
||||
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
WriteResult writeImageFile(const osg::Image& osg_image, const std::string& full_file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE;
|
||||
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
|
||||
virtual WriteResult writeImage(const osg::Image& osg_image, const std::string& file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(file_name);
|
||||
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
|
||||
virtual WriteResult writeImage(const osg::Image& osg_image, const std::string& file_name, const osgDB::ReaderWriter::Options* the_options) const
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(file_name);
|
||||
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
|
||||
|
||||
#if 1
|
||||
// FIXME: Something may need to provide a proper writable location for the files.
|
||||
std::string full_file_name;
|
||||
full_file_name = file_name;
|
||||
return writeImageFile(osg_image, full_file_name, the_options);
|
||||
// FIXME: Something may need to provide a proper writable location for the files.
|
||||
std::string full_file_name;
|
||||
full_file_name = file_name;
|
||||
return writeImageFile(osg_image, full_file_name, the_options);
|
||||
#else
|
||||
// Only here to help test ostream backend. The file version is better because
|
||||
// the filenname.extension could potentially be used by ImageIO to hint what the format type is.
|
||||
std::ofstream fout(file_name.c_str(), std::ios::out | std::ios::binary);
|
||||
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
|
||||
return writeImage(osg_image, fout, the_options);
|
||||
#endif
|
||||
}
|
||||
// Only here to help test ostream backend. The file version is better because
|
||||
// the filenname.extension could potentially be used by ImageIO to hint what the format type is.
|
||||
std::ofstream fout(file_name.c_str(), std::ios::out | std::ios::binary);
|
||||
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
|
||||
return writeImage(osg_image, fout, the_options);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// now register with Registry to instantiate the above
|
||||
// reader/writer.
|
||||
REGISTER_OSGPLUGIN(imageio, ReaderWriterImageIO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
{
|
||||
supportsExtension("ogr","OGR file reader");
|
||||
supportsOption("useRandomColorByFeature", "Assign a random color to each feature.");
|
||||
supportsOption("addGroupPerFeature", "Places each feature in a seperate group.");
|
||||
supportsOption("addGroupPerFeature", "Places each feature in a separate group.");
|
||||
oldHandler = CPLSetErrorHandler(CPLOSGErrorHandler);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
virtual void readBool( bool& b )
|
||||
{
|
||||
std::string boolString;
|
||||
*_in >> boolString;
|
||||
readString( boolString );
|
||||
if ( boolString=="TRUE" ) b = true;
|
||||
else b = false;
|
||||
}
|
||||
@@ -147,50 +147,58 @@ public:
|
||||
virtual void readChar( char& c )
|
||||
{
|
||||
short s = 0;
|
||||
*_in >> s;
|
||||
readShort( s );
|
||||
c = (char)s;
|
||||
}
|
||||
|
||||
virtual void readSChar( signed char& c )
|
||||
{
|
||||
short s = 0;
|
||||
*_in >> s;
|
||||
readShort( s );
|
||||
c = (signed char)s;
|
||||
}
|
||||
|
||||
virtual void readUChar( unsigned char& c )
|
||||
{
|
||||
short s = 0;
|
||||
*_in >> s;
|
||||
readShort( s );
|
||||
c = (unsigned char)s;
|
||||
}
|
||||
|
||||
virtual void readShort( short& s )
|
||||
{ std::string str; *_in >> str; s = static_cast<short>(strtol(str.c_str(), NULL, 0)); }
|
||||
{ std::string str; readString(str); s = static_cast<short>(strtol(str.c_str(), NULL, 0)); }
|
||||
|
||||
virtual void readUShort( unsigned short& s )
|
||||
{ std::string str; *_in >> str; s = static_cast<unsigned short>(strtoul(str.c_str(), NULL, 0)); }
|
||||
{ std::string str; readString(str); s = static_cast<unsigned short>(strtoul(str.c_str(), NULL, 0)); }
|
||||
|
||||
virtual void readInt( int& i )
|
||||
{ std::string str; *_in >> str; i = static_cast<int>(strtol(str.c_str(), NULL, 0)); }
|
||||
{ std::string str; readString(str); i = static_cast<int>(strtol(str.c_str(), NULL, 0)); }
|
||||
|
||||
virtual void readUInt( unsigned int& i )
|
||||
{ std::string str; *_in >> str; i = static_cast<unsigned int>(strtoul(str.c_str(), NULL, 0)); }
|
||||
{ std::string str; readString(str); i = static_cast<unsigned int>(strtoul(str.c_str(), NULL, 0)); }
|
||||
|
||||
virtual void readLong( long& l )
|
||||
{ std::string str; *_in >> str; l = strtol(str.c_str(), NULL, 0); }
|
||||
{ std::string str; readString(str); l = strtol(str.c_str(), NULL, 0); }
|
||||
|
||||
virtual void readULong( unsigned long& l )
|
||||
{ std::string str; *_in >> str; l = strtoul(str.c_str(), NULL, 0); }
|
||||
{ std::string str; readString(str); l = strtoul(str.c_str(), NULL, 0); }
|
||||
|
||||
virtual void readFloat( float& f )
|
||||
{ std::string str; *_in >> str; f = osg::asciiToFloat(str.c_str()); }
|
||||
{ std::string str; readString(str); f = osg::asciiToFloat(str.c_str()); }
|
||||
|
||||
virtual void readDouble( double& d )
|
||||
{ std::string str; *_in >> str; d = osg::asciiToDouble(str.c_str()); }
|
||||
{ std::string str; readString(str); d = osg::asciiToDouble(str.c_str()); }
|
||||
|
||||
virtual void readString( std::string& s )
|
||||
{ *_in >> s; }
|
||||
{
|
||||
if ( _preReadString.empty() )
|
||||
*_in >> s;
|
||||
else
|
||||
{
|
||||
s = _preReadString;
|
||||
_preReadString.clear();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void readStream( std::istream& (*fn)(std::istream&) )
|
||||
{ *_in >> fn; }
|
||||
@@ -202,7 +210,7 @@ public:
|
||||
{
|
||||
GLenum e = 0;
|
||||
std::string enumString;
|
||||
*_in >> enumString;
|
||||
readString( enumString );
|
||||
e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString);
|
||||
value.set( e );
|
||||
}
|
||||
@@ -211,7 +219,7 @@ public:
|
||||
{
|
||||
int value = 0;
|
||||
std::string enumString;
|
||||
*_in >> enumString;
|
||||
readString( enumString );
|
||||
if ( prop._mapProperty )
|
||||
{
|
||||
value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString);
|
||||
@@ -231,7 +239,7 @@ public:
|
||||
virtual void readMark( osgDB::ObjectMark& mark )
|
||||
{
|
||||
std::string markString;
|
||||
*_in >> markString;
|
||||
readString( markString );
|
||||
}
|
||||
|
||||
virtual void readCharArray( char* s, unsigned int size ) {}
|
||||
@@ -239,28 +247,28 @@ public:
|
||||
virtual void readWrappedString( std::string& str )
|
||||
{
|
||||
char ch;
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
|
||||
// skip white space
|
||||
while ( ch==' ' || (ch=='\n') || (ch=='\r'))
|
||||
{
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
}
|
||||
|
||||
if (ch=='"')
|
||||
{
|
||||
// we have an "wrapped string"
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
while ( ch!='"' )
|
||||
{
|
||||
if (ch=='\\')
|
||||
{
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
str += ch;
|
||||
}
|
||||
else str += ch;
|
||||
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -269,23 +277,20 @@ public:
|
||||
while ( (ch!=' ') && (ch!=0) && (ch!='\n') )
|
||||
{
|
||||
str += ch;
|
||||
_in->get( ch ); checkStream();
|
||||
getCharacter( ch );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool matchString( const std::string& str )
|
||||
{
|
||||
std::string s; readString(s);
|
||||
if ( s==str ) return true;
|
||||
else
|
||||
if ( _preReadString.empty() )
|
||||
*_in >> _preReadString;
|
||||
|
||||
if ( _preReadString==str )
|
||||
{
|
||||
// originally "_in->seekg( -(int)(s.length()), std::ios::cur );" was used below but
|
||||
// problems under windows occurred when reading ascii files with unix line endings.
|
||||
// The workaround for this problem was to unget each of the characters in term,
|
||||
// hacky yes, but at least it works!
|
||||
for (unsigned int i = 0; i < s.length(); ++i)
|
||||
_in->unget();
|
||||
_preReadString.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -308,6 +313,23 @@ public:
|
||||
blocks++;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void getCharacter( char& ch )
|
||||
{
|
||||
if ( !_preReadString.empty() )
|
||||
{
|
||||
ch = _preReadString[0];
|
||||
_preReadString.erase( _preReadString.begin() );
|
||||
}
|
||||
else
|
||||
{
|
||||
_in->get( ch );
|
||||
checkStream();
|
||||
}
|
||||
}
|
||||
|
||||
std::string _preReadString;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -326,7 +326,7 @@ public:
|
||||
|
||||
// note from Robert Osfield when integrating, we should probably have so
|
||||
// error handling mechanism here. Possibly move the load from
|
||||
// the constructor to a seperate load method, and have a valid
|
||||
// the constructor to a separate load method, and have a valid
|
||||
// state on the ImageStream... will integrated as is right now
|
||||
// to get things off the ground.
|
||||
QuicktimeImageStream* moov = new QuicktimeImageStream(fileName);
|
||||
|
||||
@@ -88,7 +88,7 @@ private:
|
||||
{
|
||||
if (options && (options->getOptionString() == "separateFiles"))
|
||||
{
|
||||
OSG_INFO << "ReaderWriterSTL::writeNode: Files are seperated written" << std::endl;
|
||||
OSG_INFO << "ReaderWriterSTL::writeNode: Files are separated written" << std::endl;
|
||||
} else {
|
||||
m_f = new osgDB::ofstream(m_fout.c_str());
|
||||
*m_f << "solid " << counter << std::endl;
|
||||
|
||||
@@ -332,7 +332,7 @@ bool trpgHeader::Read(trpgReadBuffer &buf)
|
||||
return isValid();
|
||||
}
|
||||
|
||||
// Read the LOD info (seperate token)
|
||||
// Read the LOD info (separate token)
|
||||
bool trpgHeader::ReadLodInfo(trpgReadBuffer &buf)
|
||||
{
|
||||
float64 range;
|
||||
|
||||
@@ -178,33 +178,26 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string& f
|
||||
if (fileName.empty())
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
// convert possible Windows backslashes to Unix slashes
|
||||
// OpenVRML doesn't like backslashes, even on Windows
|
||||
std::string unixFileName = osgDB::convertFileNameToUnixStyle(fileName);
|
||||
|
||||
#ifdef WIN32
|
||||
if(unixFileName[1] == ':') // absolute path
|
||||
fileName = "file:///" + unixFileName;
|
||||
#else
|
||||
if (unixFileName[0] == '/') // absolute path
|
||||
fileName = "file://" + unixFileName;
|
||||
#endif
|
||||
else
|
||||
// relative path
|
||||
fileName = unixFileName;
|
||||
|
||||
std::fstream null;
|
||||
resource_fetcher fetcher;
|
||||
openvrml::browser *b = new openvrml::browser(fetcher, null, null);
|
||||
|
||||
osgDB::ifstream vrml_stream(fileName.c_str());
|
||||
if (!vrml_stream.is_open())
|
||||
{
|
||||
OSG_INFO << "ReaderWriterVRML2: Could not open \"" << fileName << "\"" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const std::vector< boost::intrusive_ptr< openvrml::node > > & mfn = b->create_vrml_from_stream(vrml_stream);
|
||||
|
||||
if(mfn.empty())
|
||||
{
|
||||
OSG_INFO << "ReaderWriterVRML2: OpenVRML library did not return any vrml nodes." << std::endl;
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<osg::MatrixTransform> osg_root = new osg::MatrixTransform(osg::Matrix( 1, 0, 0, 0,
|
||||
@@ -212,7 +205,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string& f
|
||||
0, -1, 0, 0,
|
||||
0, 0, 0, 1));
|
||||
|
||||
osgDB::getDataFilePathList().push_front(osgDB::getFilePath(unixFileName));
|
||||
osgDB::getDataFilePathList().push_front(osgDB::getFilePath(fileName));
|
||||
for (unsigned i = 0; i < mfn.size(); i++)
|
||||
{
|
||||
openvrml::node *vrml_node = mfn[i].get();
|
||||
@@ -223,8 +216,16 @@ osgDB::ReaderWriter::ReadResult ReaderWriterVRML2::readNode(const std::string& f
|
||||
}
|
||||
}
|
||||
|
||||
catch (openvrml::invalid_vrml) { return ReadResult::FILE_NOT_HANDLED; }
|
||||
catch (std::invalid_argument) { return ReadResult::FILE_NOT_HANDLED; }
|
||||
catch (const openvrml::invalid_vrml& e)
|
||||
{
|
||||
OSG_INFO << "ReaderWriterVRML2: Invalid VRML in line " << e.line << " at column " << e.column << ": \"" << e.what() << "\"" << std::endl;
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
catch (const std::invalid_argument& e)
|
||||
{
|
||||
OSG_INFO << "ReaderWriterVRML2: Invalid argument: \"" << e.what() << "\"" << std::endl;
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::WriteResult ReaderWriterVRML2::writeNode(const osg::Node& root,const std::string& filename, const osgDB::ReaderWriter::Options *options) const
|
||||
|
||||
@@ -288,7 +288,9 @@ void GLWidget::wheelEvent( QWheelEvent* event )
|
||||
{
|
||||
setKeyboardModifiers( event );
|
||||
_gw->getEventQueue()->mouseScroll(
|
||||
event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN );
|
||||
event->orientation() == Qt::Vertical ?
|
||||
(event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :
|
||||
(event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ StandardShadowMap::StandardShadowMap():
|
||||
"void main(void) \n"
|
||||
"{ \n"
|
||||
" vec4 colorAmbientEmissive = gl_FrontLightModelProduct.sceneColor; \n"
|
||||
" // Add ambient from Light of index = 0 \n"
|
||||
" colorAmbientEmissive += gl_FrontLightProduct[0].ambient; \n"
|
||||
// " // Add ambient from Light of index = 0 \n"
|
||||
// " colorAmbientEmissive += gl_FrontLightProduct[0].ambient; \n"
|
||||
" vec4 color = texture2D( baseTexture, gl_TexCoord[0].xy ); \n"
|
||||
" color *= mix( colorAmbientEmissive, gl_Color, DynamicShadow() ); \n"
|
||||
#if DISPLAY_SHADOW_TEXEL_TO_PIXEL_ERROR
|
||||
@@ -325,7 +325,7 @@ StandardShadowMap::StandardShadowMap():
|
||||
" gl_FrontColor = colorAmbientEmissive + \n"
|
||||
" diff * gl_FrontMaterial.diffuse; \n"
|
||||
" \n"
|
||||
" gl_FrontSecondaryColor = vec4(spec*gl_FrontMaterial.specular); \n"
|
||||
" gl_FrontSecondaryColor = vec4(spec*gl_FrontMaterial.specular); \n"
|
||||
" \n"
|
||||
" gl_BackColor = gl_FrontColor; \n"
|
||||
" gl_BackSecondaryColor = gl_FrontSecondaryColor; \n"
|
||||
|
||||
@@ -287,11 +287,17 @@ osg::BoundingBox TextBase::computeBound() const
|
||||
|
||||
if (!bbox.valid())
|
||||
{
|
||||
// provide a fallback in cases where no bounding box has been been setup so far
|
||||
if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)
|
||||
// Provide a fallback in cases where no bounding box has been been setup so far.
|
||||
// Note, assume a scaling of 1.0 for _characterSizeMode!=OBJECT_COORDS as the
|
||||
// for screen space coordinates size modes we don't know what scale will be used until
|
||||
// the text is actually rendered, but we haven't to assume something otherwise the
|
||||
// text label will be culled by view or small feature culling on first frame.
|
||||
if (_autoRotateToScreen)
|
||||
{
|
||||
// default to a zero size.
|
||||
bbox.set(_position, _position);
|
||||
// use bounding sphere encompassing the maximum size of the text centered on the _position
|
||||
double radius = _textBB.radius();
|
||||
osg::Vec3 diagonal(radius, radius, radius);
|
||||
bbox.set(_position-diagonal, _position+diagonal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -341,15 +341,13 @@ bool GraphicsWindowX11::createVisualInfo()
|
||||
#if defined(GLX_SAMPLE_BUFFERS) && defined (GLX_SAMPLES)
|
||||
|
||||
if (_traits->sampleBuffers) { attributes.push_back(GLX_SAMPLE_BUFFERS); attributes.push_back(_traits->sampleBuffers); }
|
||||
if (_traits->sampleBuffers) { attributes.push_back(GLX_SAMPLES); attributes.push_back(_traits->samples); }
|
||||
if (_traits->samples) { attributes.push_back(GLX_SAMPLES); attributes.push_back(_traits->samples); }
|
||||
|
||||
#endif
|
||||
// TODO
|
||||
// GLX_AUX_BUFFERS
|
||||
// GLX_ACCUM_RED_SIZE
|
||||
// GLX_ACCUM_GREEN_SIZE
|
||||
// GLX_SAMPLE_BUFFERS
|
||||
// GLX_SAMPLES
|
||||
|
||||
attributes.push_back(None);
|
||||
|
||||
@@ -730,6 +728,8 @@ void GraphicsWindowX11::init()
|
||||
|
||||
OSG_NOTICE<<"GraphicsWindowX11::init() - window created ="<<_valid<<std::endl;
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
EGLConfig eglConfig = 0;
|
||||
|
||||
#if defined(OSG_GLES2_AVAILABLE)
|
||||
@@ -738,19 +738,27 @@ void GraphicsWindowX11::init()
|
||||
#define OSG_EGL_OPENGL_TARGET_BIT EGL_OPENGL_ES_BIT
|
||||
#endif
|
||||
|
||||
EGLint configAttribs[] = {
|
||||
EGL_SAMPLE_BUFFERS, 0,
|
||||
EGL_SAMPLES, 0,
|
||||
EGL_RED_SIZE, 1,
|
||||
EGL_GREEN_SIZE, 1,
|
||||
EGL_BLUE_SIZE, 1,
|
||||
EGL_DEPTH_SIZE, 1,
|
||||
EGL_RENDERABLE_TYPE, OSG_EGL_OPENGL_TARGET_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
typedef std::vector<EGLint> Attributes;
|
||||
Attributes attributes;
|
||||
|
||||
attributes.push_back(EGL_RED_SIZE); attributes.push_back(_traits->red);
|
||||
attributes.push_back(EGL_GREEN_SIZE); attributes.push_back(_traits->green);
|
||||
attributes.push_back(EGL_BLUE_SIZE); attributes.push_back(_traits->blue);
|
||||
attributes.push_back(EGL_DEPTH_SIZE); attributes.push_back(_traits->depth);
|
||||
|
||||
if (_traits->alpha) { attributes.push_back(EGL_ALPHA_SIZE); attributes.push_back(_traits->alpha); }
|
||||
if (_traits->stencil) { attributes.push_back(EGL_STENCIL_SIZE); attributes.push_back(_traits->stencil); }
|
||||
|
||||
if (_traits->sampleBuffers) { attributes.push_back(EGL_SAMPLE_BUFFERS); attributes.push_back(_traits->sampleBuffers); }
|
||||
if (_traits->samples) { attributes.push_back(EGL_SAMPLES); attributes.push_back(_traits->samples); }
|
||||
|
||||
attributes.push_back(EGL_RENDERABLE_TYPE); attributes.push_back(OSG_EGL_OPENGL_TARGET_BIT);
|
||||
|
||||
attributes.push_back(EGL_NONE);
|
||||
attributes.push_back(EGL_NONE);
|
||||
|
||||
int numConfigs;
|
||||
if (!eglChooseConfig(_eglDisplay, configAttribs, &eglConfig, 1, &numConfigs) || (numConfigs != 1))
|
||||
if (!eglChooseConfig(_eglDisplay, &(attributes.front()), &eglConfig, 1, &numConfigs) || (numConfigs != 1))
|
||||
{
|
||||
OSG_NOTICE<<"GraphicsWindowX11::init() - eglChooseConfig() failed."<<std::endl;
|
||||
XCloseDisplay( _display );
|
||||
@@ -759,7 +767,6 @@ void GraphicsWindowX11::init()
|
||||
return;
|
||||
}
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
_eglSurface = eglCreateWindowSurface(_eglDisplay, eglConfig, (EGLNativeWindowType)_window, NULL);
|
||||
if (_eglSurface == EGL_NO_SURFACE)
|
||||
|
||||
@@ -544,6 +544,44 @@ void Renderer::compile()
|
||||
sceneView->getState()->checkGLErrors("After Renderer::compile");
|
||||
}
|
||||
|
||||
static void collectSceneViewStats(unsigned int frameNumber, osgUtil::SceneView* sceneView, osg::Stats* stats)
|
||||
{
|
||||
osgUtil::Statistics sceneStats;
|
||||
sceneView->getStats(sceneStats);
|
||||
|
||||
stats->setAttribute(frameNumber, "Visible vertex count", static_cast<double>(sceneStats._vertexCount));
|
||||
stats->setAttribute(frameNumber, "Visible number of drawables", static_cast<double>(sceneStats.numDrawables));
|
||||
stats->setAttribute(frameNumber, "Visible number of fast drawables", static_cast<double>(sceneStats.numFastDrawables));
|
||||
stats->setAttribute(frameNumber, "Visible number of lights", static_cast<double>(sceneStats.nlights));
|
||||
stats->setAttribute(frameNumber, "Visible number of render bins", static_cast<double>(sceneStats.nbins));
|
||||
stats->setAttribute(frameNumber, "Visible depth", static_cast<double>(sceneStats.depth));
|
||||
stats->setAttribute(frameNumber, "Number of StateGraphs", static_cast<double>(sceneStats.numStateGraphs));
|
||||
stats->setAttribute(frameNumber, "Visible number of impostors", static_cast<double>(sceneStats.nimpostor));
|
||||
stats->setAttribute(frameNumber, "Number of ordered leaves", static_cast<double>(sceneStats.numOrderedLeaves));
|
||||
|
||||
unsigned int totalNumPrimitiveSets = 0;
|
||||
const osgUtil::Statistics::PrimitiveValueMap& pvm = sceneStats.getPrimitiveValueMap();
|
||||
for(osgUtil::Statistics::PrimitiveValueMap::const_iterator pvm_itr = pvm.begin();
|
||||
pvm_itr != pvm.end();
|
||||
++pvm_itr)
|
||||
{
|
||||
totalNumPrimitiveSets += pvm_itr->second.first;
|
||||
}
|
||||
stats->setAttribute(frameNumber, "Visible number of PrimitiveSets", static_cast<double>(totalNumPrimitiveSets));
|
||||
|
||||
osgUtil::Statistics::PrimitiveCountMap& pcm = sceneStats.getPrimitiveCountMap();
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_POINTS", static_cast<double>(pcm[GL_POINTS]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINES", static_cast<double>(pcm[GL_LINES]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINE_STRIP", static_cast<double>(pcm[GL_LINE_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINE_LOOP", static_cast<double>(pcm[GL_LINE_LOOP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLES", static_cast<double>(pcm[GL_TRIANGLES]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_STRIP", static_cast<double>(pcm[GL_TRIANGLE_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_FAN", static_cast<double>(pcm[GL_TRIANGLE_FAN]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_QUADS", static_cast<double>(pcm[GL_QUADS]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_QUAD_STRIP", static_cast<double>(pcm[GL_QUAD_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_POLYGON", static_cast<double>(pcm[GL_POLYGON]));
|
||||
}
|
||||
|
||||
void Renderer::cull()
|
||||
{
|
||||
DEBUG_MESSAGE<<"cull()"<<std::endl;
|
||||
@@ -596,41 +634,7 @@ void Renderer::cull()
|
||||
|
||||
if (stats && stats->collectStats("scene"))
|
||||
{
|
||||
osgUtil::Statistics sceneStats;
|
||||
sceneView->getStats(sceneStats);
|
||||
|
||||
stats->setAttribute(frameNumber, "Visible vertex count", static_cast<double>(sceneStats._vertexCount));
|
||||
stats->setAttribute(frameNumber, "Visible number of drawables", static_cast<double>(sceneStats.numDrawables));
|
||||
stats->setAttribute(frameNumber, "Visible number of fast drawables", static_cast<double>(sceneStats.numFastDrawables));
|
||||
stats->setAttribute(frameNumber, "Visible number of lights", static_cast<double>(sceneStats.nlights));
|
||||
stats->setAttribute(frameNumber, "Visible number of render bins", static_cast<double>(sceneStats.nbins));
|
||||
stats->setAttribute(frameNumber, "Visible depth", static_cast<double>(sceneStats.depth));
|
||||
stats->setAttribute(frameNumber, "Number of StateGraphs", static_cast<double>(sceneStats.numStateGraphs));
|
||||
stats->setAttribute(frameNumber, "Visible number of impostors", static_cast<double>(sceneStats.nimpostor));
|
||||
stats->setAttribute(frameNumber, "Number of ordered leaves", static_cast<double>(sceneStats.numOrderedLeaves));
|
||||
|
||||
unsigned int totalNumPrimitiveSets = 0;
|
||||
const osgUtil::Statistics::PrimitiveValueMap& pvm = sceneStats.getPrimitiveValueMap();
|
||||
for(osgUtil::Statistics::PrimitiveValueMap::const_iterator pvm_itr = pvm.begin();
|
||||
pvm_itr != pvm.end();
|
||||
++pvm_itr)
|
||||
{
|
||||
totalNumPrimitiveSets += pvm_itr->second.first;
|
||||
}
|
||||
stats->setAttribute(frameNumber, "Visible number of PrimitiveSets", static_cast<double>(totalNumPrimitiveSets));
|
||||
|
||||
osgUtil::Statistics::PrimitiveCountMap& pcm = sceneStats.getPrimitiveCountMap();
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_POINTS", static_cast<double>(pcm[GL_POINTS]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINES", static_cast<double>(pcm[GL_LINES]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINE_STRIP", static_cast<double>(pcm[GL_LINE_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_LINE_LOOP", static_cast<double>(pcm[GL_LINE_LOOP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLES", static_cast<double>(pcm[GL_TRIANGLES]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_STRIP", static_cast<double>(pcm[GL_TRIANGLE_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_TRIANGLE_FAN", static_cast<double>(pcm[GL_TRIANGLE_FAN]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_QUADS", static_cast<double>(pcm[GL_QUADS]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_QUAD_STRIP", static_cast<double>(pcm[GL_QUAD_STRIP]));
|
||||
stats->setAttribute(frameNumber, "Visible number of GL_POLYGON", static_cast<double>(pcm[GL_POLYGON]));
|
||||
|
||||
collectSceneViewStats(frameNumber, sceneView, stats);
|
||||
}
|
||||
|
||||
_drawQueue.add(sceneView);
|
||||
@@ -808,17 +812,7 @@ void Renderer::cull_draw()
|
||||
|
||||
if (stats && stats->collectStats("scene"))
|
||||
{
|
||||
osgUtil::Statistics sceneStats;
|
||||
sceneView->getStats(sceneStats);
|
||||
|
||||
stats->setAttribute(frameNumber, "Visible vertex count", static_cast<double>(sceneStats._vertexCount));
|
||||
stats->setAttribute(frameNumber, "Visible number of drawables", static_cast<double>(sceneStats.numDrawables));
|
||||
stats->setAttribute(frameNumber, "Visible number of lights", static_cast<double>(sceneStats.nlights));
|
||||
stats->setAttribute(frameNumber, "Visible number of render bins", static_cast<double>(sceneStats.nbins));
|
||||
stats->setAttribute(frameNumber, "Visible depth", static_cast<double>(sceneStats.depth));
|
||||
stats->setAttribute(frameNumber, "Number of StateGraphs", static_cast<double>(sceneStats.numStateGraphs));
|
||||
stats->setAttribute(frameNumber, "Visible number of impostors", static_cast<double>(sceneStats.nimpostor));
|
||||
stats->setAttribute(frameNumber, "Number of ordered leaves", static_cast<double>(sceneStats.numOrderedLeaves));
|
||||
collectSceneViewStats(frameNumber, sceneView, stats);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -2007,7 +2007,7 @@ const osg::Camera* View::getCameraContainingPosition(float x, float y, float& lo
|
||||
new_x = static_cast<double>(_camera->getGraphicsContext()->getTraits()->width) * (x - eventState->getXmin())/(eventState->getXmax()-eventState->getXmin());
|
||||
new_y = view_invert_y ?
|
||||
static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (1.0 - (y- eventState->getYmin())/(eventState->getYmax()-eventState->getYmin())) :
|
||||
static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (y - eventState->getYmin())/(eventState->getYmax()-eventState->getXmin());
|
||||
static_cast<double>(_camera->getGraphicsContext()->getTraits()->height) * (y - eventState->getYmin())/(eventState->getYmax()-eventState->getYmin());
|
||||
}
|
||||
|
||||
if (viewport &&
|
||||
|
||||
@@ -377,11 +377,11 @@ bool ThreadingHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIAction
|
||||
{
|
||||
case(osgViewer::Viewer::BeforeSwapBuffers):
|
||||
viewer->setEndBarrierPosition(osgViewer::Viewer::AfterSwapBuffers);
|
||||
OSG_NOTICE<<"Threading model 'AfterSwapBuffers' selected."<<std::endl;
|
||||
OSG_NOTICE<<"Threading end of frame barrier position 'AfterSwapBuffers' selected."<<std::endl;
|
||||
break;
|
||||
case(osgViewer::Viewer::AfterSwapBuffers):
|
||||
viewer->setEndBarrierPosition(osgViewer::Viewer::BeforeSwapBuffers);
|
||||
OSG_NOTICE<<"Threading model 'BeforeSwapBuffers' selected."<<std::endl;
|
||||
OSG_NOTICE<<"Threading end of frame barrier position 'BeforeSwapBuffers' selected."<<std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -407,8 +407,6 @@ RecordCameraPathHandler::RecordCameraPathHandler(const std::string& filename, fl
|
||||
_animStartTime(0),
|
||||
_lastFrameTime(osg::Timer::instance()->tick())
|
||||
{
|
||||
_animPath = new osg::AnimationPath();
|
||||
|
||||
const char* str = getenv("OSG_RECORD_CAMERA_PATH_FPS");
|
||||
if (str)
|
||||
{
|
||||
@@ -446,7 +444,7 @@ bool RecordCameraPathHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GU
|
||||
// If our internal _delta is finally large enough to warrant a ControlPoint
|
||||
// insertion, do so now. Be sure and reset the internal _delta, so we can start
|
||||
// calculating when the next insert should happen.
|
||||
if (_currentlyRecording && _delta >= _interval)
|
||||
if (_animPath.valid() && _currentlyRecording && _delta >= _interval)
|
||||
{
|
||||
const osg::Matrixd& m = view->getCamera()->getInverseViewMatrix();
|
||||
double animationPathTime = osg::Timer::instance()->delta_s(_animStartTime, time);
|
||||
@@ -479,7 +477,7 @@ bool RecordCameraPathHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GU
|
||||
{
|
||||
_currentlyRecording = true;
|
||||
_animStartTime = osg::Timer::instance()->tick();
|
||||
_animPath->clear();
|
||||
_animPath = new osg::AnimationPath();
|
||||
|
||||
if (!_filename.empty())
|
||||
{
|
||||
@@ -530,31 +528,41 @@ bool RecordCameraPathHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GU
|
||||
_currentlyRecording = false;
|
||||
_delta = 0.0f;
|
||||
|
||||
// In the future this will need to be written continuously, rather
|
||||
// than all at once.
|
||||
osgDB::ofstream out(_filename.c_str());
|
||||
OSG_NOTICE<<"Writing camera file: "<<_filename<<std::endl;
|
||||
_animPath->write(out);
|
||||
out.close();
|
||||
if (_animPath.valid() && !_animPath->empty())
|
||||
{
|
||||
// In the future this will need to be written continuously, rather
|
||||
// than all at once.
|
||||
osgDB::ofstream out(_filename.c_str());
|
||||
OSG_NOTICE<<"Writing camera file: "<<_filename<<std::endl;
|
||||
_animPath->write(out);
|
||||
out.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<"No animation path to write out."<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// The user has requested to BEGIN playback.
|
||||
if (!_currentlyPlaying)
|
||||
{
|
||||
_animPathManipulator = new osgGA::AnimationPathManipulator(_animPath.get());
|
||||
_animPathManipulator->home(ea,aa);
|
||||
if (_animPath.valid() && !_animPath->empty())
|
||||
{
|
||||
_animPathManipulator = new osgGA::AnimationPathManipulator(_animPath.get());
|
||||
_animPathManipulator->home(ea,aa);
|
||||
|
||||
|
||||
// If we successfully found our _filename file, set it and keep a copy
|
||||
// around of the original CameraManipulator to restore later.
|
||||
if (_animPathManipulator.valid() && _animPathManipulator->valid())
|
||||
{
|
||||
_oldManipulator = view->getCameraManipulator();
|
||||
view->setCameraManipulator(_animPathManipulator.get());
|
||||
_currentlyPlaying = true;
|
||||
}
|
||||
// If we successfully found our _filename file, set it and keep a copy
|
||||
// around of the original CameraManipulator to restore later.
|
||||
if (_animPathManipulator.valid() && _animPathManipulator->valid())
|
||||
{
|
||||
_oldManipulator = view->getCameraManipulator();
|
||||
view->setCameraManipulator(_animPathManipulator.get());
|
||||
_currentlyPlaying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The user has requested to STOP playback.
|
||||
else
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ REGISTER_OBJECT_WRAPPER( Texture,
|
||||
ADD_BOOL_SERIALIZER( UseHardwareMipMapGeneration, true ); // _useHardwareMipMapGeneration
|
||||
ADD_BOOL_SERIALIZER( UnRefImageDataAfterApply, false ); // _unrefImageDataAfterApply
|
||||
ADD_BOOL_SERIALIZER( ClientStorageHint, false ); // _clientStorageHint
|
||||
ADD_BOOL_SERIALIZER( ResizeNonPowerOfTwoHint, false ); // _resizeNonPowerOfTwoHint
|
||||
ADD_BOOL_SERIALIZER( ResizeNonPowerOfTwoHint, true ); // _resizeNonPowerOfTwoHint
|
||||
ADD_VEC4D_SERIALIZER( BorderColor, osg::Vec4d(0.0,0.0,0.0,0.0) ); // _borderColor
|
||||
ADD_GLINT_SERIALIZER( BorderWidth, 0 ); // _borderWidth
|
||||
|
||||
|
||||
@@ -22,10 +22,20 @@ static bool readLightPointList( osgDB::InputStream& is, osgSim::LightPointNode&
|
||||
is >> osgDB::PROPERTY("Attributes") >> pt._on >> blendingMode >> pt._intensity >> pt._radius;
|
||||
pt._blendingMode = (osgSim::LightPoint::BlendingMode)blendingMode;
|
||||
|
||||
is >> osgDB::PROPERTY("Sector");
|
||||
pt._sector = dynamic_cast<osgSim::Sector*>( is.readObject() );
|
||||
is >> osgDB::PROPERTY("BlinkSequence");
|
||||
pt._blinkSequence = dynamic_cast<osgSim::BlinkSequence*>( is.readObject() );
|
||||
bool hasObject = false; is >> osgDB::PROPERTY("Sector") >> hasObject;
|
||||
if ( hasObject )
|
||||
{
|
||||
is >> osgDB::BEGIN_BRACKET;
|
||||
pt._sector = dynamic_cast<osgSim::Sector*>( is.readObject() );
|
||||
is >> osgDB::END_BRACKET;
|
||||
}
|
||||
hasObject = false; is >> osgDB::PROPERTY("BlinkSequence") >> hasObject;
|
||||
if ( hasObject )
|
||||
{
|
||||
is >> osgDB::BEGIN_BRACKET;
|
||||
pt._blinkSequence = dynamic_cast<osgSim::BlinkSequence*>( is.readObject() );
|
||||
is >> osgDB::END_BRACKET;
|
||||
}
|
||||
is >> osgDB::END_BRACKET;
|
||||
node.addLightPoint( pt );
|
||||
}
|
||||
@@ -45,8 +55,20 @@ static bool writeLightPointList( osgDB::OutputStream& os, const osgSim::LightPoi
|
||||
os << osgDB::PROPERTY("Color") << pt._color << std::endl;
|
||||
os << osgDB::PROPERTY("Attributes") << pt._on << (int)pt._blendingMode
|
||||
<< pt._intensity << pt._radius << std::endl;
|
||||
os << osgDB::PROPERTY("Sector"); os.writeObject( pt._sector.get() );
|
||||
os << osgDB::PROPERTY("BlinkSequence"); os.writeObject( pt._blinkSequence.get() );
|
||||
os << osgDB::PROPERTY("Sector") << (pt._sector!=NULL);
|
||||
if ( pt._sector!=NULL )
|
||||
{
|
||||
os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
os.writeObject( pt._sector.get() );
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
}
|
||||
os << osgDB::PROPERTY("BlinkSequence") << (pt._blinkSequence!=NULL);
|
||||
if ( pt._blinkSequence!=NULL )
|
||||
{
|
||||
os << osgDB::BEGIN_BRACKET << std::endl;
|
||||
os.writeObject( pt._blinkSequence.get() );
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
|
||||
@@ -23,6 +23,7 @@ static bool readValues( osgDB::InputStream& is, osgSim::MultiSwitch& node )
|
||||
values.push_back( value );
|
||||
}
|
||||
node.setValueList( i, values );
|
||||
is >> osgDB::END_BRACKET;
|
||||
}
|
||||
is >> osgDB::END_BRACKET;
|
||||
return true;
|
||||
@@ -40,7 +41,7 @@ static bool writeValues( osgDB::OutputStream& os, const osgSim::MultiSwitch& nod
|
||||
for ( osgSim::MultiSwitch::ValueList::const_iterator itr=values.begin();
|
||||
itr!=values.end(); ++itr )
|
||||
{
|
||||
os << *itr;
|
||||
os << *itr << std::endl;
|
||||
}
|
||||
os << osgDB::END_BRACKET << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user