SO3Engine
SO3ScreenshotManager.cpp
Go to the documentation of this file.
1
14
15#include "OgreMemoryAllocatorConfig.h"
16
17namespace SO3
18{
19 SScreenshotManager::SScreenshotManager()
20 {
21 // Forbiden constructor (private).
22 }
23
24 SScreenshotManager::SScreenshotManager(SViewPort* viewport, unsigned int width, unsigned int height, bool withOverlays, bool transparentBackground)
25 {
26 mViewport = viewport;
27 mDestWidth = width;
28 mDestHeight = height;
29 mEnableOverlays = withOverlays;
30 mTransparentBackground = transparentBackground;
31
32 mWindowWidth = mViewport->GetWidthPixels();
33 mWindowHeight = mViewport->GetHeightPixels();
34 mWidthGridSize = (((float)width / (float)mWindowWidth) > (width / mWindowWidth)) ? (width / mWindowWidth) + 1 : (width / mWindowWidth);
35 mHeightGridSize = (((float)height / (float)mWindowHeight) > (height / mWindowHeight)) ? (height / mWindowHeight) + 1 : (height / mWindowHeight);
36
37 //temp texture with current screensize
38 Ogre::PixelFormat pformat = (mTransparentBackground) ? Ogre::PF_B8G8R8A8 : Ogre::PF_B8G8R8;
39 mTempTex = Ogre::TextureManager::getSingleton().createManual(mViewport->GetCamera()->GetName() + "/ScreenShotTex", SO3_INTERNAL_RESOURCE_GROUP, Ogre::TEX_TYPE_2D, mWindowWidth, mWindowHeight, 0, pformat, Ogre::TU_RENDERTARGET, 0, false, 4);
40
41 mRT = mTempTex->getBuffer()->getRenderTarget();
42 mBuffer = mTempTex->getBuffer();
43
44 mData = new uint8[(mWindowWidth * mWidthGridSize) * (mWindowHeight * mHeightGridSize) * Ogre::PixelUtil::getNumElemBytes(mRT->suggestPixelFormat())];
45 mFinalPicturePB = Ogre::PixelBox(mWindowWidth * mWidthGridSize, mWindowHeight * mHeightGridSize, 1, mRT->suggestPixelFormat(), mData);
46 }
47
49 {
50 if (mData)
51 delete[] mData;
52
53 if (mTempTex)
54 {
55 Ogre::TextureManager::getSingleton().remove(mTempTex->getHandle());
56 mTempTex.reset();
57 }
58 }
59
60 void SScreenshotManager::MakeScreenshot(std::string filename)
61 {
62 SWindow* cwindow = mViewport->GetParentWindow();
63 StereoManager::StereoMode stereoMode = cwindow->GetStereoMode();
64 if (stereoMode != StereoManager::SO3_NONE_STEREO)
66
67 //Remove all viewports, so the added Viewport(camera) ist the only
68 Ogre::Camera* camera = mViewport->GetCamera()->GetOgreCameraPointer();
69 mRT->removeAllViewports();
70 mRT->addViewport(camera);
71
72 Ogre::Vector2 foffset = camera->getFrustumOffset();
73 Ogre::Real lodBias = camera->getLodBias();
74 bool bmatrix = camera->isCustomProjectionMatrixEnabled();
75 Ogre::Matrix4 cmatrix = camera->getProjectionMatrix();
76 bool autoRatio = camera->getAutoAspectRatio();
77 float prevRatio = camera->getAspectRatio();
78 camera->setAspectRatio((float)mDestWidth / (float)mDestHeight);
79 camera->setFrustumOffset(Ogre::Vector2(0.0f, 0.0f));
80 camera->setLodBias(10.0f);
81 camera->setCustomProjectionMatrix(false);
82
83 //set the viewport settings
84 Ogre::Viewport *vp = mRT->getViewport(0);
85 vp->setClearEveryFrame(true);
86
87 Ogre::ColourValue bgcolor = (mTransparentBackground) ? Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f) : mViewport->GetOgreViewPortPointer()->getBackgroundColour();
88 vp->setBackgroundColour(bgcolor);
89 vp->setOverlaysEnabled(mEnableOverlays);
90 vp->setMaterialScheme(mViewport->GetMaterialScheme());
91
92 if (mWidthGridSize <= 1 && mHeightGridSize <= 1)
93 {
94 // Simple case where the contents of the screen are taken directly
95 // Also used when an invalid value is passed within gridSize (zero or negative grid size)
96 mRT->update();
97
98 Ogre::PixelBox pb(mWindowWidth, mWindowHeight, 1, mRT->suggestPixelFormat());
99 pb.data = new uint8[pb.getConsecutiveSize()];
100 mRT->copyContentsToMemory(pb, pb);
101
102 Ogre::PixelBox sizedImage = Ogre::PixelBox(mDestWidth, mDestHeight, 1, mRT->suggestPixelFormat());
103 sizedImage.data = new uint8[sizedImage.getConsecutiveSize()];
104 Ogre::Image::scale(pb, sizedImage);
105
106 Ogre::Image finalImage;
107 finalImage.loadDynamicImage(static_cast<unsigned char*>(sizedImage.data), sizedImage.getWidth(), sizedImage.getHeight(), mRT->suggestPixelFormat());
108
109 //write the file on the Harddisk
110 finalImage.save(filename);
111 delete[] pb.data;
112 delete[] sizedImage.data;
113 }
114 else
115 {
116 // do not repeat overlays
117 vp->setOverlaysEnabled(false);
118
119 // set the original Frustum extents
120 Ogre::RealRect originalFrustum = camera->getFrustumExtents();
121
122 // compute the Stepsize for the drid
123 Ogre::Real frustumGridStepHorizontal = (originalFrustum.right * 2) / mWidthGridSize;
124 Ogre::Real frustumGridStepVertical = (originalFrustum.top * 2) / mHeightGridSize;
125
126 // process each grid
127 Ogre::Real frustumLeft, frustumRight, frustumTop, frustumBottom;
128
129 for (unsigned int y = 0; y < mHeightGridSize; y++)
130 {
131 for (unsigned int x = 0; x < mWidthGridSize; x++)
132 {
133 // compute the new frustum extents
134 frustumLeft = originalFrustum.left + frustumGridStepHorizontal * x;
135 frustumRight = frustumLeft + frustumGridStepHorizontal;
136 frustumTop = originalFrustum.top - frustumGridStepVertical * y;
137 frustumBottom = frustumTop - frustumGridStepVertical;
138
139 // set the frustum extents value to the camera
140 camera->setFrustumExtents(frustumLeft, frustumRight, frustumTop, frustumBottom);
141
142 // ignore time duration between frames
143 SRoot::getSingletonPtr()->GetOgreRootPointer()->clearEventTimes();
144 mRT->update();//render
145
146 //define the current
147 Ogre::Box subBox = Ogre::Box(x * mWindowWidth, y * mWindowHeight, x * mWindowWidth + mWindowWidth, y * mWindowHeight + mWindowHeight);
148
149 //copy the content from the temp buffer into the final picture PixelBox
150 //Place the tempBuffer content at the right position
151 mBuffer->blitToMemory(mFinalPicturePB.getSubVolume(subBox));
152 }
153 }
154
155 // set frustum extents to previous settings
156 camera->resetFrustumExtents();
157
158 //insert the PixelBox data into the Image Object
159 Ogre::PixelBox sizedImage = Ogre::PixelBox(mDestWidth, mDestHeight, 1, mRT->suggestPixelFormat());
160 sizedImage.data = new uint8[sizedImage.getConsecutiveSize()];
161 Ogre::Image::scale(mFinalPicturePB, sizedImage);
162
163 Ogre::Image finalImage;
164 finalImage.loadDynamicImage(static_cast<unsigned char*>(sizedImage.data), sizedImage.getWidth(), sizedImage.getHeight(), mRT->suggestPixelFormat());
165 // Save the Final image to a file
166 finalImage.save(filename);
167 delete[] sizedImage.data;
168 }
169
170 //restore auto ratio
171 camera->setAutoAspectRatio(autoRatio);
172 camera->setAspectRatio(prevRatio);
173 camera->setFrustumOffset(foffset);
174 camera->setLodBias(lodBias);
175 camera->setCustomProjectionMatrix(bmatrix, cmatrix);
176
177 // reset time since last frame to pause the scene
178 SRoot::getSingletonPtr()->GetOgreRootPointer()->clearEventTimes();
179
180 if (stereoMode != StereoManager::SO3_NONE_STEREO)
181 cwindow->SetStereoMode(stereoMode);
182 }
183
184}
Ogre::Camera * GetOgreCameraPointer()
Definition SO3Camera.cpp:50
std::string GetName() const
Ogre::Root * GetOgreRootPointer()
Definition SO3Root.cpp:301
static SRoot * getSingletonPtr()
Definition SO3Root.cpp:111
void MakeScreenshot(std::string filename)
SCamera * GetCamera()
SWindow * GetParentWindow() const
Ogre::Viewport * GetOgreViewPortPointer()
std::string GetMaterialScheme()
StereoManager::StereoMode GetStereoMode()
void SetStereoMode(const StereoManager::StereoMode &stereoMode)