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"
This commit is contained in:
parent
ce0f928f6f
commit
eed71f647d
@ -233,7 +233,7 @@ IF(APPLE)
|
|||||||
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
||||||
|
|
||||||
#you need to manually set the default sdk version here
|
#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
|
#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
|
# Force gcc <= 4.2 on iPhone
|
||||||
@ -517,6 +517,7 @@ ELSE()
|
|||||||
FIND_PACKAGE(DirectInput)
|
FIND_PACKAGE(DirectInput)
|
||||||
FIND_PACKAGE(NVTT)
|
FIND_PACKAGE(NVTT)
|
||||||
FIND_PACKAGE(Asio)
|
FIND_PACKAGE(Asio)
|
||||||
|
FIND_PACKAGE(ZeroConf)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(CMAKE_MAJOR_VERSION EQUAL 2 AND CMAKE_MINOR_VERSION LESS 8)
|
IF(CMAKE_MAJOR_VERSION EQUAL 2 AND CMAKE_MINOR_VERSION LESS 8)
|
||||||
@ -584,7 +585,6 @@ IF(NOT ANDROID)
|
|||||||
FIND_PACKAGE(JPEG)
|
FIND_PACKAGE(JPEG)
|
||||||
FIND_PACKAGE(PNG)
|
FIND_PACKAGE(PNG)
|
||||||
FIND_PACKAGE(TIFF)
|
FIND_PACKAGE(TIFF)
|
||||||
|
|
||||||
# QuickTime is required for OS X, but optional for Windows.
|
# QuickTime is required for OS X, but optional for Windows.
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
FIND_PACKAGE(QuickTime)
|
FIND_PACKAGE(QuickTime)
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#
|
#
|
||||||
# Created by Stephan Maximilian Huber
|
# 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)
|
IF(APPLE)
|
||||||
FIND_PATH(AV_FOUNDATION_INCLUDE_DIR AVFoundation/AVFoundation.h)
|
FIND_PATH(AV_FOUNDATION_INCLUDE_DIR AVFoundation/AVFoundation.h)
|
||||||
@ -23,19 +21,22 @@ IF(AV_FOUNDATION_LIBRARY AND AV_FOUNDATION_INCLUDE_DIR)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
||||||
# TODO, AVFoundation exists ON iOS, too
|
# AVFoundation exists ON iOS, too -- good support for SDK 6.0 and greater
|
||||||
SET(AV_FOUNDATION_FOUND "NO")
|
IF(${IPHONE_SDKVER} LESS "6.0")
|
||||||
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 ;-)
|
|
||||||
ELSE()
|
|
||||||
MESSAGE("AVFoundation disabled for SDK < 10.8")
|
|
||||||
SET(AV_FOUNDATION_FOUND "NO")
|
SET(AV_FOUNDATION_FOUND "NO")
|
||||||
|
ELSE()
|
||||||
|
SET(AV_FOUNDATION_FOUND "YES")
|
||||||
ENDIF()
|
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()
|
||||||
|
@ -49,24 +49,24 @@ ENDIF()
|
|||||||
|
|
||||||
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
||||||
SET(QUICKTIME_FOUND "NO")
|
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(APPLE)
|
IF(${OSG_OSX_SDK_NAME} STREQUAL "macosx10.7" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.8" OR ${OSG_OSX_SDK_NAME} STREQUAL "macosx10.9")
|
||||||
#Quicktime is not supported under 64bit OSX build so we need to detect it and disable it.
|
MESSAGE("disabling quicktime because it's not supported by the selected SDK ${OSG_OSX_SDK_NAME}")
|
||||||
#First check to see if we are running with a native 64-bit compiler (10.6 default) and implicit arch
|
SET(QUICKTIME_FOUND "NO")
|
||||||
IF(NOT CMAKE_OSX_ARCHITECTURES AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
ENDIF()
|
||||||
SET(QUICKTIME_FOUND "NO")
|
ENDIF()
|
||||||
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()
|
||||||
|
47
CMakeModules/FindZeroConf.cmake
Executable file
47
CMakeModules/FindZeroConf.cmake
Executable file
@ -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()
|
@ -303,6 +303,25 @@ void processLoadedModel(osg::ref_ptr<osg::Node>& loadedModel, int optimizer_opti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addDeviceTo(osgViewer::Viewer& viewer, const std::string& device_name)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osgGA::Device> dev = osgDB::readFile<osgGA::Device>(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 )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
// use an ArgumentParser object to manage the program arguments.
|
// 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");
|
const char* p3dDevice = getenv("P3D_DEVICE");
|
||||||
if (p3dDevice)
|
if (p3dDevice)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osgGA::Device> dev = osgDB::readFile<osgGA::Device>(p3dDevice);
|
addDeviceTo(viewer, p3dDevice);
|
||||||
if (dev.valid())
|
|
||||||
{
|
|
||||||
viewer.addDevice(dev.get());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string device;
|
std::string device;
|
||||||
while (arguments.read("--device", device))
|
while (arguments.read("--device", device))
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osgGA::Device> dev = osgDB::readFile<osgGA::Device>(device);
|
addDeviceTo(viewer, device);
|
||||||
if (dev.valid())
|
|
||||||
{
|
|
||||||
OSG_NOTICE<<"Adding Device : "<<device<<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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,16 +356,54 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
osg::ref_ptr<osgGA::Device> _device;
|
osg::ref_ptr<osgGA::Device> _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<osgGA::Device>(ss.str());
|
||||||
|
|
||||||
|
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
|
||||||
|
if (view)
|
||||||
|
view->addEventHandler(new PickHandler(_device));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
// use an ArgumentParser object to manage the program arguments.
|
// use an ArgumentParser object to manage the program arguments.
|
||||||
osg::ArgumentParser arguments(&argc,argv);
|
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.
|
// read the scene from the list of file specified commandline args.
|
||||||
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
|
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
|
||||||
|
|
||||||
@ -375,6 +413,9 @@ int main( int argc, char **argv )
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_zeroconf(false);
|
||||||
|
if(arguments.find("--zeroconf") > 0) { use_zeroconf = true; }
|
||||||
|
|
||||||
// construct the viewer.
|
// construct the viewer.
|
||||||
osgViewer::CompositeViewer viewer(arguments);
|
osgViewer::CompositeViewer viewer(arguments);
|
||||||
|
|
||||||
@ -418,10 +459,20 @@ int main( int argc, char **argv )
|
|||||||
view->addEventHandler( new osgViewer::StatsHandler );
|
view->addEventHandler( new osgViewer::StatsHandler );
|
||||||
view->addEventHandler( new UserEventHandler(text) );
|
view->addEventHandler( new UserEventHandler(text) );
|
||||||
|
|
||||||
osg::ref_ptr<osgGA::Device> device = osgDB::readFile<osgGA::Device>("localhost:9000.receiver.osc");
|
osg::ref_ptr<osgGA::Device> device = osgDB::readFile<osgGA::Device>("0.0.0.0:9000.receiver.osc");
|
||||||
if (device.valid() && (device->getCapabilities() & osgGA::Device::RECEIVE_EVENTS))
|
if (device.valid() && (device->getCapabilities() & osgGA::Device::RECEIVE_EVENTS))
|
||||||
{
|
{
|
||||||
view->addDevice(device);
|
view->addDevice(device);
|
||||||
|
|
||||||
|
// add a zeroconf device, advertising the osc-device
|
||||||
|
if(use_zeroconf)
|
||||||
|
{
|
||||||
|
osgGA::Device* zeroconf_device = osgDB::readFile<osgGA::Device>("_osc._udp:9000.advertise.zeroconf");
|
||||||
|
if (zeroconf_device)
|
||||||
|
{
|
||||||
|
view->addDevice(zeroconf_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OSG_WARN << "could not open osc-device, receiving will not work" << std::endl;
|
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( statesetManipulator.get() );
|
||||||
view->addEventHandler( new osgViewer::StatsHandler );
|
view->addEventHandler( new osgViewer::StatsHandler );
|
||||||
|
|
||||||
// get device
|
if (use_zeroconf)
|
||||||
|
|
||||||
osg::ref_ptr<osgGA::Device> device = osgDB::readFile<osgGA::Device>("localhost:9000.sender.osc");
|
|
||||||
if (device.valid() && (device->getCapabilities() & osgGA::Device::SEND_EVENTS))
|
|
||||||
{
|
{
|
||||||
// add as first event handler, so it gets ALL events ...
|
osgGA::Device* zeroconf_device = osgDB::readFile<osgGA::Device>("_osc._udp.discover.zeroconf");
|
||||||
view->getEventHandlers().push_front(new ForwardToDeviceEventHandler(device));
|
if(zeroconf_device) {
|
||||||
|
view->addDevice(zeroconf_device);
|
||||||
|
view->getEventHandlers().push_front(new OscServiceDiscoveredEventHandler());
|
||||||
|
|
||||||
// add the demo-pick-event-handler
|
}
|
||||||
view->addEventHandler(new PickHandler(device));
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
OSG_WARN << "could not open osc-device, sending will not work" << std::endl;
|
{
|
||||||
|
osg::ref_ptr<osgGA::Device> device = osgDB::readFile<osgGA::Device>("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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,8 @@ class GraphicsWindowIOS : public osgViewer::GraphicsWindow
|
|||||||
WindowData(UIView* window_or_view = NULL, DeviceOrientationFlags orientationFlags = ALL_ORIENTATIONS, float scaleFactor = -1.0f)
|
WindowData(UIView* window_or_view = NULL, DeviceOrientationFlags orientationFlags = ALL_ORIENTATIONS, float scaleFactor = -1.0f)
|
||||||
: _windowOrView(window_or_view),
|
: _windowOrView(window_or_view),
|
||||||
_deviceOrientationFlags(orientationFlags),
|
_deviceOrientationFlags(orientationFlags),
|
||||||
_viewContentScaleFactor(scaleFactor)
|
_viewContentScaleFactor(scaleFactor),
|
||||||
|
_createTransparentView(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,11 +158,15 @@ class GraphicsWindowIOS : public osgViewer::GraphicsWindow
|
|||||||
void setViewContentScaleFactor(float scaleFactor) { _viewContentScaleFactor = scaleFactor; }
|
void setViewContentScaleFactor(float scaleFactor) { _viewContentScaleFactor = scaleFactor; }
|
||||||
|
|
||||||
UIView* getWindowOrParentView() const { return _windowOrView; }
|
UIView* getWindowOrParentView() const { return _windowOrView; }
|
||||||
|
|
||||||
|
bool getCreateTransparentView() { return _createTransparentView; }
|
||||||
|
void setCreateTransparentView(bool b) { _createTransparentView = b; }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UIView* _windowOrView;
|
UIView* _windowOrView;
|
||||||
DeviceOrientationFlags _deviceOrientationFlags;
|
DeviceOrientationFlags _deviceOrientationFlags;
|
||||||
float _viewContentScaleFactor;
|
float _viewContentScaleFactor;
|
||||||
|
bool _createTransparentView;
|
||||||
|
|
||||||
friend class GraphicsWindowIOS;
|
friend class GraphicsWindowIOS;
|
||||||
|
|
||||||
|
@ -2745,7 +2745,19 @@ Geometry* osg::createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVe
|
|||||||
geom->setNormalArray(normals);
|
geom->setNormalArray(normals);
|
||||||
geom->setNormalBinding(Geometry::BIND_OVERALL);
|
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));
|
geom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,4));
|
||||||
|
#endif
|
||||||
|
|
||||||
return geom;
|
return geom;
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,11 @@ IF(ASIO_FOUND)
|
|||||||
ADD_SUBDIRECTORY(RestHttpDevice)
|
ADD_SUBDIRECTORY(RestHttpDevice)
|
||||||
ENDIF(ASIO_FOUND)
|
ENDIF(ASIO_FOUND)
|
||||||
|
|
||||||
|
|
||||||
|
IF(ZEROCONF_FOUND)
|
||||||
|
ADD_SUBDIRECTORY(ZeroConfDevice)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
##########to get all the variables of Cmake
|
##########to get all the variables of Cmake
|
||||||
#GET_CMAKE_PROPERTY(MYVARS VARIABLES)
|
#GET_CMAKE_PROPERTY(MYVARS VARIABLES)
|
||||||
#FOREACH(myvar ${MYVARS})
|
#FOREACH(myvar ${MYVARS})
|
||||||
|
@ -132,11 +132,14 @@ void OSXCoreVideoTexture::apply(osg::State& state) const {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_adapter.valid()) {
|
if (!_adapter.valid()) {
|
||||||
OSXQTKitVideo* m = dynamic_cast<OSXQTKitVideo*>(_image.get());
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||||
if ((m) && (m->getCoreVideoAdapter()))
|
if (!_adapter.valid()) {
|
||||||
_adapter = m->getCoreVideoAdapter();
|
OSXQTKitVideo* m = dynamic_cast<OSXQTKitVideo*>(_image.get());
|
||||||
else
|
if ((m) && (m->getCoreVideoAdapter()))
|
||||||
_adapter = new OSXCoreVideoAdapter(state, _image.get());
|
_adapter = m->getCoreVideoAdapter();
|
||||||
|
else
|
||||||
|
_adapter = new OSXCoreVideoAdapter(state, _image.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_adapter->getFrame();
|
_adapter->getFrame();
|
||||||
|
@ -76,5 +76,6 @@ class OSXCoreVideoTexture : public osg::Texture {
|
|||||||
|
|
||||||
typedef osg::buffered_value<unsigned int> ImageModifiedCount;
|
typedef osg::buffered_value<unsigned int> ImageModifiedCount;
|
||||||
mutable ImageModifiedCount _modifiedCount;
|
mutable ImageModifiedCount _modifiedCount;
|
||||||
|
mutable OpenThreads::Mutex _mutex;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -13,22 +13,31 @@
|
|||||||
|
|
||||||
#include "RestHttpDevice.hpp"
|
#include "RestHttpDevice.hpp"
|
||||||
#include <OpenThreads/Thread>
|
#include <OpenThreads/Thread>
|
||||||
|
#include <osg/ValueObject>
|
||||||
#include <osgDB/FileUtils>
|
#include <osgDB/FileUtils>
|
||||||
#include "request_handler.hpp"
|
#include "request_handler.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StandardRequestHandler : public RestHttpDevice::RequestHandler {
|
class StandardRequestHandler : public RestHttpDevice::RequestHandler {
|
||||||
public:
|
public:
|
||||||
StandardRequestHandler() : RestHttpDevice::RequestHandler("") {}
|
StandardRequestHandler() : RestHttpDevice::RequestHandler("") {}
|
||||||
virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const Arguments& arguments, http::server::reply& reply)
|
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<osgGA::GUIEventAdapter> 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)
|
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
|
virtual void describeTo(std::ostream& out) const
|
||||||
@ -138,7 +147,10 @@ public:
|
|||||||
double time_stamp = getTimeStamp(arguments, reply);
|
double time_stamp = getTimeStamp(arguments, reply);
|
||||||
|
|
||||||
if (getDevice()->isNewer(time_stamp))
|
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);
|
return sendOkReply(reply);
|
||||||
@ -182,6 +194,7 @@ public:
|
|||||||
&& getIntArgument(arguments, "y", reply, y)
|
&& getIntArgument(arguments, "y", reply, y)
|
||||||
&& getIntArgument(arguments, "button", reply, button))
|
&& getIntArgument(arguments, "button", reply, button))
|
||||||
{
|
{
|
||||||
|
getDevice()->setTargetMousePosition(x,y, true);
|
||||||
switch (_mode) {
|
switch (_mode) {
|
||||||
case PRESS:
|
case PRESS:
|
||||||
getDevice()->getEventQueue()->mouseButtonPress(x,y, button, getLocalTime(arguments, reply));
|
getDevice()->getEventQueue()->mouseButtonPress(x,y, button, getLocalTime(arguments, reply));
|
||||||
@ -253,7 +266,9 @@ RestHttpDevice::RestHttpDevice(const std::string& listening_address, const std::
|
|||||||
, _firstEventRemoteTimeStamp(-1)
|
, _firstEventRemoteTimeStamp(-1)
|
||||||
, _lastEventRemoteTimeStamp(0)
|
, _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())
|
if (osgDB::findDataFile(doc_root).empty())
|
||||||
{
|
{
|
||||||
|
@ -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:
|
private:
|
||||||
void parseArguments(const std::string request_path, RequestHandler::Arguments& arguments);
|
void parseArguments(const std::string request_path, RequestHandler::Arguments& arguments);
|
||||||
@ -179,6 +198,7 @@ private:
|
|||||||
double _firstEventLocalTimeStamp;
|
double _firstEventLocalTimeStamp;
|
||||||
double _firstEventRemoteTimeStamp;
|
double _firstEventRemoteTimeStamp;
|
||||||
double _lastEventRemoteTimeStamp;
|
double _lastEventRemoteTimeStamp;
|
||||||
|
float _currentMouseX, _currentMouseY, _targetMouseX, _targetMouseY;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ connection::connection(asio::io_service& io_service,
|
|||||||
: socket_(io_service),
|
: socket_(io_service),
|
||||||
request_handler_(handler)
|
request_handler_(handler)
|
||||||
{
|
{
|
||||||
OSG_INFO << "RestHttpDevice :: connection::connection" << std::endl;
|
OSG_DEBUG << "RestHttpDevice :: connection::connection" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection::~connection()
|
connection::~connection()
|
||||||
{
|
{
|
||||||
OSG_INFO << "RestHttpDevice :: connection::~connection" << std::endl;
|
OSG_DEBUG << "RestHttpDevice :: connection::~connection" << std::endl;
|
||||||
}
|
}
|
||||||
asio::ip::tcp::socket& connection::socket()
|
asio::ip::tcp::socket& connection::socket()
|
||||||
{
|
{
|
||||||
@ -36,7 +36,7 @@ asio::ip::tcp::socket& connection::socket()
|
|||||||
|
|
||||||
void connection::start()
|
void connection::start()
|
||||||
{
|
{
|
||||||
OSG_INFO << "RestHttpDevice :: connection::start" << std::endl;
|
OSG_DEBUG << "RestHttpDevice :: connection::start" << std::endl;
|
||||||
|
|
||||||
socket_.async_read_some(asio::buffer(buffer_),
|
socket_.async_read_some(asio::buffer(buffer_),
|
||||||
boost::bind(&connection::handle_read, shared_from_this(),
|
boost::bind(&connection::handle_read, shared_from_this(),
|
||||||
|
@ -68,6 +68,10 @@ void request_handler::handle_request(const request& req, reply& rep)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OSG_INFO << "RestHttpDevice :: serving file " << full_path << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Fill out the reply to be sent to the client.
|
// Fill out the reply to be sent to the client.
|
||||||
rep.status = reply::ok;
|
rep.status = reply::ok;
|
||||||
|
@ -51,7 +51,7 @@ void server::handle_accept(const asio::error_code& e)
|
|||||||
{
|
{
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
OSG_INFO << "RestHttpDevice :: server::handle_accept" << std::endl;
|
OSG_DEBUG << "RestHttpDevice :: server::handle_accept" << std::endl;
|
||||||
new_connection_->start();
|
new_connection_->start();
|
||||||
new_connection_.reset(new connection(
|
new_connection_.reset(new connection(
|
||||||
io_service_pool_.get_io_service(), request_handler_));
|
io_service_pool_.get_io_service(), request_handler_));
|
||||||
|
@ -14,4 +14,4 @@ SET(TARGET_LIBRARIES_VARS AV_FOUNDATION_LIBRARY COCOA_LIBRARY COREVIDEO_LIBRARY
|
|||||||
SET(TARGET_ADDED_LIBRARIES osgViewer )
|
SET(TARGET_ADDED_LIBRARIES osgViewer )
|
||||||
|
|
||||||
#### end var setup ###
|
#### end var setup ###
|
||||||
SETUP_PLUGIN(AVFoundation)
|
SETUP_PLUGIN(avfoundation)
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <osg/Timer>
|
#include <osg/Timer>
|
||||||
#include "../QTKit/VideoFrameDispatcher.h"
|
#include "../QTKit/VideoFrameDispatcher.h"
|
||||||
|
|
||||||
@ -117,3 +115,4 @@ private:
|
|||||||
double _framerate;
|
double _framerate;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
#include "OSXAVFoundationVideo.h"
|
#include "OSXAVFoundationVideo.h"
|
||||||
|
|
||||||
#include <osgdB/FileNameUtils>
|
#include <osgdB/FileNameUtils>
|
||||||
#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
#import "TargetConditionals.h"
|
||||||
|
#if (TARGET_OS_IPHONE)
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#include <osgViewer/api/IOS/GraphicsWindowIOS>
|
||||||
|
#else
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
|
||||||
|
#endif
|
||||||
#include "OSXAVFoundationCoreVideoTexture.h"
|
#include "OSXAVFoundationCoreVideoTexture.h"
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +110,11 @@ public:
|
|||||||
OSXAVFoundationVideoDelegate* delegate;
|
OSXAVFoundationVideoDelegate* delegate;
|
||||||
std::vector<CVBufferRef> lastFrames;
|
std::vector<CVBufferRef> lastFrames;
|
||||||
int readFrameNdx, writeFrameNdx;
|
int readFrameNdx, writeFrameNdx;
|
||||||
|
#if (TARGET_OS_IPHONE)
|
||||||
|
CVOpenGLESTextureCacheRef coreVideoTextureCache;
|
||||||
|
#else
|
||||||
CVOpenGLTextureCacheRef coreVideoTextureCache;
|
CVOpenGLTextureCacheRef coreVideoTextureCache;
|
||||||
|
#endif
|
||||||
|
|
||||||
Data()
|
Data()
|
||||||
: avplayer(NULL)
|
: avplayer(NULL)
|
||||||
@ -157,7 +166,11 @@ public:
|
|||||||
|
|
||||||
if (coreVideoTextureCache)
|
if (coreVideoTextureCache)
|
||||||
{
|
{
|
||||||
|
#if (TARGET_OS_IPHONE)
|
||||||
|
CFRelease(coreVideoTextureCache); // huh, there's no CVOpenGLESTextureCacheRelease?
|
||||||
|
#else
|
||||||
CVOpenGLTextureCacheRelease(coreVideoTextureCache);
|
CVOpenGLTextureCacheRelease(coreVideoTextureCache);
|
||||||
|
#endif
|
||||||
coreVideoTextureCache = NULL;
|
coreVideoTextureCache = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,20 +429,30 @@ void OSXAVFoundationVideo::decodeFrame()
|
|||||||
if (isCoreVideoUsed())
|
if (isCoreVideoUsed())
|
||||||
{
|
{
|
||||||
CVPixelBufferLockBaseAddress(newframe, kCVPixelBufferLock_ReadOnly);
|
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 w = CVPixelBufferGetWidth(newframe);
|
||||||
int h = CVPixelBufferGetHeight(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);
|
_dimensionsChangedCallbackNeeded = (_s != w) || (_t != h);
|
||||||
_s = w; _t = h; _r = 1;
|
_s = w; _t = h; _r = 1;
|
||||||
|
|
||||||
_data->addFrame(texture);
|
|
||||||
|
|
||||||
CVPixelBufferUnlockBaseAddress(newframe, kCVPixelBufferLock_ReadOnly);
|
CVPixelBufferUnlockBaseAddress(newframe, kCVPixelBufferLock_ReadOnly);
|
||||||
CVPixelBufferRelease(newframe);
|
CVPixelBufferRelease(newframe);
|
||||||
}
|
}
|
||||||
@ -500,17 +523,29 @@ void OSXAVFoundationVideo::requestNewFrame()
|
|||||||
|
|
||||||
bool OSXAVFoundationVideo::getCurrentCoreVideoTexture(GLenum& target, GLint& name, int& width, int& height) const
|
bool OSXAVFoundationVideo::getCurrentCoreVideoTexture(GLenum& target, GLint& name, int& width, int& height) const
|
||||||
{
|
{
|
||||||
CVOpenGLTextureCacheFlush(_data->coreVideoTextureCache, 0);
|
#if (TARGET_OS_IPHONE)
|
||||||
CVOpenGLTextureRef texture = _data->getLastFrame();
|
CVOpenGLESTextureCacheFlush(_data->coreVideoTextureCache, 0);
|
||||||
if (texture)
|
CVOpenGLESTextureRef texture = _data->getLastFrame();
|
||||||
{
|
if(texture) {
|
||||||
target = CVOpenGLTextureGetTarget(texture);
|
target = GL_TEXTURE_2D;
|
||||||
name = CVOpenGLTextureGetName(texture);
|
name = CVOpenGLESTextureGetName(texture);
|
||||||
width = _s;
|
width = _s;
|
||||||
height = _t;
|
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);
|
return (texture != NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -518,25 +553,42 @@ void OSXAVFoundationVideo::lazyInitCoreVideoTextureCache(osg::State& state)
|
|||||||
{
|
{
|
||||||
if (_data->coreVideoTextureCache)
|
if (_data->coreVideoTextureCache)
|
||||||
return;
|
return;
|
||||||
|
#if (TARGET_OS_IPHONE)
|
||||||
osgViewer::GraphicsWindowCocoa* win = dynamic_cast<osgViewer::GraphicsWindowCocoa*>(state.getGraphicsContext());
|
osgViewer::GraphicsWindowIOS* win = dynamic_cast<osgViewer::GraphicsWindowIOS*>(state.getGraphicsContext());
|
||||||
if (win)
|
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;
|
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<osgViewer::GraphicsWindowCocoa*>(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()
|
osg::Texture* OSXAVFoundationVideo::createSuitableTexture()
|
||||||
{
|
{
|
||||||
return NULL; // new OSXAVFoundationCoreVideoTexture(this);
|
#if (TARGET_OS_IPHONE)
|
||||||
|
return new OSXAVFoundationCoreVideoTexture(this);
|
||||||
|
#else
|
||||||
|
return NULL; // new OSXAVFoundationCoreVideoTexture(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,14 +11,23 @@
|
|||||||
* OpenSceneGraph Public License for more details.
|
* 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 "OSXAVFoundationCoreVideoTexture.h"
|
||||||
#include "OSXAVFoundationVideo.H"
|
#include "OSXAVFoundationVideo.H"
|
||||||
#include <CoreVideo/CoreVideo.h>
|
#include <CoreVideo/CoreVideo.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture()
|
OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture()
|
||||||
: osg::Texture()
|
: osg::Texture()
|
||||||
, _textureTarget(GL_TEXTURE_RECTANGLE_EXT)
|
, _textureTarget(COREVIDEO_TEXTURE_TARGET)
|
||||||
, _textureWidth(0)
|
, _textureWidth(0)
|
||||||
, _textureHeight(0)
|
, _textureHeight(0)
|
||||||
, _inited(false)
|
, _inited(false)
|
||||||
@ -28,7 +37,7 @@ OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture()
|
|||||||
|
|
||||||
OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture(osg::Image* image)
|
OSXAVFoundationCoreVideoTexture::OSXAVFoundationCoreVideoTexture(osg::Image* image)
|
||||||
: osg::Texture()
|
: osg::Texture()
|
||||||
, _textureTarget(GL_TEXTURE_RECTANGLE_EXT)
|
, _textureTarget(COREVIDEO_TEXTURE_TARGET)
|
||||||
, _textureWidth(0)
|
, _textureWidth(0)
|
||||||
, _textureHeight(0)
|
, _textureHeight(0)
|
||||||
, _inited(false)
|
, _inited(false)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include <osg/Texture>
|
#include <osg/Texture>
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,8 +104,11 @@ class ReaderWriterAVFoundation : public osgDB::ReaderWriter
|
|||||||
if (!video || !use_core_video)
|
if (!video || !use_core_video)
|
||||||
return rr;
|
return rr;
|
||||||
|
|
||||||
osg::ref_ptr<OSXAVFoundationCoreVideoTexture> texture = new OSXAVFoundationCoreVideoTexture(video);
|
osg::ref_ptr<osg::Texture> texture = video->createSuitableTexture();
|
||||||
return texture.release();
|
if (texture.valid())
|
||||||
|
return texture.release();
|
||||||
|
|
||||||
|
return video.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -117,4 +120,4 @@ class ReaderWriterAVFoundation : public osgDB::ReaderWriter
|
|||||||
|
|
||||||
// now register with Registry to instantiate the above
|
// now register with Registry to instantiate the above
|
||||||
// reader/writer.
|
// reader/writer.
|
||||||
REGISTER_OSGPLUGIN(AVFoundation, ReaderWriterAVFoundation)
|
REGISTER_OSGPLUGIN(avfoundation, ReaderWriterAVFoundation)
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
SET(TARGET_SRC ReaderWriterImageIO.cpp )
|
||||||
SET(TARGET_SRC ReaderWriterImageIO_IOS.cpp )
|
|
||||||
ELSE()
|
|
||||||
SET(TARGET_SRC ReaderWriterImageIO.cpp )
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (APPLE)
|
IF (APPLE)
|
||||||
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
IF(OSG_BUILD_PLATFORM_IPHONE OR OSG_BUILD_PLATFORM_IPHONE_SIMULATOR)
|
||||||
# compile FileUtils.cpp as objective-c++
|
# 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++"
|
PROPERTIES COMPILE_FLAGS "-x objective-c++"
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -18,14 +18,24 @@
|
|||||||
// probably especially important for istream which lacks extension information.
|
// probably especially important for istream which lacks extension information.
|
||||||
// Is there information we can use in the OSG options parameter?
|
// Is there information we can use in the OSG options parameter?
|
||||||
|
|
||||||
// For ImageIO framework and also LaunchServices framework (for UTIs)
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#import "TargetConditionals.h"
|
||||||
|
#if (TARGET_OS_IPHONE)
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <ImageIO/ImageIO.h>
|
||||||
|
#import <CoreGraphics/CoreGraphics.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <MobileCoreServices/MobileCoreServices.h>
|
||||||
|
#else
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#endif
|
||||||
// For the vImage framework (part of the Accerlate framework)
|
// For the vImage framework (part of the Accerlate framework)
|
||||||
#include <Accelerate/Accelerate.h>
|
#include <Accelerate/Accelerate.h>
|
||||||
|
|
||||||
// Used because CGDataProviderCreate became deprecated in 10.5
|
// Used because CGDataProviderCreate became deprecated in 10.5
|
||||||
#include <AvailabilityMacros.h>
|
#include <AvailabilityMacros.h>
|
||||||
|
|
||||||
|
|
||||||
#include <osg/GL>
|
#include <osg/GL>
|
||||||
#include <osg/Notify>
|
#include <osg/Notify>
|
||||||
#include <osg/Image>
|
#include <osg/Image>
|
||||||
|
@ -1,572 +0,0 @@
|
|||||||
#include <osg/GL>
|
|
||||||
#include <osg/Notify>
|
|
||||||
#include <osg/Image>
|
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
|
||||||
#include <osgDB/FileNameUtils>
|
|
||||||
#include <osgDB/FileUtils>
|
|
||||||
|
|
||||||
#include <sstream> // for istream
|
|
||||||
#include <iostream> // for ios::
|
|
||||||
|
|
||||||
#import <UIKit/UIImage.h>
|
|
||||||
#import <CoreGraphics/CoreGraphics.h>
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <ImageIO/CGImageSource.h>
|
|
||||||
|
|
||||||
/**************************************************************
|
|
||||||
***** 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<int>(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<int>(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)
|
|
@ -60,7 +60,7 @@
|
|||||||
using namespace osgPresentation;
|
using namespace osgPresentation;
|
||||||
|
|
||||||
#define USE_CLIENT_STORAGE_HINT 0
|
#define USE_CLIENT_STORAGE_HINT 0
|
||||||
#define USE_TEXTURE_FROM_VIDEO_PLUGIN 1
|
|
||||||
|
|
||||||
class SetToTransparentBin : public osg::NodeVisitor
|
class SetToTransparentBin : public osg::NodeVisitor
|
||||||
{
|
{
|
||||||
@ -857,12 +857,10 @@ osg::Geometry* SlideShowConstructor::createTexturedQuadGeometry(const osg::Vec3&
|
|||||||
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image);
|
osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image);
|
||||||
|
|
||||||
// let the video-plugin create a texture for us, if supported
|
// let the video-plugin create a texture for us, if supported
|
||||||
#if USE_TEXTURE_FROM_VIDEO_PLUGIN
|
if(imageStream && getenv("P3D_ENABLE_CORE_VIDEO"))
|
||||||
if(imageStream)
|
|
||||||
{
|
{
|
||||||
texture = imageStream->createSuitableTexture();
|
texture = imageStream->createSuitableTexture();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
bool flipYAxis = image->getOrigin()==osg::Image::TOP_LEFT;
|
bool flipYAxis = image->getOrigin()==osg::Image::TOP_LEFT;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user