| 1 | |
|---|
| 2 | |
|---|
| 3 | #include <osg/io_utils> |
|---|
| 4 | #include <osgDB/ReadFile> |
|---|
| 5 | #include <osgWidget/WindowManager> |
|---|
| 6 | #include <osgWidget/Frame> |
|---|
| 7 | #include <cassert> |
|---|
| 8 | |
|---|
| 9 | namespace osgWidget { |
|---|
| 10 | |
|---|
| 11 | std::string Frame::cornerTypeToString(CornerType c) |
|---|
| 12 | { |
|---|
| 13 | if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft"; |
|---|
| 14 | |
|---|
| 15 | else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight"; |
|---|
| 16 | |
|---|
| 17 | else if(c == CORNER_UPPER_RIGHT) return "CornerUpperRight"; |
|---|
| 18 | |
|---|
| 19 | else return "CornerUpperLeft"; |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | std::string Frame::borderTypeToString(BorderType b) |
|---|
| 23 | { |
|---|
| 24 | if(b == BORDER_LEFT) return "BorderLeft"; |
|---|
| 25 | |
|---|
| 26 | else if(b == BORDER_RIGHT) return "BorderRight"; |
|---|
| 27 | |
|---|
| 28 | else if(b == BORDER_TOP) return "BorderTop"; |
|---|
| 29 | |
|---|
| 30 | else return "BorderBottom"; |
|---|
| 31 | } |
|---|
| 32 | |
|---|
| 33 | Frame::Corner::Corner(CornerType corner, point_type width, point_type height): |
|---|
| 34 | Widget (cornerTypeToString(corner), width, height), |
|---|
| 35 | _corner (corner) |
|---|
| 36 | { |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | Frame::Corner::Corner(const Corner& corner, const osg::CopyOp& co): |
|---|
| 40 | Widget (corner, co), |
|---|
| 41 | _corner (corner._corner) |
|---|
| 42 | { |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | void Frame::Corner::parented(Window* window) { |
|---|
| 46 | Frame* parent = dynamic_cast<Frame*>(getParent()); |
|---|
| 47 | |
|---|
| 48 | if(!parent) return; |
|---|
| 49 | |
|---|
| 50 | if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG); |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | bool Frame::Corner::mouseDrag(double x, double y, const WindowManager* wm) |
|---|
| 54 | { |
|---|
| 55 | Frame* parent = dynamic_cast<Frame*>(getParent()); |
|---|
| 56 | |
|---|
| 57 | if(!parent || !parent->canResize()) return false; |
|---|
| 58 | |
|---|
| 59 | if(_corner == CORNER_UPPER_LEFT) { |
|---|
| 60 | if(parent->resizeAdd(-x, y)) parent->addX(x); |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y); |
|---|
| 64 | |
|---|
| 65 | else if(_corner == CORNER_LOWER_RIGHT) { |
|---|
| 66 | if(parent->resizeAdd(x, -y)) parent->addY(y); |
|---|
| 67 | } |
|---|
| 68 | |
|---|
| 69 | else { |
|---|
| 70 | if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | parent->update(); |
|---|
| 74 | |
|---|
| 75 | return true; |
|---|
| 76 | } |
|---|
| 77 | |
|---|
| 78 | Frame::Border::Border(BorderType border, point_type width, point_type height): |
|---|
| 79 | Widget (borderTypeToString(border), width, height), |
|---|
| 80 | _border (border) |
|---|
| 81 | { |
|---|
| 82 | setCanFill(true); |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | Frame::Border::Border(const Border& border, const osg::CopyOp& co): |
|---|
| 86 | Widget (border, co), |
|---|
| 87 | _border (border._border) |
|---|
| 88 | { |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | void Frame::Border::parented(Window* window) { |
|---|
| 92 | Frame* parent = dynamic_cast<Frame*>(getParent()); |
|---|
| 93 | |
|---|
| 94 | if(!parent) return; |
|---|
| 95 | |
|---|
| 96 | if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG); |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | void Frame::Border::positioned() |
|---|
| 100 | { |
|---|
| 101 | osg::Image* image = _image(); |
|---|
| 102 | |
|---|
| 103 | if(!image) return; |
|---|
| 104 | |
|---|
| 105 | Frame* parent = dynamic_cast<Frame*>(getParent()); |
|---|
| 106 | |
|---|
| 107 | if(!parent || !parent->canTexture()) return; |
|---|
| 108 | |
|---|
| 109 | point_type w = image->s() / 8.0f; |
|---|
| 110 | point_type h = getHeight(); |
|---|
| 111 | |
|---|
| 112 | if(_border == BORDER_LEFT) setTexCoordRegion(w * 3, 0.0f, w, h); |
|---|
| 113 | |
|---|
| 114 | else if(_border == BORDER_RIGHT) setTexCoordRegion(w * 4, 0.0f, w, h); |
|---|
| 115 | |
|---|
| 116 | else if(_border == BORDER_TOP) { |
|---|
| 117 | |
|---|
| 118 | point_type tx1 = (w * 2) / image->s(); |
|---|
| 119 | point_type tx2 = w / image->s(); |
|---|
| 120 | point_type tx3 = getWidth() / w; |
|---|
| 121 | |
|---|
| 122 | setTexCoord(tx1, tx3, LL); |
|---|
| 123 | setTexCoord(tx1, 0.0f, LR); |
|---|
| 124 | setTexCoord(tx2, 0.0f, UR); |
|---|
| 125 | setTexCoord(tx2, tx3, UL); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | else { |
|---|
| 129 | point_type tx1 = (w * 7) / image->s(); |
|---|
| 130 | point_type tx2 = (w * 6) / image->s(); |
|---|
| 131 | point_type tx3 = getWidth() / w; |
|---|
| 132 | |
|---|
| 133 | setTexCoord(tx1, tx3, LL); |
|---|
| 134 | setTexCoord(tx1, 0.0f, LR); |
|---|
| 135 | setTexCoord(tx2, 0.0f, UR); |
|---|
| 136 | setTexCoord(tx2, tx3, UL); |
|---|
| 137 | } |
|---|
| 138 | } |
|---|
| 139 | |
|---|
| 140 | bool Frame::Border::mouseDrag(double x, double y, const WindowManager* wm) |
|---|
| 141 | { |
|---|
| 142 | Frame* parent = dynamic_cast<Frame*>(getParent()); |
|---|
| 143 | |
|---|
| 144 | if(!parent) return false; |
|---|
| 145 | |
|---|
| 146 | if(_border == BORDER_TOP && parent->canMove()) parent->addOrigin(x, y); |
|---|
| 147 | |
|---|
| 148 | else { |
|---|
| 149 | if(!parent->canResize()) return false; |
|---|
| 150 | |
|---|
| 151 | if(_border == BORDER_LEFT) { |
|---|
| 152 | if(parent->resizeAdd(-x, 0.0f)) parent->addX(x); |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f); |
|---|
| 156 | |
|---|
| 157 | else { |
|---|
| 158 | if(parent->resizeAdd(0.0f, -y)) parent->addY(y); |
|---|
| 159 | } |
|---|
| 160 | } |
|---|
| 161 | |
|---|
| 162 | parent->update(); |
|---|
| 163 | |
|---|
| 164 | return true; |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | Frame::Frame(const std::string& name, unsigned int flags): |
|---|
| 168 | Table (name, 3, 3), |
|---|
| 169 | _flags (flags) |
|---|
| 170 | { |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | Frame::Frame(const Frame& frame, const osg::CopyOp& co): |
|---|
| 174 | Table(frame, co), |
|---|
| 175 | _flags(frame._flags) |
|---|
| 176 | { |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | Widget* Frame::_getCorner(CornerType c) const |
|---|
| 180 | { |
|---|
| 181 | return const_cast<Widget*>(getByName(cornerTypeToString(c))); |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | Widget* Frame::_getBorder(BorderType b) const |
|---|
| 185 | { |
|---|
| 186 | return const_cast<Widget*>(getByName(borderTypeToString(b))); |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | bool Frame::setWindow(Window* window) |
|---|
| 190 | { |
|---|
| 191 | if(!window) return false; |
|---|
| 192 | |
|---|
| 193 | EmbeddedWindow* ew = getEmbeddedWindow(); |
|---|
| 194 | |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | if(!ew) return addWidget(window->embed(), 1, 1); |
|---|
| 198 | |
|---|
| 199 | else return ew->setWindow(window); |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | Frame* Frame::createSimpleFrame( |
|---|
| 203 | const std::string& name, |
|---|
| 204 | point_type cw, |
|---|
| 205 | point_type ch, |
|---|
| 206 | point_type w, |
|---|
| 207 | point_type h, |
|---|
| 208 | unsigned int flags, |
|---|
| 209 | Frame* exFrame |
|---|
| 210 | ) { |
|---|
| 211 | Frame* frame = 0; |
|---|
| 212 | |
|---|
| 213 | |
|---|
| 214 | |
|---|
| 215 | if(!exFrame) frame = new Frame(name, flags); |
|---|
| 216 | |
|---|
| 217 | else frame = exFrame; |
|---|
| 218 | |
|---|
| 219 | frame->addWidget(new Corner(CORNER_LOWER_LEFT, cw, ch), 0, 0); |
|---|
| 220 | frame->addWidget(new Border(BORDER_BOTTOM, w, ch), 0, 1); |
|---|
| 221 | frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 0, 2); |
|---|
| 222 | frame->addWidget(new Border(BORDER_LEFT, cw, h), 1, 0); |
|---|
| 223 | frame->addWidget(new Border(BORDER_RIGHT, cw, h), 1, 2); |
|---|
| 224 | frame->addWidget(new Corner(CORNER_UPPER_LEFT, cw, ch), 2, 0); |
|---|
| 225 | frame->addWidget(new Border(BORDER_TOP, w, ch), 2, 1); |
|---|
| 226 | frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 2, 2); |
|---|
| 227 | |
|---|
| 228 | EmbeddedWindow* ew = new EmbeddedWindow(name, w, h); |
|---|
| 229 | |
|---|
| 230 | ew->setCanFill(true); |
|---|
| 231 | |
|---|
| 232 | frame->addWidget(ew, 1, 1); |
|---|
| 233 | |
|---|
| 234 | return frame; |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | |
|---|
| 238 | |
|---|
| 239 | |
|---|
| 240 | |
|---|
| 241 | |
|---|
| 242 | |
|---|
| 243 | |
|---|
| 244 | |
|---|
| 245 | |
|---|
| 246 | |
|---|
| 247 | |
|---|
| 248 | |
|---|
| 249 | |
|---|
| 250 | |
|---|
| 251 | |
|---|
| 252 | |
|---|
| 253 | |
|---|
| 254 | |
|---|
| 255 | |
|---|
| 256 | |
|---|
| 257 | |
|---|
| 258 | |
|---|
| 259 | |
|---|
| 260 | |
|---|
| 261 | |
|---|
| 262 | |
|---|
| 263 | |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | |
|---|
| 267 | |
|---|
| 268 | |
|---|
| 269 | |
|---|
| 270 | |
|---|
| 271 | |
|---|
| 272 | |
|---|
| 273 | |
|---|
| 274 | Frame* Frame::createSimpleFrameWithSingleTexture( |
|---|
| 275 | const std::string& name, |
|---|
| 276 | osg::Image* image, |
|---|
| 277 | point_type width, |
|---|
| 278 | point_type height, |
|---|
| 279 | unsigned int flags, |
|---|
| 280 | Frame* exFrame |
|---|
| 281 | ) { |
|---|
| 282 | Frame* frame = 0; |
|---|
| 283 | |
|---|
| 284 | double w = width; |
|---|
| 285 | double h = height; |
|---|
| 286 | |
|---|
| 287 | if (image) |
|---|
| 288 | { |
|---|
| 289 | w = image->s() / 8.0f; |
|---|
| 290 | h = image->t(); |
|---|
| 291 | } |
|---|
| 292 | |
|---|
| 293 | |
|---|
| 294 | if(!exFrame) frame = createSimpleFrame(name, w, h, width, height, flags); |
|---|
| 295 | |
|---|
| 296 | else frame = createSimpleFrame(name, w, h, width, height, 0, exFrame); |
|---|
| 297 | |
|---|
| 298 | if (image) |
|---|
| 299 | { |
|---|
| 300 | |
|---|
| 301 | for(unsigned int i = 0; i < 9; i++) frame->getObjects()[i]->setImage(image); |
|---|
| 302 | |
|---|
| 303 | XYCoord twh(w, h); |
|---|
| 304 | |
|---|
| 305 | frame->getCorner(CORNER_UPPER_LEFT )->setTexCoordRegion(0.0f, 0.0f, twh); |
|---|
| 306 | frame->getBorder(BORDER_TOP )->setTexCoordRegion(w, 0.0f, twh); |
|---|
| 307 | frame->getCorner(CORNER_UPPER_RIGHT)->setTexCoordRegion(w * 2, 0.0f, twh); |
|---|
| 308 | frame->getBorder(BORDER_LEFT )->setTexCoordRegion(w * 3, 0.0f, twh); |
|---|
| 309 | frame->getBorder(BORDER_RIGHT )->setTexCoordRegion(w * 4, 0.0f, twh); |
|---|
| 310 | frame->getCorner(CORNER_LOWER_LEFT )->setTexCoordRegion(w * 5, 0.0f, twh); |
|---|
| 311 | frame->getBorder(BORDER_BOTTOM )->setTexCoordRegion(w * 6, 0.0f, twh); |
|---|
| 312 | frame->getCorner(CORNER_LOWER_RIGHT)->setTexCoordRegion(w * 7, 0.0f, twh); |
|---|
| 313 | |
|---|
| 314 | |
|---|
| 315 | |
|---|
| 316 | frame->getByRowCol(0, 1)->setTexCoordWrapVertical(); |
|---|
| 317 | frame->getByRowCol(1, 0)->setTexCoordWrapVertical(); |
|---|
| 318 | frame->getByRowCol(1, 2)->setTexCoordWrapVertical(); |
|---|
| 319 | frame->getByRowCol(2, 1)->setTexCoordWrapVertical(); |
|---|
| 320 | |
|---|
| 321 | |
|---|
| 322 | } |
|---|
| 323 | else |
|---|
| 324 | { |
|---|
| 325 | OSG_WARN << "createSimpleFrameWithSingleTexture with a null image, the frame " << name << " will be use texture" << std::endl; |
|---|
| 326 | } |
|---|
| 327 | |
|---|
| 328 | return frame; |
|---|
| 329 | } |
|---|
| 330 | |
|---|
| 331 | bool Frame::resizeFrame(point_type w, point_type h) { |
|---|
| 332 | Border* left = getBorder(BORDER_LEFT); |
|---|
| 333 | Border* right = getBorder(BORDER_RIGHT); |
|---|
| 334 | Border* top = getBorder(BORDER_TOP); |
|---|
| 335 | Border* bottom = getBorder(BORDER_BOTTOM); |
|---|
| 336 | |
|---|
| 337 | if(!left || !right || !top || !bottom) return false; |
|---|
| 338 | |
|---|
| 339 | return resize( |
|---|
| 340 | left->getWidth() + right->getWidth() + w, |
|---|
| 341 | top->getHeight() + bottom->getHeight() + h |
|---|
| 342 | ); |
|---|
| 343 | } |
|---|
| 344 | |
|---|
| 345 | |
|---|
| 346 | osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme); |
|---|
| 347 | |
|---|
| 348 | Frame* Frame::createSimpleFrameFromTheme( |
|---|
| 349 | const std::string& name, |
|---|
| 350 | osg::Image* image, |
|---|
| 351 | point_type width, |
|---|
| 352 | point_type height, |
|---|
| 353 | unsigned int flags, |
|---|
| 354 | Frame* exFrame |
|---|
| 355 | ) { |
|---|
| 356 | |
|---|
| 357 | osg::ref_ptr<osg::Image> natifImage = createNatifEdgeImageFromTheme(image); |
|---|
| 358 | Frame* frame; |
|---|
| 359 | |
|---|
| 360 | frame = createSimpleFrameWithSingleTexture(name, natifImage.get(), width, height, flags, exFrame); |
|---|
| 361 | |
|---|
| 362 | if (frame && image && natifImage.valid()) |
|---|
| 363 | { |
|---|
| 364 | const unsigned int bpps = image->getPixelSizeInBits() / 8; |
|---|
| 365 | const unsigned int one_third_s = image->s()/3; |
|---|
| 366 | unsigned char* srcdata = (unsigned char*)image->data(); |
|---|
| 367 | osg::Vec4 color(0,0,0,1); |
|---|
| 368 | for (unsigned int d = 0; d < bpps; d++) |
|---|
| 369 | { |
|---|
| 370 | color[d] = srcdata[one_third_s * image->s() * bpps + (one_third_s) * bpps + d] * 1.0/255.0; |
|---|
| 371 | } |
|---|
| 372 | frame->getEmbeddedWindow()->setColor(color); |
|---|
| 373 | } |
|---|
| 374 | return frame; |
|---|
| 375 | } |
|---|
| 376 | |
|---|
| 377 | |
|---|
| 378 | |
|---|
| 379 | |
|---|
| 380 | |
|---|
| 381 | |
|---|
| 382 | |
|---|
| 383 | |
|---|
| 384 | |
|---|
| 385 | |
|---|
| 386 | |
|---|
| 387 | template<typename T> |
|---|
| 388 | void copyDataImpl(const osg::Image* source, |
|---|
| 389 | const unsigned int x1, const unsigned int y1, |
|---|
| 390 | const unsigned int x2, const unsigned int y2, |
|---|
| 391 | osg::Image* destination, |
|---|
| 392 | const unsigned int xd = 0, const unsigned int yd = 0) |
|---|
| 393 | { |
|---|
| 394 | if ((unsigned int)destination->s() >= xd + (x2 - x1) && |
|---|
| 395 | (unsigned int)destination->t() >= yd + (y2 - y1)) |
|---|
| 396 | { |
|---|
| 397 | const unsigned int bpps = source->getPixelSizeInBits() / (8 * sizeof(T)); |
|---|
| 398 | |
|---|
| 399 | T* srcdata = (T*)source->data(); |
|---|
| 400 | T* dstdata = (T*)destination->data(); |
|---|
| 401 | |
|---|
| 402 | for (unsigned int y = 0; y < y2 - y1; ++y) |
|---|
| 403 | { |
|---|
| 404 | for (unsigned int x = 0; x < x2 - x1; ++x) |
|---|
| 405 | { |
|---|
| 406 | for (unsigned int d = 0; d < bpps; d++) |
|---|
| 407 | { |
|---|
| 408 | T v = srcdata[(y + y1) * source->s() * bpps + (x + x1) * bpps + d]; |
|---|
| 409 | dstdata[(yd + y) * destination->s() * bpps + (xd + x) * bpps + d] = v; |
|---|
| 410 | } |
|---|
| 411 | } |
|---|
| 412 | } |
|---|
| 413 | } |
|---|
| 414 | else |
|---|
| 415 | assert(false && "copyDataImpl: Incorrect image dimensions."); |
|---|
| 416 | } |
|---|
| 417 | |
|---|
| 418 | |
|---|
| 419 | |
|---|
| 420 | |
|---|
| 421 | |
|---|
| 422 | void copyData(const osg::Image* source, |
|---|
| 423 | const unsigned int x1, const unsigned int y1, |
|---|
| 424 | const unsigned int x2, const unsigned int y2, |
|---|
| 425 | osg::Image* destination, |
|---|
| 426 | const unsigned int xd, const unsigned int yd) |
|---|
| 427 | { |
|---|
| 428 | if (source->getDataType() == destination->getDataType()) |
|---|
| 429 | { |
|---|
| 430 | if (source->getDataType() == GL_UNSIGNED_BYTE) |
|---|
| 431 | { |
|---|
| 432 | copyDataImpl<unsigned char>(source, x1, y1, x2, y2, |
|---|
| 433 | destination, xd, yd); |
|---|
| 434 | } |
|---|
| 435 | else |
|---|
| 436 | { |
|---|
| 437 | assert(false && "copyData not implemented for this data type"); |
|---|
| 438 | } |
|---|
| 439 | } |
|---|
| 440 | else |
|---|
| 441 | { |
|---|
| 442 | assert(false && "source and destination images must be of the same type."); |
|---|
| 443 | return; |
|---|
| 444 | } |
|---|
| 445 | } |
|---|
| 446 | |
|---|
| 447 | |
|---|
| 448 | |
|---|
| 449 | template<typename T> |
|---|
| 450 | osg::Image* rotateImageImpl(osg::Image* image) |
|---|
| 451 | { |
|---|
| 452 | if (image->s() == image->t()) |
|---|
| 453 | { |
|---|
| 454 | const unsigned int s = image->s(); |
|---|
| 455 | const unsigned int bpp = image->getPixelSizeInBits() / (8 * sizeof(T)); |
|---|
| 456 | |
|---|
| 457 | osg::ref_ptr<osg::Image> destination = new osg::Image; |
|---|
| 458 | destination->allocateImage(s, s, 1, |
|---|
| 459 | image->getPixelFormat(), image->getDataType(), |
|---|
| 460 | image->getPacking()); |
|---|
| 461 | destination->setInternalTextureFormat(image->getInternalTextureFormat()); |
|---|
| 462 | |
|---|
| 463 | T* srcdata = (T*)image->data(); |
|---|
| 464 | T* dstdata = (T*)destination->data(); |
|---|
| 465 | |
|---|
| 466 | for (unsigned int y = 0; y < s; ++y) |
|---|
| 467 | { |
|---|
| 468 | for (unsigned int x = 0; x < s; ++x) |
|---|
| 469 | { |
|---|
| 470 | for (unsigned int p = 0; p < bpp; p++) |
|---|
| 471 | dstdata[y * s * bpp + x * bpp + p] = srcdata[x * s * bpp + y * bpp + p]; |
|---|
| 472 | } |
|---|
| 473 | } |
|---|
| 474 | |
|---|
| 475 | return destination.release(); |
|---|
| 476 | } |
|---|
| 477 | else |
|---|
| 478 | { |
|---|
| 479 | assert(false && "rotateImageImpl: Image must be square."); |
|---|
| 480 | return 0; |
|---|
| 481 | } |
|---|
| 482 | } |
|---|
| 483 | |
|---|
| 484 | |
|---|
| 485 | |
|---|
| 486 | osg::Image* rotateImage(osg::Image* image) |
|---|
| 487 | { |
|---|
| 488 | if (image->getDataType() == GL_UNSIGNED_BYTE) |
|---|
| 489 | { |
|---|
| 490 | return rotateImageImpl<unsigned char>(image); |
|---|
| 491 | } |
|---|
| 492 | else |
|---|
| 493 | { |
|---|
| 494 | assert(false && "rotateImage not implemented for this data type"); |
|---|
| 495 | return 0; |
|---|
| 496 | } |
|---|
| 497 | } |
|---|
| 498 | |
|---|
| 499 | |
|---|
| 500 | |
|---|
| 501 | |
|---|
| 502 | |
|---|
| 503 | |
|---|
| 504 | |
|---|
| 505 | |
|---|
| 506 | |
|---|
| 507 | |
|---|
| 508 | |
|---|
| 509 | |
|---|
| 510 | |
|---|
| 511 | |
|---|
| 512 | |
|---|
| 513 | |
|---|
| 514 | |
|---|
| 515 | |
|---|
| 516 | |
|---|
| 517 | |
|---|
| 518 | |
|---|
| 519 | |
|---|
| 520 | |
|---|
| 521 | |
|---|
| 522 | |
|---|
| 523 | |
|---|
| 524 | |
|---|
| 525 | osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme) |
|---|
| 526 | { |
|---|
| 527 | if (!theme) { |
|---|
| 528 | OSG_WARN << "can't create a natif edge image from null image theme as argument" << std::endl; |
|---|
| 529 | return 0; |
|---|
| 530 | } |
|---|
| 531 | osg::ref_ptr<osg::Image> final = new osg::Image; |
|---|
| 532 | const int s = theme->s(); |
|---|
| 533 | const int t = theme->t(); |
|---|
| 534 | const GLenum pixelFormat = theme->getPixelFormat(); |
|---|
| 535 | const GLenum dataType = theme->getDataType(); |
|---|
| 536 | const GLint internalFormat = theme->getInternalTextureFormat(); |
|---|
| 537 | unsigned int packing = theme->getPacking(); |
|---|
| 538 | |
|---|
| 539 | if (s != t) |
|---|
| 540 | { |
|---|
| 541 | OSG_WARN << "width and height are different, bad format theme image " << theme->getFileName() << std::endl; |
|---|
| 542 | return 0; |
|---|
| 543 | } |
|---|
| 544 | |
|---|
| 545 | |
|---|
| 546 | int ceilvalue = static_cast<int>(ceil(s * 1.0 / 3)); |
|---|
| 547 | int intvalue = s/3; |
|---|
| 548 | if (intvalue != ceilvalue) |
|---|
| 549 | { |
|---|
| 550 | OSG_WARN << "the size of theme file " << theme->getFileName() << " can not be divided by 3, check the documentation about theme format" << std::endl; |
|---|
| 551 | return 0; |
|---|
| 552 | } |
|---|
| 553 | |
|---|
| 554 | const unsigned int one_third_s = s/3; |
|---|
| 555 | const unsigned int one_third_t = t/3; |
|---|
| 556 | |
|---|
| 557 | final->allocateImage(8 * one_third_s , one_third_t, 1, pixelFormat, dataType, packing); |
|---|
| 558 | final->setInternalTextureFormat(internalFormat); |
|---|
| 559 | |
|---|
| 560 | |
|---|
| 561 | copyData(theme, 0, 2 * one_third_s, one_third_s, 3 * one_third_s, final.get(), 0, 0); |
|---|
| 562 | |
|---|
| 563 | |
|---|
| 564 | osg::ref_ptr<osg::Image> rotateandcopy2 = new osg::Image; |
|---|
| 565 | rotateandcopy2->allocateImage(one_third_s , one_third_t, 1, pixelFormat, dataType, packing); |
|---|
| 566 | rotateandcopy2->setInternalTextureFormat(internalFormat); |
|---|
| 567 | copyData(theme, one_third_s, 0, 2 * one_third_s , one_third_s, rotateandcopy2.get(), 0, 0); |
|---|
| 568 | rotateandcopy2 = rotateImage(rotateandcopy2.get()); |
|---|
| 569 | rotateandcopy2->flipHorizontal(); |
|---|
| 570 | copyData(rotateandcopy2.get(), 0, 0, one_third_s , one_third_s, final.get(), 6*one_third_s, 0); |
|---|
| 571 | |
|---|
| 572 | |
|---|
| 573 | copyData(theme, 2*one_third_s , 2 *one_third_s, 3*one_third_s , 3 * one_third_s, final.get(), 2 * one_third_s, 0); |
|---|
| 574 | |
|---|
| 575 | |
|---|
| 576 | copyData(theme, 0, one_third_s, one_third_s , 2 * one_third_s, final.get(), 3 * one_third_s, 0); |
|---|
| 577 | |
|---|
| 578 | |
|---|
| 579 | copyData(theme, 2*one_third_s , one_third_s, 3 * one_third_s , 2 * one_third_s, final.get(), 4 * one_third_s, 0); |
|---|
| 580 | |
|---|
| 581 | |
|---|
| 582 | copyData(theme, 0 , 0, one_third_s, one_third_s, final.get(), 5 * one_third_s, 0); |
|---|
| 583 | |
|---|
| 584 | |
|---|
| 585 | osg::ref_ptr<osg::Image> rotateandcopy7 = new osg::Image; |
|---|
| 586 | rotateandcopy7->allocateImage(one_third_s , one_third_t, 1, pixelFormat, dataType, packing); |
|---|
| 587 | rotateandcopy7->setInternalTextureFormat(internalFormat); |
|---|
| 588 | copyData(theme, one_third_s, 2*one_third_s, 2 * one_third_s , 3 * one_third_s, rotateandcopy7.get(), 0, 0); |
|---|
| 589 | rotateandcopy7 = rotateImage(rotateandcopy7.get()); |
|---|
| 590 | rotateandcopy7->flipHorizontal(); |
|---|
| 591 | copyData(rotateandcopy7.get(), 0, 0, one_third_s , one_third_s, final.get(), one_third_s, 0); |
|---|
| 592 | |
|---|
| 593 | |
|---|
| 594 | copyData(theme, 2 * one_third_s, 0, 3 * one_third_s , one_third_s , final.get(), 7 * one_third_s, 0); |
|---|
| 595 | |
|---|
| 596 | return final.release(); |
|---|
| 597 | } |
|---|
| 598 | |
|---|
| 599 | } |
|---|