SO3Engine
SO3BitmapWidget.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
36#include "SO3Renderer/SO3Root.h"
39#include <OgreBitwise.h>
40
41namespace SO3
42{
43SBitmapWidget::SBitmapWidget(SScene* targetScene, const std::string& bitmapWidgetName, const int& xPos, const int& yPos, const unsigned short& widgetWidth, const unsigned short& widgetHeight, SViewPort* targetViewport, const unsigned int& widgetZOrder) : SWidget(targetScene, bitmapWidgetName, xPos, yPos, widgetWidth, widgetHeight, targetViewport, widgetZOrder, SO3_BITMAP_WIDGET_TYPE)
44{
46}
47
48SBitmapWidget::SBitmapWidget(SScene* targetScene, const std::string& bitmapWidgetName, const int& xPos, const int& yPos, const unsigned short& widgetWidth, const unsigned short& widgetHeight, SViewPort* targetViewport) : SWidget(targetScene, bitmapWidgetName, xPos, yPos, widgetWidth, widgetHeight, targetViewport, SO3_BITMAP_WIDGET_TYPE)
49{
51}
52
53SBitmapWidget::SBitmapWidget(SScene* targetScene, const std::string& bitmapWidgetName, const unsigned short& widgetWidth, const unsigned short& widgetHeight, SMaterial* targetMaterial, const unsigned short& targetTechnique, const unsigned short& targetPass, const unsigned short& targetTextureUnit) : SWidget(targetScene, bitmapWidgetName, widgetWidth, widgetHeight, targetMaterial, targetTechnique, targetPass, targetTextureUnit, SO3_BITMAP_WIDGET_TYPE)
54{
56}
57
59{
60 iLastWidth = 0;
61 iLastHeight = 0;
62 pixelsData = 0;
63 bLastAlphaState = false;
64}
65
67{
68 if (pixelsData)
69 SAFE_FREE(pixelsData);
70}
71
72void SBitmapWidget::LoadURL(const std::string& url)
73{
74 // Throw exception, catch in scol bind, and return nil.
76 OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, "Cannot directly load an URL in a Bitmap widget, use \"UpdateRawData\" function!", "SBitmapWidget::LoadURL");
77}
78
79void SBitmapWidget::LoadFile(const std::string& file)
80{
81 // Throw exception, catch in scol bind, and return nil.
83 OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, "Cannot load a file directly in a Bitmap widget, use \"UpdateRawData\" function!", "SBitmapWidget::LoadFile");
84}
85
86void SBitmapWidget::UpdateRawData(unsigned char* buffer, int width, int height, int bitperpixel)
87{
88 // only on rgb or rgba
89 if (bitperpixel < 3)
90 return;
91
92 // Test if the scolBitmap is valid
93 if ((width > 0) && (height > 0))
94 {
95 CheckSizeAndAlloc(width, height, (bitperpixel == 4) ? true : false);
96
98 {
99 MMechostr(MSKDEBUG, ">>>> SBitmapWidget : Texture creation failed.");
100 return;
101 }
102
103 // Lock the pixel buffer and get a pixel box
104 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
105
107
108 int align = width * bitperpixel;
109 //if (align % 4 != 0)
110 // align += 4 - (align % 4);
111 //bool aligned = (align == (bitperpixel * width)) ? true : false;
112
113 if ((pixelBuffer->getWidth() == width) && ((pixelBuffer->getHeight() == height)))// && aligned)
114 {
115 memcpy(pixelsData, buffer, width * height * bitperpixel);
116
117 // Create an Ogre pixel box with our scol bitmap data for easy streching.
118 /*
119 Ogre::PixelFormat format = Ogre::PF_A8R8G8B8;
120 SRoot::getSingleton().GetRttPixelFormat(format, (bitperpixel == 4) ? true : false);
121 const Ogre::PixelBox scolPixelBox(width, height, 1, format, pixelsData);
122 */
123 const Ogre::PixelBox scolPixelBox(width, height, 1, (bitperpixel == 4) ? Ogre::PF_BYTE_BGRA : Ogre::PF_BYTE_BGR, pixelsData);
124 pixelBuffer->blitFromMemory(scolPixelBox);
125 }
126 else
127 {
128#ifdef APPLE_IOS
129 const Ogre::PixelBox scolPixelBox(width, height, 1, (bitperpixel == 4) ? Ogre::PF_BYTE_BGRA : Ogre::PF_BYTE_BGR, buffer);
130#else
131 ConversionTools::ScolBitmapGetRGBA(buffer, width, height, bitperpixel, align, pixelBuffer->getWidth(), pixelBuffer->getHeight(), pixelBuffer->getFormat(), static_cast<Ogre::uint32*>(pixelsData));
132
133 // Create an Ogre pixel box with our scol bitmap data for easy streching.
134 const Ogre::PixelBox scolPixelBox(pixelBuffer->getWidth(), pixelBuffer->getHeight(), 1, pixelBuffer->getFormat(), pixelsData);
135#endif
136 pixelBuffer->blitFromMemory(scolPixelBox);
137 }
138
140 }
141}
142
143void SBitmapWidget::UpdateRawData(PtrObjBitmap scolBitmap)
144{
145 // Test if the scolBitmap is valid
146 if((scolBitmap->TailleW > 0) && (scolBitmap->TailleH > 0))
147 {
148 CheckSizeAndAlloc(scolBitmap->TailleW, scolBitmap->TailleH, false);
149
150 if (!renderingTexture)
151 {
152 MMechostr(MSKDEBUG, ">>>> SBitmapWidget : Texture creation failed.");
153 return;
154 }
155
156 // Lock the pixel buffer and get a pixel box
157 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
158
160
161 // copy last bitmap state
162 ConversionTools::ScolBitmapGetRGBA(scolBitmap, 0, pixelBuffer->getWidth(), pixelBuffer->getHeight(), pixelBuffer->getFormat(), static_cast<Ogre::uint32*>(pixelsData));
163
164 // Create an Ogre pixel box with our scol bitmap data for easy streching.
165 const Ogre::PixelBox scolPixelBox(pixelBuffer->getWidth(), pixelBuffer->getHeight(), 1, pixelBuffer->getFormat(), pixelsData);
166 pixelBuffer->blitFromMemory(scolPixelBox);
167
169 }
170}
171
172void SBitmapWidget::UpdateRawData(PtrObjBitmap scolBitmap, PtrObjBitmap scolAlphaBitmap)
173{
174 if (scolAlphaBitmap == 0)
175 {
176 UpdateRawData(scolBitmap);
177 return;
178 }
179
180 // Test if the scolBitmap is valid
181 if((scolBitmap->TailleW > 0) && (scolBitmap->TailleH > 0))
182 {
183 CheckSizeAndAlloc(scolBitmap->TailleW, scolBitmap->TailleH, true);
184
185 if (!renderingTexture)
186 {
187 MMechostr(MSKDEBUG, ">>>> SBitmapWidget : Texture creation failed.");
188 return;
189 }
190
191 // Lock the pixel buffer and get a pixel box
192 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
193
195
196 // copy last bitmap state
197 ConversionTools::ScolBitmapGetRGBA(scolBitmap, scolAlphaBitmap, pixelBuffer->getWidth(), pixelBuffer->getHeight(), pixelBuffer->getFormat(), static_cast<Ogre::uint32*>(pixelsData));
198 // Create an Ogre pixel box with our scol bitmap data for easy streching.
199 const Ogre::PixelBox scolPixelBox(pixelBuffer->getWidth(), pixelBuffer->getHeight(), 1, pixelBuffer->getFormat(), pixelsData);
200 pixelBuffer->blitFromMemory(scolPixelBox);
201
203 }
204}
205
206void SBitmapWidget::InjectMouseMove(const int& xPos, const int& yPos, const MouseButtonId& button)
207{
208 // Nothing to do
209}
210
211void SBitmapWidget::InjectMouseWheel(const int& scrollX, const int& scrollY, const int& relativeScroll)
212{
213 // Nothing to do
214}
215
216void SBitmapWidget::InjectMouseDown(const int& xPos, const int& yPos, const MouseButtonId& button)
217{
218 // Nothing to do
219}
220
221void SBitmapWidget::InjectMouseUp(const int& xPos, const int& yPos, const MouseButtonId& button)
222{
223 // Nothing to do
224}
225
226void SBitmapWidget::InjectTouchAdd(const int& xPos, const int& yPos, const int& touchid)
227{
228 // Nothing to do
229}
230
231void SBitmapWidget::InjectTouchRemove(const int& touchid)
232{
233 // Nothing to do
234}
235
236void SBitmapWidget::InjectTouchUpdate(const int& xPos, const int& yPos, const int& vx, const int& vy, const int& touchid)
237{
238 // Nothing to do
239}
240
241void SBitmapWidget::InjectKeyEvent(const UINT& msg, const ScolWindowHandle& hwnd, const WPARAM& wParam, const LPARAM& lParam)
242{
243 // Nothing to do
244}
245
246void SBitmapWidget::InjectTextEvent(const std::string& utf8)
247{
248 // Nothing to do
249}
250
251void SBitmapWidget::SetFocusImpl(const bool& focusOnWidget)
252{
253 // Nothing to do
254}
255
256void SBitmapWidget::SetTransparencyImpl(const bool& enableTransparency)
257{
258 // Nothing to do
259}
260void SBitmapWidget::RunScriptFunction(const std::string& functionName, const std::vector<std::string>& argumentList)
261{
262 // Nothing to do, no script for bitmap!
263}
264
265void SBitmapWidget::SetKeyboardEnableImpl(const bool& enableKeyboardOnWidget)
266{
267 // Nothing to do
268}
269
270void SBitmapWidget::SetMouseEnableImpl(const bool& enableMouseOnWidget)
271{
272 // Nothing to do
273}
274
275void SBitmapWidget::SetSizeImpl(const unsigned short& newWidth, const unsigned short& newHeight)
276{
277 CheckSizeAndAlloc(newWidth, newHeight, bLastAlphaState);
278}
279
280bool SBitmapWidget::CheckPixelAlpha(const int& posX, const int& posY)
281{
282 bool result = false;
283 if ((mTextureWidth > 0) && (mTextureHeight > 0) && (width > 0) && (height > 0))
284 {
285 int nxpos = static_cast<int>((float)posX / (float)width * (float)mTextureWidth);
286 int nypos = static_cast<int>((float)posY / (float)height * (float)mTextureHeight);
287 if((nxpos < mTextureWidth) && (nypos < mTextureHeight))
288 {
289 if(bLastAlphaState)
290 {
291 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
292 pixelBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
293 Ogre::PixelBox pixelBox = pixelBuffer->getCurrentLock();
294
295 Ogre::ColourValue tempColor = pixelBox.getColourAt(nxpos, nypos, 0);
296 if (tempColor.a > transparentTresholdColor)
297 result = true;
298
299 pixelBuffer->unlock();
300 }
301 else
302 {
303 result = true;
304 }
305 }
306 }
307 return result;
308}
309
310void SBitmapWidget::CheckSizeAndAlloc(const unsigned int& newWidth, const unsigned int& newHeight, const bool& alpha)
311{
312 unsigned short nCalcTexWidth = 0;
313 unsigned short nCalcTexHeight = 0;
314 if (compensateNPOT)
315 {
316 nCalcTexWidth = Ogre::Bitwise::firstPO2From(static_cast <unsigned short>(newWidth * textureRatio));
317 nCalcTexHeight = Ogre::Bitwise::firstPO2From(static_cast <unsigned short>(newHeight * textureRatio));
318
319#if defined(ANDROID) || defined(APPLE_IOS)
320 if (nCalcTexWidth > 512 || nCalcTexHeight > 512)
321 {
322 nCalcTexWidth = nCalcTexWidth / 2;
323 nCalcTexHeight = nCalcTexHeight / 2;
324 }
325#endif
326 }
327 else
328 {
329 nCalcTexWidth = static_cast <unsigned short>(newWidth * textureRatio);
330 nCalcTexHeight = static_cast <unsigned short>(newHeight * textureRatio);
331 }
332
333 if ((nCalcTexWidth != iLastWidth) || (nCalcTexHeight != iLastHeight) || (alpha != bLastAlphaState))
334 {
335 mTextureWidth = newWidth;
336 mTextureHeight = newHeight;
337
338 if (pixelsData)
339 SAFE_FREE(pixelsData);
340
341 CreateTexture(alpha);
342
343 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
344
345 iLastWidth = pixelBuffer->getWidth();
346 iLastHeight = pixelBuffer->getHeight();
347 bLastAlphaState = alpha;
348
349 //MMechostr(MSKDEBUG, ">>>> SBitmapWidget Bitmap size: %ix%i\n", newWidth, newHeight);
350
351 int size = sizeof(Ogre::uint32*); // (alpha) ? 4 : 3;
352 pixelsData = (void*)malloc(iLastWidth * iLastHeight * size);
353 }
354}
355
356void SBitmapWidget::loadResource(Ogre::Resource* resource)
357{
358 /*Ogre::Texture* tex = static_cast<Ogre::Texture*>(resource);
359 tex->setTextureType(Ogre::TEX_TYPE_2D);
360 tex->setWidth(mTextureWidth);
361 tex->setHeight(mTextureHeight);
362 tex->setNumMipmaps(0);
363 tex->setFormat(Ogre::PF_BYTE_BGRA);
364 tex->setUsage(Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
365 tex->createInternalResources();
366 */
367 if(pixelsData)
368 {
369 Ogre::HardwarePixelBufferSharedPtr pixelBuffer = renderingTexture->getBuffer();
370
371 // Create an Ogre pixel box with our scol bitmap data for easy streching.
372 const Ogre::PixelBox scolPixelBox(iLastWidth, iLastHeight, 1, pixelBuffer->getFormat(), pixelsData);
373 pixelBuffer->blitFromMemory(scolPixelBox);
374
375 /*
376 pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
377 const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
378
379 // Streching scolBitmap data to Ogre texture size. Nb that the scale function takes an optional filter parameter if we wants other filtering than bilinear
380 try
381 {
382 Ogre::Image::scale(scolPixelBox, pixelBox);
383 }
384 catch(Ogre::Exception &e)
385 {
386 MMechostr(MSKRUNTIME, "Error on bitmap ressource: %s\n", e.what());
387 }
388
389 // No mipmap generation with widget.
390 pixelBuffer->unlock();
391 */
392 }
393
395}
396
397}
unsigned int UINT
Definition SO3Android.h:58
MMechostr(MSKDEBUG, " > Start loading Plugin SO3Engine dll\n")
static void ScolBitmapGetRGBA(PtrObjBitmap scolBitmap, PtrObjBitmap alphaBitmap, const Ogre::PixelBox &pixelbox)
virtual void SetKeyboardEnableImpl(const bool &enableKeyboardOnWidget)
virtual void SetMouseEnableImpl(const bool &enableMouseOnWidget)
virtual void SetFocusImpl(const bool &focusOnWidget)
virtual void InjectTouchUpdate(const int &xPos, const int &yPos, const int &vx, const int &vy, const int &touchid)
virtual void RunScriptFunction(const std::string &functionName, const std::vector< std::string > &argumentList)
virtual void LoadFile(const std::string &file)
virtual void InjectMouseWheel(const int &scrollX, const int &scrollY, const int &relativeScroll)
virtual void loadResource(Ogre::Resource *resource)
virtual void InjectTouchRemove(const int &touchid)
virtual void InjectTouchAdd(const int &xPos, const int &yPos, const int &touchid)
virtual void InjectMouseMove(const int &xPos, const int &yPos, const MouseButtonId &button)
virtual void LoadURL(const std::string &url)
SBitmapWidget(SScene *targetScene, const std::string &bitmapWidgetName, const int &xPos, const int &yPos, const unsigned short &widgetWidth, const unsigned short &widgetHeight, SViewPort *targetViewport, const unsigned int &widgetZOrder)
virtual void InjectMouseDown(const int &xPos, const int &yPos, const MouseButtonId &button)
virtual void SetSizeImpl(const unsigned short &newWidth, const unsigned short &newHeight)
virtual void InjectTextEvent(const std::string &utf8)
virtual void InjectMouseUp(const int &xPos, const int &yPos, const MouseButtonId &button)
virtual bool CheckPixelAlpha(const int &posX, const int &posY)
void UpdateRawData(PtrObjBitmap scolBitmap)
virtual void SetTransparencyImpl(const bool &enableTransparency)
virtual void InjectKeyEvent(const UINT &msg, const ScolWindowHandle &hwnd, const WPARAM &wParam, const LPARAM &lParam)
bool forceRenderingUpdate
Definition SO3Widget.h:89
float transparentTresholdColor
Definition SO3Widget.h:90
unsigned short width
Definition SO3Widget.h:80
Ogre::TexturePtr renderingTexture
Definition SO3Widget.h:88
unsigned short height
Definition SO3Widget.h:81
unsigned short mTextureWidth
The actual texture width allocated in ogre.
Definition SO3Widget.h:82
bool compensateNPOT
Use to indicate if the texture size has be rounded to an exact pow2.
Definition SO3Widget.h:91
float textureRatio
Texture ratio compared to widget size, usually 1.0.
Definition SO3Widget.h:84
unsigned short mTextureHeight
The actual texture height allocated in ogre.
Definition SO3Widget.h:83
void CreateTexture(bool alpha=true)
void _FireOnLoadStart(SWidget *targetedWidget)
void _FireOnLoadError(SWidget *targetedWidget, const int &errorCode, const std::string &failedUrl)
void _FireOnLoadEnd(SWidget *targetedWidget)
static SWidgetManager & getSingleton()