From eed71f647d3291427538de8c95156ad535947074 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 5 Dec 2012 17:15:53 +0000 Subject: [PATCH] From Stephan Huber, "* imageio: removed ReaderWriterImageIO_IOS.cpp, refactored ReaderWriterImageIO to work on OS X and IOS * avfoundation: added support for IOS (CoreVideo-support is still in development, works only for SDK >= 6.0, set IPHONE_SDKVER in cMake accordingly) * zeroconf: added ZeroConf-device-plugin (Mac/Win only, linux implementation missing) to advertise and discover services via ZeroConf/Bonjour, on windows you'll need the Bonjour SDK from Apple * osgosc: modified the example to demonstrate the usage of the ZeroConf-plugin (start the example with the command-line-argument --zeroconf) * SlideShowConstructor: enable/disable CoreVideo via a environment variable (P3D_ENABLE_CORE_VIDEO) * RestHttp: mouse-motion-events get interpolated * RestHttp: unhandled http-requests get sent as an user-event to the event-queue, all arguments get attached as user-values to the event * modified some CMakeModules to work correctly when compiling for IOS * fixed a compile-error for IOS in GraphicsWindowIOS * some minor bugfixes" --- CMakeLists.txt | 4 +- CMakeModules/FindAVFoundation.cmake | 31 +- CMakeModules/FindQuickTime.cmake | 40 +- CMakeModules/FindZeroConf.cmake | 47 ++ applications/present3D/present3D.cpp | 37 +- examples/osgoscdevice/osgoscdevice.cpp | 87 ++- include/osgViewer/api/IOS/GraphicsWindowIOS | 7 +- src/osg/Geometry.cpp | 12 + src/osgPlugins/CMakeLists.txt | 5 + src/osgPlugins/QTKit/OSXCoreVideoTexture.cpp | 15 +- src/osgPlugins/QTKit/OSXCoreVideoTexture.h | 1 + .../RestHttpDevice/RestHttpDevice.cpp | 25 +- .../RestHttpDevice/RestHttpDevice.hpp | 22 +- src/osgPlugins/RestHttpDevice/connection.cpp | 6 +- .../RestHttpDevice/request_handler.cpp | 4 + src/osgPlugins/RestHttpDevice/server.cpp | 2 +- src/osgPlugins/avfoundation/CMakeLists.txt | 2 +- .../avfoundation/OSXAVFoundationVideo.h | 3 +- .../avfoundation/OSXAVFoundationVideo.mm | 122 ++-- .../OSXAvFoundationCoreVideoTexture.cpp | 13 +- .../OSXAvFoundationCoreVideoTexture.h | 3 +- .../avfoundation/ReaderWriterAVFoundation.cpp | 9 +- src/osgPlugins/imageio/CMakeLists.txt | 8 +- .../imageio/ReaderWriterImageIO.cpp | 14 +- .../imageio/ReaderWriterImageIO_IOS.cpp | 572 ------------------ src/osgPresentation/SlideShowConstructor.cpp | 6 +- 26 files changed, 387 insertions(+), 710 deletions(-) create mode 100755 CMakeModules/FindZeroConf.cmake delete mode 100644 src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 13f6c669e..bc4d4a228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,7 +233,7 @@ IF(APPLE) IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) #you need to manually set the default sdk version here - SET (IPHONE_SDKVER "5.1") + SET (IPHONE_SDKVER "5.1" CACHE STRING "IOS SDK-Version") #the below is taken from ogre, it states the gcc stuff needs to happen before PROJECT() is called. I've no clue if we even need it # Force gcc <= 4.2 on iPhone @@ -517,6 +517,7 @@ ELSE() FIND_PACKAGE(DirectInput) FIND_PACKAGE(NVTT) FIND_PACKAGE(Asio) + FIND_PACKAGE(ZeroConf) ENDIF() IF(CMAKE_MAJOR_VERSION EQUAL 2 AND CMAKE_MINOR_VERSION LESS 8) @@ -584,7 +585,6 @@ IF(NOT ANDROID) FIND_PACKAGE(JPEG) FIND_PACKAGE(PNG) FIND_PACKAGE(TIFF) - # QuickTime is required for OS X, but optional for Windows. IF(WIN32) FIND_PACKAGE(QuickTime) diff --git a/CMakeModules/FindAVFoundation.cmake b/CMakeModules/FindAVFoundation.cmake index a5b8ada81..a67a5de08 100644 --- a/CMakeModules/FindAVFoundation.cmake +++ b/CMakeModules/FindAVFoundation.cmake @@ -9,8 +9,6 @@ # # Created by Stephan Maximilian Huber -# QTKit on OS X looks different than QTKit for Windows, -# so I am going to case the two. IF(APPLE) FIND_PATH(AV_FOUNDATION_INCLUDE_DIR AVFoundation/AVFoundation.h) @@ -23,19 +21,22 @@ IF(AV_FOUNDATION_LIBRARY AND AV_FOUNDATION_INCLUDE_DIR) ENDIF() IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) - # TODO, AVFoundation exists ON iOS, too - SET(AV_FOUNDATION_FOUND "NO") -ENDIF() - -IF(APPLE) - # AVFoundation exists since 10.7, but only 10.8 has all features necessary for OSG - # so check the SDK-setting - - IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8") - # nothing special here ;-) + # AVFoundation exists ON iOS, too -- good support for SDK 6.0 and greater + IF(${IPHONE_SDKVER} LESS "6.0") + SET(AV_FOUNDATION_FOUND "NO") ELSE() - MESSAGE("AVFoundation disabled for SDK < 10.8") - SET(AV_FOUNDATION_FOUND "NO") + SET(AV_FOUNDATION_FOUND "YES") ENDIF() -ENDIF() +ELSE() + IF(APPLE) + # AVFoundation exists since 10.7, but only 10.8 has all features necessary for OSG + # so check the SDK-setting + IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8") + # nothing special here ;-) + ELSE() + MESSAGE("AVFoundation disabled for SDK < 10.8") + SET(AV_FOUNDATION_FOUND "NO") + ENDIF() + ENDIF() +ENDIF() diff --git a/CMakeModules/FindQuickTime.cmake b/CMakeModules/FindQuickTime.cmake index 240cb8e23..84c3d8478 100644 --- a/CMakeModules/FindQuickTime.cmake +++ b/CMakeModules/FindQuickTime.cmake @@ -49,24 +49,24 @@ ENDIF() IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) SET(QUICKTIME_FOUND "NO") -ENDIF() - -IF(APPLE) - #Quicktime is not supported under 64bit OSX build so we need to detect it and disable it. - #First check to see if we are running with a native 64-bit compiler (10.6 default) and implicit arch - IF(NOT CMAKE_OSX_ARCHITECTURES AND CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(QUICKTIME_FOUND "NO") - ELSE() - #Otherwise check to see if 64-bit is explicitly called for. - LIST(FIND CMAKE_OSX_ARCHITECTURES "x86_64" has64Compile) - IF(NOT has64Compile EQUAL -1) - SET(QUICKTIME_FOUND "NO") - ENDIF() - ENDIF() - # Disable quicktime for >= 10.7, as it's officially deprecated - - IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.7" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.9") - MESSAGE("disabling quicktime because it's not supported by the selected SDK ${OSG_OSX_SDK_NAME}") - SET(QUICKTIME_FOUND "NO") - ENDIF() +ELSE() + IF(APPLE) + #Quicktime is not supported under 64bit OSX build so we need to detect it and disable it. + #First check to see if we are running with a native 64-bit compiler (10.6 default) and implicit arch + IF(NOT CMAKE_OSX_ARCHITECTURES AND CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(QUICKTIME_FOUND "NO") + ELSE() + #Otherwise check to see if 64-bit is explicitly called for. + LIST(FIND CMAKE_OSX_ARCHITECTURES "x86_64" has64Compile) + IF(NOT has64Compile EQUAL -1) + SET(QUICKTIME_FOUND "NO") + ENDIF() + ENDIF() + # Disable quicktime for >= 10.7, as it's officially deprecated + + IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.7" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.9") + MESSAGE("disabling quicktime because it's not supported by the selected SDK ${OSG_OSX_SDK_NAME}") + SET(QUICKTIME_FOUND "NO") + ENDIF() + ENDIF() ENDIF() diff --git a/CMakeModules/FindZeroConf.cmake b/CMakeModules/FindZeroConf.cmake new file mode 100755 index 000000000..36b858e30 --- /dev/null +++ b/CMakeModules/FindZeroConf.cmake @@ -0,0 +1,47 @@ +# Locate ZeroConf / Bonjour +# This module defines +# ZEROCONF_LIBRARY +# ZEROCONF_FOUND, if false, do not try to link to gdal +# ZEROCONF_INCLUDE_DIR, where to find the headers +# +# $ZEROCONF_DIR is an environment variable that would +# correspond to the ./configure --prefix=$ZEROCONF_DIR + +# Created by Stephan Maximilian Huber + +SET(ZEROCONF_FOUND "NO") + +IF(APPLE) + # bonjour is part of the system on os x / ios + SET(ZEROCONF_FOUND "YES") +ELSE() + IF(WIN32) + # find the Bonjour SDK + FIND_PATH(ZEROCONF_INCLUDE_DIR dnssd.h + $ENV{ZEROCONF_DIR}/include + $ENV{ZEROCONF_DIR} + NO_DEFAULT_PATH + ) + FIND_PATH(ZEROCONF_INCLUDE_DIR dnssd.h + PATHS ${CMAKE_PREFIX_PATH} # Unofficial: We are proposing this. + NO_DEFAULT_PATH + PATH_SUFFIXES include + ) + FIND_PATH(ZEROCONF_INCLUDE_DIR dnssd.h) + + FIND_LIBRARY(ZEROCONF_LIBRARY dnssd + PATHS ${CMAKE_PREFIX_PATH} # Unofficial: We are proposing this. + NO_DEFAULT_PATH + PATH_SUFFIXES lib64 lib + ) + FIND_LIBRARY(ZEROCONF_LIBRARY dnssd) + + SET(ZEROCONF_FOUND "NO") + IF(ZEROCONF_LIBRARY AND ZEROCONF_INCLUDE_DIR) + SET(ZEROCONF_FOUND "YES") + ENDIF() + + ELSE() + # TODO find AVAHI on linux + ENDIF() +ENDIF() diff --git a/applications/present3D/present3D.cpp b/applications/present3D/present3D.cpp index 1911d3ef6..05e6475c2 100644 --- a/applications/present3D/present3D.cpp +++ b/applications/present3D/present3D.cpp @@ -303,6 +303,25 @@ void processLoadedModel(osg::ref_ptr& loadedModel, int optimizer_opti } } +void addDeviceTo(osgViewer::Viewer& viewer, const std::string& device_name) +{ + osg::ref_ptr dev = osgDB::readFile(device_name); + if (dev.valid()) + { + OSG_INFO << "Adding Device : " << device_name << std::endl; + if (dev->getCapabilities() & osgGA::Device::RECEIVE_EVENTS) + viewer.addDevice(dev.get()); + + if (dev->getCapabilities() & osgGA::Device::SEND_EVENTS) + viewer.getEventHandlers().push_front(new ForwardToDeviceEventHandler(dev.get())); + } + else + { + OSG_WARN << "could not open device: " << device_name << std::endl; + } +} + + int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. @@ -434,27 +453,15 @@ int main( int argc, char **argv ) const char* p3dDevice = getenv("P3D_DEVICE"); if (p3dDevice) { - osg::ref_ptr dev = osgDB::readFile(p3dDevice); - if (dev.valid()) - { - viewer.addDevice(dev.get()); - } + addDeviceTo(viewer, p3dDevice); + } std::string device; while (arguments.read("--device", device)) { - osg::ref_ptr dev = osgDB::readFile(device); - if (dev.valid()) - { - OSG_NOTICE<<"Adding Device : "<getCapabilities() & osgGA::Device::RECEIVE_EVENTS) - viewer.addDevice(dev.get()); - - if (dev->getCapabilities() & osgGA::Device::SEND_EVENTS) - viewer.getEventHandlers().push_front(new ForwardToDeviceEventHandler(dev.get())); - } + addDeviceTo(viewer, device); } diff --git a/examples/osgoscdevice/osgoscdevice.cpp b/examples/osgoscdevice/osgoscdevice.cpp index 5167e809d..0e0a7dc70 100755 --- a/examples/osgoscdevice/osgoscdevice.cpp +++ b/examples/osgoscdevice/osgoscdevice.cpp @@ -356,15 +356,53 @@ public: return false; } -private: +protected: osg::ref_ptr _device; }; +class OscServiceDiscoveredEventHandler: public ForwardToDeviceEventHandler { +public: + OscServiceDiscoveredEventHandler() : ForwardToDeviceEventHandler(NULL) {} + + virtual bool handle (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa, osg::Object *o, osg::NodeVisitor *nv) + { + if (_device.valid()) + return ForwardToDeviceEventHandler::handle(ea, aa, o, nv); + + if (ea.getEventType() == osgGA::GUIEventAdapter::USER) + { + if (ea.getName() == "/zeroconf/service-added") + { + std::string host; + unsigned int port; + ea.getUserValue("host", host); + ea.getUserValue("port", port); + + OSG_ALWAYS << "new osc-service discovered: " << host << ":" << port << std::endl; + + std::ostringstream ss ; + ss << host << ":" << port << ".sender.osc"; + _device = osgDB::readFile(ss.str()); + + osgViewer::View* view = dynamic_cast(&aa); + if (view) + view->addEventHandler(new PickHandler(_device)); + return true; + } + } + return false; + } + +}; + int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); + + arguments.getApplicationUsage()->addCommandLineOption("--zeroconf","uses zeroconf to advertise the osc-plugin and to discover it"); + // read the scene from the list of file specified commandline args. osg::ref_ptr scene = osgDB::readNodeFiles(arguments); @@ -374,6 +412,9 @@ int main( int argc, char **argv ) std::cout << argv[0] << ": requires filename argument." << std::endl; return 1; } + + bool use_zeroconf(false); + if(arguments.find("--zeroconf") > 0) { use_zeroconf = true; } // construct the viewer. osgViewer::CompositeViewer viewer(arguments); @@ -418,10 +459,20 @@ int main( int argc, char **argv ) view->addEventHandler( new osgViewer::StatsHandler ); view->addEventHandler( new UserEventHandler(text) ); - osg::ref_ptr device = osgDB::readFile("localhost:9000.receiver.osc"); + osg::ref_ptr device = osgDB::readFile("0.0.0.0:9000.receiver.osc"); if (device.valid() && (device->getCapabilities() & osgGA::Device::RECEIVE_EVENTS)) { view->addDevice(device); + + // add a zeroconf device, advertising the osc-device + if(use_zeroconf) + { + osgGA::Device* zeroconf_device = osgDB::readFile("_osc._udp:9000.advertise.zeroconf"); + if (zeroconf_device) + { + view->addDevice(zeroconf_device); + } + } } else { OSG_WARN << "could not open osc-device, receiving will not work" << std::endl; @@ -463,19 +514,29 @@ int main( int argc, char **argv ) view->addEventHandler( statesetManipulator.get() ); view->addEventHandler( new osgViewer::StatsHandler ); - // get device - - osg::ref_ptr device = osgDB::readFile("localhost:9000.sender.osc"); - if (device.valid() && (device->getCapabilities() & osgGA::Device::SEND_EVENTS)) + if (use_zeroconf) { - // add as first event handler, so it gets ALL events ... - view->getEventHandlers().push_front(new ForwardToDeviceEventHandler(device)); - - // add the demo-pick-event-handler - view->addEventHandler(new PickHandler(device)); + osgGA::Device* zeroconf_device = osgDB::readFile("_osc._udp.discover.zeroconf"); + if(zeroconf_device) { + view->addDevice(zeroconf_device); + view->getEventHandlers().push_front(new OscServiceDiscoveredEventHandler()); + + } } - else { - OSG_WARN << "could not open osc-device, sending will not work" << std::endl; + else + { + osg::ref_ptr device = osgDB::readFile("localhost:9000.sender.osc"); + if (device.valid() && (device->getCapabilities() & osgGA::Device::SEND_EVENTS)) + { + // add as first event handler, so it gets ALL events ... + view->getEventHandlers().push_front(new ForwardToDeviceEventHandler(device)); + + // add the demo-pick-event-handler + view->addEventHandler(new PickHandler(device)); + } + else { + OSG_WARN << "could not open osc-device, sending will not work" << std::endl; + } } } diff --git a/include/osgViewer/api/IOS/GraphicsWindowIOS b/include/osgViewer/api/IOS/GraphicsWindowIOS index 481bfd632..335fa7b5b 100644 --- a/include/osgViewer/api/IOS/GraphicsWindowIOS +++ b/include/osgViewer/api/IOS/GraphicsWindowIOS @@ -148,7 +148,8 @@ class GraphicsWindowIOS : public osgViewer::GraphicsWindow WindowData(UIView* window_or_view = NULL, DeviceOrientationFlags orientationFlags = ALL_ORIENTATIONS, float scaleFactor = -1.0f) : _windowOrView(window_or_view), _deviceOrientationFlags(orientationFlags), - _viewContentScaleFactor(scaleFactor) + _viewContentScaleFactor(scaleFactor), + _createTransparentView(false) { } @@ -157,11 +158,15 @@ class GraphicsWindowIOS : public osgViewer::GraphicsWindow void setViewContentScaleFactor(float scaleFactor) { _viewContentScaleFactor = scaleFactor; } UIView* getWindowOrParentView() const { return _windowOrView; } + + bool getCreateTransparentView() { return _createTransparentView; } + void setCreateTransparentView(bool b) { _createTransparentView = b; } private: UIView* _windowOrView; DeviceOrientationFlags _deviceOrientationFlags; float _viewContentScaleFactor; + bool _createTransparentView; friend class GraphicsWindowIOS; diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 0e54e8812..117efa7d0 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -2745,7 +2745,19 @@ Geometry* osg::createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVe geom->setNormalArray(normals); geom->setNormalBinding(Geometry::BIND_OVERALL); +#if defined(OSG_GLES1_AVAILABLE) || !defined(OSG_GLES2_AVAILABLE) + DrawElementsUByte* elems = new DrawElementsUByte(PrimitiveSet::TRIANGLES); + elems->push_back(0); + elems->push_back(1); + elems->push_back(2); + + elems->push_back(2); + elems->push_back(3); + elems->push_back(0); + geom->addPrimitiveSet(elems); +#else geom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,4)); +#endif return geom; } diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 02c3de4df..5c8b1706a 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -269,6 +269,11 @@ IF(ASIO_FOUND) ADD_SUBDIRECTORY(RestHttpDevice) ENDIF(ASIO_FOUND) + +IF(ZEROCONF_FOUND) + ADD_SUBDIRECTORY(ZeroConfDevice) +ENDIF() + ##########to get all the variables of Cmake #GET_CMAKE_PROPERTY(MYVARS VARIABLES) #FOREACH(myvar ${MYVARS}) diff --git a/src/osgPlugins/QTKit/OSXCoreVideoTexture.cpp b/src/osgPlugins/QTKit/OSXCoreVideoTexture.cpp index acb2965fc..673bcbf74 100644 --- a/src/osgPlugins/QTKit/OSXCoreVideoTexture.cpp +++ b/src/osgPlugins/QTKit/OSXCoreVideoTexture.cpp @@ -130,13 +130,16 @@ void OSXCoreVideoTexture::setImage(osg::Image* image) void OSXCoreVideoTexture::apply(osg::State& state) const { if (!_image.valid()) return; - + if (!_adapter.valid()) { - OSXQTKitVideo* m = dynamic_cast(_image.get()); - if ((m) && (m->getCoreVideoAdapter())) - _adapter = m->getCoreVideoAdapter(); - else - _adapter = new OSXCoreVideoAdapter(state, _image.get()); + OpenThreads::ScopedLock lock(_mutex); + if (!_adapter.valid()) { + OSXQTKitVideo* m = dynamic_cast(_image.get()); + if ((m) && (m->getCoreVideoAdapter())) + _adapter = m->getCoreVideoAdapter(); + else + _adapter = new OSXCoreVideoAdapter(state, _image.get()); + } } _adapter->getFrame(); diff --git a/src/osgPlugins/QTKit/OSXCoreVideoTexture.h b/src/osgPlugins/QTKit/OSXCoreVideoTexture.h index 60095dc5a..a61e37f23 100644 --- a/src/osgPlugins/QTKit/OSXCoreVideoTexture.h +++ b/src/osgPlugins/QTKit/OSXCoreVideoTexture.h @@ -76,5 +76,6 @@ class OSXCoreVideoTexture : public osg::Texture { typedef osg::buffered_value ImageModifiedCount; mutable ImageModifiedCount _modifiedCount; + mutable OpenThreads::Mutex _mutex; }; diff --git a/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp b/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp index ba30a0668..c4bf58632 100755 --- a/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp +++ b/src/osgPlugins/RestHttpDevice/RestHttpDevice.cpp @@ -13,22 +13,31 @@ #include "RestHttpDevice.hpp" #include +#include #include #include "request_handler.hpp" + class StandardRequestHandler : public RestHttpDevice::RequestHandler { public: StandardRequestHandler() : RestHttpDevice::RequestHandler("") {} virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const Arguments& arguments, http::server::reply& reply) { - OSG_NOTICE << "RestHttpDevice :: unhandled request: " << full_request_path << std::endl; + OSG_INFO << "RestHttpDevice :: handling request " << full_request_path << " as user-event" << std::endl; + + osg::ref_ptr event = new osgGA::GUIEventAdapter(); + event->setEventType(osgGA::GUIEventAdapter::USER); + event->setName(full_request_path); + event->setTime(getDevice()->getEventQueue()->getTime()); + for(Arguments::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { - OSG_NOTICE << "RestHttpDevice :: " << i->first << ": " << i->second << std::endl; + event->setUserValue(i->first,i->second); } + getDevice()->getEventQueue()->addEvent(event.get()); - return false; + return sendOkReply(reply); } virtual void describeTo(std::ostream& out) const @@ -138,7 +147,10 @@ public: double time_stamp = getTimeStamp(arguments, reply); if (getDevice()->isNewer(time_stamp)) - getDevice()->getEventQueue()->mouseMotion(x,y, getLocalTime(time_stamp)); + { + //getDevice()->getEventQueue()->mouseMotion(x,y, getLocalTime(time_stamp)); + getDevice()->setTargetMousePosition(x,y); + } } return sendOkReply(reply); @@ -182,6 +194,7 @@ public: && getIntArgument(arguments, "y", reply, y) && getIntArgument(arguments, "button", reply, button)) { + getDevice()->setTargetMousePosition(x,y, true); switch (_mode) { case PRESS: getDevice()->getEventQueue()->mouseButtonPress(x,y, button, getLocalTime(arguments, reply)); @@ -253,7 +266,9 @@ RestHttpDevice::RestHttpDevice(const std::string& listening_address, const std:: , _firstEventRemoteTimeStamp(-1) , _lastEventRemoteTimeStamp(0) { - OSG_INFO << "RestHttpDevice :: listening on " << listening_address << ":" << listening_port << ", document root: " << doc_root << std::endl; + setCapabilities(RECEIVE_EVENTS); + + OSG_NOTICE << "RestHttpDevice :: listening on " << listening_address << ":" << listening_port << ", document root: " << doc_root << std::endl; if (osgDB::findDataFile(doc_root).empty()) { diff --git a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp index 9a03fe9f5..5c2197148 100755 --- a/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp +++ b/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp @@ -169,7 +169,26 @@ public: - virtual void checkEvents() {} + virtual void checkEvents() + { + if ((fabs(_currentMouseX - _targetMouseY) > 0.1f) || (fabs(_currentMouseY - _targetMouseY) > 0.1)) + { + static const float scalar = 0.2f; + _currentMouseX = (1.0f - scalar) * _currentMouseX + scalar * _targetMouseX; + _currentMouseY = (1.0f - scalar) * _currentMouseY + scalar * _targetMouseY; + getEventQueue()->mouseMotion(_currentMouseX, _currentMouseY, getEventQueue()->getTime()); + } + } + + void setTargetMousePosition(float x, float y, bool force = false) + { + _targetMouseX = x; _targetMouseY = y; + if (force) { + _currentMouseX = x; _currentMouseY = y; + } + } + + private: void parseArguments(const std::string request_path, RequestHandler::Arguments& arguments); @@ -179,6 +198,7 @@ private: double _firstEventLocalTimeStamp; double _firstEventRemoteTimeStamp; double _lastEventRemoteTimeStamp; + float _currentMouseX, _currentMouseY, _targetMouseX, _targetMouseY; }; diff --git a/src/osgPlugins/RestHttpDevice/connection.cpp b/src/osgPlugins/RestHttpDevice/connection.cpp index ed76e5316..f591083ad 100755 --- a/src/osgPlugins/RestHttpDevice/connection.cpp +++ b/src/osgPlugins/RestHttpDevice/connection.cpp @@ -22,12 +22,12 @@ connection::connection(asio::io_service& io_service, : socket_(io_service), request_handler_(handler) { - OSG_INFO << "RestHttpDevice :: connection::connection" << std::endl; + OSG_DEBUG << "RestHttpDevice :: connection::connection" << std::endl; } connection::~connection() { - OSG_INFO << "RestHttpDevice :: connection::~connection" << std::endl; + OSG_DEBUG << "RestHttpDevice :: connection::~connection" << std::endl; } asio::ip::tcp::socket& connection::socket() { @@ -36,7 +36,7 @@ asio::ip::tcp::socket& connection::socket() void connection::start() { - OSG_INFO << "RestHttpDevice :: connection::start" << std::endl; + OSG_DEBUG << "RestHttpDevice :: connection::start" << std::endl; socket_.async_read_some(asio::buffer(buffer_), boost::bind(&connection::handle_read, shared_from_this(), diff --git a/src/osgPlugins/RestHttpDevice/request_handler.cpp b/src/osgPlugins/RestHttpDevice/request_handler.cpp index 3921c1cc1..63fc9d4b5 100755 --- a/src/osgPlugins/RestHttpDevice/request_handler.cpp +++ b/src/osgPlugins/RestHttpDevice/request_handler.cpp @@ -68,6 +68,10 @@ void request_handler::handle_request(const request& req, reply& rep) } return; } + else + { + OSG_INFO << "RestHttpDevice :: serving file " << full_path << std::endl; + } // Fill out the reply to be sent to the client. rep.status = reply::ok; diff --git a/src/osgPlugins/RestHttpDevice/server.cpp b/src/osgPlugins/RestHttpDevice/server.cpp index 47ef3a63c..d0231ef10 100755 --- a/src/osgPlugins/RestHttpDevice/server.cpp +++ b/src/osgPlugins/RestHttpDevice/server.cpp @@ -51,7 +51,7 @@ void server::handle_accept(const asio::error_code& e) { if (!e) { - OSG_INFO << "RestHttpDevice :: server::handle_accept" << std::endl; + OSG_DEBUG << "RestHttpDevice :: server::handle_accept" << std::endl; new_connection_->start(); new_connection_.reset(new connection( io_service_pool_.get_io_service(), request_handler_)); diff --git a/src/osgPlugins/avfoundation/CMakeLists.txt b/src/osgPlugins/avfoundation/CMakeLists.txt index 765acd360..73544a48c 100644 --- a/src/osgPlugins/avfoundation/CMakeLists.txt +++ b/src/osgPlugins/avfoundation/CMakeLists.txt @@ -14,4 +14,4 @@ SET(TARGET_LIBRARIES_VARS AV_FOUNDATION_LIBRARY COCOA_LIBRARY COREVIDEO_LIBRARY SET(TARGET_ADDED_LIBRARIES osgViewer ) #### end var setup ### -SETUP_PLUGIN(AVFoundation) +SETUP_PLUGIN(avfoundation) diff --git a/src/osgPlugins/avfoundation/OSXAVFoundationVideo.h b/src/osgPlugins/avfoundation/OSXAVFoundationVideo.h index d48349c99..2ec51f6bd 100644 --- a/src/osgPlugins/avfoundation/OSXAVFoundationVideo.h +++ b/src/osgPlugins/avfoundation/OSXAVFoundationVideo.h @@ -10,8 +10,6 @@ - - #include #include "../QTKit/VideoFrameDispatcher.h" @@ -117,3 +115,4 @@ private: double _framerate; }; + diff --git a/src/osgPlugins/avfoundation/OSXAVFoundationVideo.mm b/src/osgPlugins/avfoundation/OSXAVFoundationVideo.mm index c647ad93c..6e32aa58c 100644 --- a/src/osgPlugins/avfoundation/OSXAVFoundationVideo.mm +++ b/src/osgPlugins/avfoundation/OSXAVFoundationVideo.mm @@ -1,13 +1,18 @@ #include "OSXAVFoundationVideo.h" #include -#include #include #include #import +#import "TargetConditionals.h" +#if (TARGET_OS_IPHONE) +#import +#include +#else #import - +#include +#endif #include "OSXAVFoundationCoreVideoTexture.h" @@ -105,7 +110,11 @@ public: OSXAVFoundationVideoDelegate* delegate; std::vector lastFrames; int readFrameNdx, writeFrameNdx; + #if (TARGET_OS_IPHONE) + CVOpenGLESTextureCacheRef coreVideoTextureCache; + #else CVOpenGLTextureCacheRef coreVideoTextureCache; + #endif Data() : avplayer(NULL) @@ -157,7 +166,11 @@ public: if (coreVideoTextureCache) { + #if (TARGET_OS_IPHONE) + CFRelease(coreVideoTextureCache); // huh, there's no CVOpenGLESTextureCacheRelease? + #else CVOpenGLTextureCacheRelease(coreVideoTextureCache); + #endif coreVideoTextureCache = NULL; } } @@ -416,20 +429,30 @@ void OSXAVFoundationVideo::decodeFrame() if (isCoreVideoUsed()) { CVPixelBufferLockBaseAddress(newframe, kCVPixelBufferLock_ReadOnly); - - CVOpenGLTextureRef texture = NULL; - CVReturn err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _data->coreVideoTextureCache, newframe, 0, &texture); - if (err) - { - OSG_WARN << "OSXAVFoundationVideo :: could not create texture from image, err: " << err << std::endl; - } int w = CVPixelBufferGetWidth(newframe); int h = CVPixelBufferGetHeight(newframe); + + #if (TARGET_OS_IPHONE) + CVOpenGLESTextureRef texture = NULL; + CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _data->coreVideoTextureCache, newframe, NULL, GL_TEXTURE_2D, GL_RGBA, w, h, GL_BGRA, GL_UNSIGNED_BYTE, 0, &texture); + if (err) + { + OSG_WARN << "OSXAVFoundationVideo :: could not create texture from image, err: " << err << std::endl; + } + _data->addFrame(texture); + #else + CVOpenGLTextureRef texture = NULL; + CVReturn err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _data->coreVideoTextureCache, newframe, 0, &texture); + if (err) + { + OSG_WARN << "OSXAVFoundationVideo :: could not create texture from image, err: " << err << std::endl; + } + + _data->addFrame(texture); + #endif _dimensionsChangedCallbackNeeded = (_s != w) || (_t != h); _s = w; _t = h; _r = 1; - - _data->addFrame(texture); - + CVPixelBufferUnlockBaseAddress(newframe, kCVPixelBufferLock_ReadOnly); CVPixelBufferRelease(newframe); } @@ -500,17 +523,29 @@ void OSXAVFoundationVideo::requestNewFrame() bool OSXAVFoundationVideo::getCurrentCoreVideoTexture(GLenum& target, GLint& name, int& width, int& height) const { - CVOpenGLTextureCacheFlush(_data->coreVideoTextureCache, 0); - CVOpenGLTextureRef texture = _data->getLastFrame(); - if (texture) - { - target = CVOpenGLTextureGetTarget(texture); - name = CVOpenGLTextureGetName(texture); - width = _s; - height = _t; - } - - return (texture != NULL); + #if (TARGET_OS_IPHONE) + CVOpenGLESTextureCacheFlush(_data->coreVideoTextureCache, 0); + CVOpenGLESTextureRef texture = _data->getLastFrame(); + if(texture) { + target = GL_TEXTURE_2D; + name = CVOpenGLESTextureGetName(texture); + width = _s; + height = _t; + } + return (texture != NULL); + #else + CVOpenGLTextureCacheFlush(_data->coreVideoTextureCache, 0); + CVOpenGLTextureRef texture = _data->getLastFrame(); + if (texture) + { + target = CVOpenGLTextureGetTarget(texture); + name = CVOpenGLTextureGetName(texture); + width = _s; + height = _t; + } + + return (texture != NULL); + #endif } @@ -518,25 +553,42 @@ void OSXAVFoundationVideo::lazyInitCoreVideoTextureCache(osg::State& state) { if (_data->coreVideoTextureCache) return; - - osgViewer::GraphicsWindowCocoa* win = dynamic_cast(state.getGraphicsContext()); - if (win) - { - NSOpenGLContext* context = win->getContext(); - CGLContextObj cglcntx = (CGLContextObj)[context CGLContextObj]; - CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[ win->getPixelFormat() CGLPixelFormatObj]; - CVReturn cvRet = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, 0, cglcntx, cglPixelFormat, 0, &_data->coreVideoTextureCache); - if (cvRet != kCVReturnSuccess) + #if (TARGET_OS_IPHONE) + osgViewer::GraphicsWindowIOS* win = dynamic_cast(state.getGraphicsContext()); + if (win) { - OSG_WARN << "OSXAVFoundationVideo : could not create texture cache :" << cvRet << std::endl; + EAGLContext* context = win->getContext(); + CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, context, NULL, &_data->coreVideoTextureCache); + if (err) + { + OSG_WARN << "OSXAVFoundationVideo : could not create texture cache :" << err << std::endl; + } } - } + + #else + osgViewer::GraphicsWindowCocoa* win = dynamic_cast(state.getGraphicsContext()); + if (win) + { + NSOpenGLContext* context = win->getContext(); + CGLContextObj cglcntx = (CGLContextObj)[context CGLContextObj]; + CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[ win->getPixelFormat() CGLPixelFormatObj]; + CVReturn cvRet = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, 0, cglcntx, cglPixelFormat, 0, &_data->coreVideoTextureCache); + if (cvRet != kCVReturnSuccess) + { + OSG_WARN << "OSXAVFoundationVideo : could not create texture cache :" << cvRet << std::endl; + } + } + #endif } osg::Texture* OSXAVFoundationVideo::createSuitableTexture() { - return NULL; // new OSXAVFoundationCoreVideoTexture(this); + #if (TARGET_OS_IPHONE) + return new OSXAVFoundationCoreVideoTexture(this); + #else + return NULL; // new OSXAVFoundationCoreVideoTexture(this); + #endif } diff --git a/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.cpp b/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.cpp index 4d4a9e1d4..4f0197ac1 100644 --- a/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.cpp +++ b/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.cpp @@ -11,14 +11,23 @@ * OpenSceneGraph Public License for more details. */ + +#import "TargetConditionals.h" +#if (TARGET_OS_IPHONE) +#define COREVIDEO_TEXTURE_TARGET GL_TEXTURE_2D +#else +#define COREVIDEO_TEXTURE_TARGET GL_TEXTURE_RECTANGLE_EXT +#endif + #include "OSXAVFoundationCoreVideoTexture.h" #include "OSXAVFoundationVideo.H" #include + OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture() : osg::Texture() - , _textureTarget(GL_TEXTURE_RECTANGLE_EXT) + , _textureTarget(COREVIDEO_TEXTURE_TARGET) , _textureWidth(0) , _textureHeight(0) , _inited(false) @@ -28,7 +37,7 @@ OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture() OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture(osg::Image* image) : osg::Texture() - , _textureTarget(GL_TEXTURE_RECTANGLE_EXT) + , _textureTarget(COREVIDEO_TEXTURE_TARGET) , _textureWidth(0) , _textureHeight(0) , _inited(false) diff --git a/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.h b/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.h index e3c46c30a..62160bf93 100644 --- a/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.h +++ b/src/osgPlugins/avfoundation/OSXAvFoundationCoreVideoTexture.h @@ -13,6 +13,7 @@ #pragma once + #include @@ -73,4 +74,4 @@ class OSXAVFoundationCoreVideoTexture : public osg::Texture { typedef osg::buffered_value ImageModifiedCount; mutable ImageModifiedCount _modifiedCount; -}; \ No newline at end of file +}; diff --git a/src/osgPlugins/avfoundation/ReaderWriterAVFoundation.cpp b/src/osgPlugins/avfoundation/ReaderWriterAVFoundation.cpp index 0933b7dda..f6504e273 100644 --- a/src/osgPlugins/avfoundation/ReaderWriterAVFoundation.cpp +++ b/src/osgPlugins/avfoundation/ReaderWriterAVFoundation.cpp @@ -104,8 +104,11 @@ class ReaderWriterAVFoundation : public osgDB::ReaderWriter if (!video || !use_core_video) return rr; - osg::ref_ptr texture = new OSXAVFoundationCoreVideoTexture(video); - return texture.release(); + osg::ref_ptr texture = video->createSuitableTexture(); + if (texture.valid()) + return texture.release(); + + return video.release(); } protected: @@ -117,4 +120,4 @@ class ReaderWriterAVFoundation : public osgDB::ReaderWriter // now register with Registry to instantiate the above // reader/writer. -REGISTER_OSGPLUGIN(AVFoundation, ReaderWriterAVFoundation) +REGISTER_OSGPLUGIN(avfoundation, ReaderWriterAVFoundation) diff --git a/src/osgPlugins/imageio/CMakeLists.txt b/src/osgPlugins/imageio/CMakeLists.txt index 3e806e800..20b257cf8 100644 --- a/src/osgPlugins/imageio/CMakeLists.txt +++ b/src/osgPlugins/imageio/CMakeLists.txt @@ -1,13 +1,9 @@ -IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) - SET(TARGET_SRC ReaderWriterImageIO_IOS.cpp ) -ELSE() - SET(TARGET_SRC ReaderWriterImageIO.cpp ) -ENDIF() +SET(TARGET_SRC ReaderWriterImageIO.cpp ) IF (APPLE) IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR) # compile FileUtils.cpp as objective-c++ - SET_SOURCE_FILES_PROPERTIES(ReaderWriterImageIO_IOS.cpp + SET_SOURCE_FILES_PROPERTIES(ReaderWriterImageIO.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++" ) ENDIF() diff --git a/src/osgPlugins/imageio/ReaderWriterImageIO.cpp b/src/osgPlugins/imageio/ReaderWriterImageIO.cpp index 6c52a3d24..2093323a4 100644 --- a/src/osgPlugins/imageio/ReaderWriterImageIO.cpp +++ b/src/osgPlugins/imageio/ReaderWriterImageIO.cpp @@ -18,14 +18,24 @@ // probably especially important for istream which lacks extension information. // Is there information we can use in the OSG options parameter? -// For ImageIO framework and also LaunchServices framework (for UTIs) -#include + +#import "TargetConditionals.h" +#if (TARGET_OS_IPHONE) + #import + #import + #import + #import + #import +#else + #include +#endif // For the vImage framework (part of the Accerlate framework) #include // Used because CGDataProviderCreate became deprecated in 10.5 #include + #include #include #include diff --git a/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp b/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp deleted file mode 100644 index cc8c969ba..000000000 --- a/src/osgPlugins/imageio/ReaderWriterImageIO_IOS.cpp +++ /dev/null @@ -1,572 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include // for istream -#include // for ios:: - -#import -#import -#import -#import - -/************************************************************** - ***** Begin Callback functions for istream block reading ***** - **************************************************************/ - -// This callback reads some bytes from an istream and copies it -// 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 -} - -// 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; -} - -void MyProviderRewindCallback(void* istream_userdata) -{ - 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); -} - -/************************************************************** - ***** End Callback functions for istream block reading ******** - **************************************************************/ - - -/************************************************************** - ***** Begin Callback functions for ostream block writing ****** - **************************************************************/ -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; -} - -void MyConsumerReleaseInfoCallback(void* ostream_userdata) -{ - std::ostream* the_ostream = (std::ostream*)ostream_userdata; - the_ostream->flush(); -} -/************************************************************** - ***** End Callback functions for ostream block writing ******** - **************************************************************/ - - -/************************************************************** - ***** Begin Support functions for reading (stream and file) *** - **************************************************************/ - -/* 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; -} - -static NSString* toNSString(const std::string& text, NSStringEncoding nsse) -{ - NSString* nstr = nil; - - if (!text.empty()) - { - nstr = [NSString stringWithCString:text.c_str() encoding:nsse]; - //nstr = [NSString stringWithUTF8String:text.c_str()];// encoding:nsse] - } - - if (nstr == nil) - { - nstr = @""; - } - - return nstr; -} - -// std::string to NSString with the UTF8 encoding - -static NSString* toNSString(const std::string& text) -{ - return toNSString(text, NSUTF8StringEncoding); -} - -// -//really basic image io for IOS -// -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() 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, - 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) { - pixels[j] = (static_cast(pixels[j]) * 255) / alpha; - } - } - pixels += 4; - } - - [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; - } - - 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 - // 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) { - pixels[j] = (static_cast(pixels[j]) * 255) / alpha; - } - } - pixels += 4; - } - - [pool release]; - return image; -} - -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"); - } - - 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") || - osgDB::equalCaseInsensitive(extension,"jp2") || - osgDB::equalCaseInsensitive(extension,"tiff") || - osgDB::equalCaseInsensitive(extension,"tif") || - osgDB::equalCaseInsensitive(extension,"gif") || - osgDB::equalCaseInsensitive(extension,"png") || - osgDB::equalCaseInsensitive(extension,"pict") || - osgDB::equalCaseInsensitive(extension,"pct") || - osgDB::equalCaseInsensitive(extension,"pic") || - osgDB::equalCaseInsensitive(extension,"bmp") || - osgDB::equalCaseInsensitive(extension,"BMPf") || - osgDB::equalCaseInsensitive(extension,"ico") || - osgDB::equalCaseInsensitive(extension,"icns") || - osgDB::equalCaseInsensitive(extension,"tga") || - osgDB::equalCaseInsensitive(extension,"targa") || - osgDB::equalCaseInsensitive(extension,"psd") || - - osgDB::equalCaseInsensitive(extension,"pdf") || - osgDB::equalCaseInsensitive(extension,"eps") || - osgDB::equalCaseInsensitive(extension,"epi") || - osgDB::equalCaseInsensitive(extension,"epsf") || - osgDB::equalCaseInsensitive(extension,"epsi") || - osgDB::equalCaseInsensitive(extension,"ps") || - - osgDB::equalCaseInsensitive(extension,"dng") || - osgDB::equalCaseInsensitive(extension,"cr2") || - osgDB::equalCaseInsensitive(extension,"crw") || - osgDB::equalCaseInsensitive(extension,"fpx") || - osgDB::equalCaseInsensitive(extension,"fpxi") || - osgDB::equalCaseInsensitive(extension,"raf") || - osgDB::equalCaseInsensitive(extension,"dcr") || - osgDB::equalCaseInsensitive(extension,"ptng") || - osgDB::equalCaseInsensitive(extension,"pnt") || - osgDB::equalCaseInsensitive(extension,"mac") || - osgDB::equalCaseInsensitive(extension,"mrw") || - osgDB::equalCaseInsensitive(extension,"nef") || - osgDB::equalCaseInsensitive(extension,"orf") || - osgDB::equalCaseInsensitive(extension,"exr") || - osgDB::equalCaseInsensitive(extension,"qti") || - osgDB::equalCaseInsensitive(extension,"qtif") || - osgDB::equalCaseInsensitive(extension,"hdr") || - osgDB::equalCaseInsensitive(extension,"sgi") || - osgDB::equalCaseInsensitive(extension,"srf") || - osgDB::equalCaseInsensitive(extension,"cur") || - 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; - - // Create an osg::Image from the CGImageRef. - osg::Image* osg_image = ReadCoreGraphicsImageFromFile(file_name); - - 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; - - 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); -#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); -#endif - - 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; - - 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; - } - - 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; - -#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); -#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 - } - -}; - -// now register with Registry to instantiate the above -// reader/writer. -REGISTER_OSGPLUGIN(imageio, ReaderWriterImageIO) diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index f8e730c06..ab4f0da6c 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -60,7 +60,7 @@ using namespace osgPresentation; #define USE_CLIENT_STORAGE_HINT 0 -#define USE_TEXTURE_FROM_VIDEO_PLUGIN 1 + class SetToTransparentBin : public osg::NodeVisitor { @@ -857,12 +857,10 @@ osg::Geometry* SlideShowConstructor::createTexturedQuadGeometry(const osg::Vec3& osg::ImageStream* imageStream = dynamic_cast(image); // let the video-plugin create a texture for us, if supported - #if USE_TEXTURE_FROM_VIDEO_PLUGIN - if(imageStream) + if(imageStream && getenv("P3D_ENABLE_CORE_VIDEO")) { texture = imageStream->createSuitableTexture(); } - #endif bool flipYAxis = image->getOrigin()==osg::Image::TOP_LEFT;