the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 900 lines 24 kB view raw
1#include "stdafx.h" 2#include "..\Minecraft.World\ByteBuffer.h" 3#include "Rect2i.h" 4#include "TextureManager.h" 5#include "Texture.h" 6 7#ifdef __PS3__ 8#include "PS3\SPU_Tasks\Texture_blit\Texture_blit.h" 9#include "C4JSpursJob.h" 10static const int sc_maxTextureBlits = 256; 11static Texture_blit_DataIn g_textureBlitDataIn[sc_maxTextureBlits] __attribute__((__aligned__(16))); 12static int g_currentTexBlit = 0; 13C4JSpursJobQueue::Port* g_texBlitJobQueuePort; 14// #define DISABLE_SPU_CODE 15#endif //__PS3__ 16 17#define MAX_MIP_LEVELS 5 18 19Texture::Texture(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, bool mipMap) 20{ 21 _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, mipMap); 22} 23 24void Texture::_init(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, bool mipMap) 25{ 26#ifdef __PS3__ 27 if(g_texBlitJobQueuePort == NULL) 28 g_texBlitJobQueuePort = new C4JSpursJobQueue::Port("C4JSpursJob_Texture_blit"); 29#endif 30 this->name = name; 31 this->mode = mode; 32 this->width = width; 33 this->height = height; 34 this->depth = depth; 35 this->format = format; 36 this->minFilter = minFilter; 37 this->magFilter = magFilter; 38 this->wrapMode = wrapMode; 39 immediateUpdate = false; 40 m_bInitialised = false; 41 for( int i = 0 ; i < 10; i++ ) 42 { 43 data[i] = NULL; 44 } 45 46 rect = new Rect2i(0, 0, width, height); 47 // 4J Removed 1D and 3D 48 //if (height == 1 && depth == 1) 49 //{ 50 // type = GL_TEXTURE_1D; 51 //} 52 //else if(depth == 1) 53 //{ 54 type = GL_TEXTURE_2D; 55 //} 56 //else 57 //{ 58 // type = GL_TEXTURE_3D; 59 //} 60 61 mipmapped = mipMap || (minFilter != GL_NEAREST && minFilter != GL_LINEAR) || 62 (magFilter != GL_NEAREST && magFilter != GL_LINEAR); 63 m_iMipLevels=1; 64 65 if(mipmapped) 66 { 67 // 4J-PB - In the new XDK, the CreateTexture will fail if the number of mipmaps is higher than the width & height passed in will allow! 68 int iWidthMips=1; 69 int iHeightMips=1; 70 while((8<<iWidthMips)<width) iWidthMips++; 71 while((8<<iHeightMips)<height) iHeightMips++; 72 73 m_iMipLevels=(iWidthMips<iHeightMips)?iWidthMips:iHeightMips; 74 75 // TODO - The render libs currently limit max mip map levels to 5 76 if(m_iMipLevels > MAX_MIP_LEVELS) m_iMipLevels = MAX_MIP_LEVELS; 77 } 78 79#ifdef __PSVITA__ 80 // vita doesn't have a mipmap conditional shader because it's too slow so make sure this texture don't look awful at the lower mips 81 if( name == L"terrain" ) 82 { 83 m_iMipLevels = 3; 84 } 85#endif 86 87 if (mode != TM_CONTAINER) 88 { 89 glId = glGenTextures(); 90 91 glBindTexture(type, glId); 92 glTexParameteri(type, GL_TEXTURE_MIN_FILTER, minFilter); 93 glTexParameteri(type, GL_TEXTURE_MAG_FILTER, magFilter); 94 glTexParameteri(type, GL_TEXTURE_WRAP_S, wrapMode); 95 glTexParameteri(type, GL_TEXTURE_WRAP_T, wrapMode); 96 } 97 else 98 { 99 glId = -1; 100 } 101 102 managerId = TextureManager::getInstance()->createTextureID(); 103} 104 105void Texture::_init(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, BufferedImage *image, bool mipMap) 106{ 107 _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, mipMap); 108 if (image == NULL) 109 { 110 if (width == -1 || height == -1) 111 { 112 valid = false; 113 } 114 else 115 { 116 byteArray tempBytes = byteArray(width * height * depth * 4); 117 for (int index = 0; index < tempBytes.length; index++) 118 { 119 tempBytes[index] = 0; 120 } 121#ifdef __PS3__ 122 data[0] = new ByteBuffer_IO(tempBytes.length); 123#else 124 data[0] = ByteBuffer::allocateDirect(tempBytes.length); 125#endif // __{S3__ 126 data[0]->clear(); 127 data[0]->put(tempBytes); 128 data[0]->position(0)->limit(tempBytes.length); 129 130 delete [] tempBytes.data; 131 132 if(mipmapped) 133 { 134 for(unsigned int level = 1; level < m_iMipLevels; ++level) 135 { 136 int ww = width >> level; 137 int hh = height >> height; 138 139 byteArray tempBytes = byteArray(ww * hh * depth * 4); 140 for (int index = 0; index < tempBytes.length; index++) 141 { 142 tempBytes[index] = 0; 143 } 144 145#ifdef __PS3__ 146 data[level] = new ByteBuffer_IO(tempBytes.length); 147#else 148 data[level] = ByteBuffer::allocateDirect(tempBytes.length); 149#endif // __PS3__ 150 data[level]->clear(); 151 data[level]->put(tempBytes); 152 data[level]->position(0)->limit(tempBytes.length); 153 154 delete [] tempBytes.data; 155 } 156 } 157 158 if (immediateUpdate) 159 { 160 updateOnGPU(); 161 } 162 else 163 { 164 updated = false; 165 } 166 } 167 } 168 else 169 { 170 valid = true; 171 172 transferFromImage(image); 173 174 if (mode != TM_CONTAINER) 175 { 176 updateOnGPU(); 177 immediateUpdate = false; 178 } 179 } 180} 181 182Texture::Texture(const wstring &name, int mode, int width, int height, int wrapMode, int format, int minFilter, int magFilter, BufferedImage *image, bool mipMap) 183{ 184 _init(name, mode, width, height, 1, wrapMode, format, minFilter, magFilter, image, mipMap); 185} 186 187Texture::Texture(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, BufferedImage *image, bool mipMap) 188{ 189 _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, image, mipMap); 190} 191 192Texture::~Texture() 193{ 194 delete rect; 195 196 for(int i = 0; i < 10; i++ ) 197 { 198 if(data[i] != NULL) delete data[i]; 199 } 200 201 if(glId >= 0) 202 { 203 glDeleteTextures(glId); 204 } 205} 206 207const Rect2i *Texture::getRect() 208{ 209 return rect; 210} 211 212void Texture::fill(const Rect2i *rect, int color) 213{ 214 // 4J Remove 3D 215 //if (type == GL_TEXTURE_3D) 216 //{ 217 // return; 218 //} 219 220 Rect2i *myRect = new Rect2i(0, 0, width, height); 221 myRect->intersect(rect); 222 data[0]->position(0); 223 for (int y = myRect->getY(); y < (myRect->getY() + myRect->getHeight()); y++) 224 { 225 int line = y * width * 4; 226 for (int x = myRect->getX(); x < (myRect->getX() + myRect->getWidth()); x++) 227 { 228 data[0]->put(line + x * 4 + 0, (BYTE)((color >> 24) & 0x000000ff)); 229 data[0]->put(line + x * 4 + 1, (BYTE)((color >> 16) & 0x000000ff)); 230 data[0]->put(line + x * 4 + 2, (BYTE)((color >> 8) & 0x000000ff)); 231 data[0]->put(line + x * 4 + 3, (BYTE)((color >> 0) & 0x000000ff)); 232 } 233 } 234 delete myRect; 235 236 if (immediateUpdate) 237 { 238 updateOnGPU(); 239 } 240 else 241 { 242 updated = false; 243 } 244} 245 246void Texture::writeAsBMP(const wstring &name) 247{ 248 // 4J Don't need 249#if 0 250 if (type == GL_TEXTURE_3D) 251 { 252 return; 253 } 254 255 File *outFile = new File(name); 256 if (outFile.exists()) 257 { 258 outFile.delete(); 259 } 260 261 DataOutputStream *outStream = NULL; 262 //try { 263 outStream = new DataOutputStream(new FileOutputStream(outFile)); 264 //} catch (IOException e) { 265 // Unable to open file for writing for some reason 266 // return; 267 //} 268 269 //try { 270 // Write the header 271 outStream->writeShort((short)0x424d); // 0x0000: ID - 'BM' 272 int byteSize = width * height * 4 + 54; 273 outStream->writeByte((byte)(byteSize >> 0)); // 0x0002: Raw file size 274 outStream->writeByte((byte)(byteSize >> 8)); 275 outStream->writeByte((byte)(byteSize >> 16)); 276 outStream->writeByte((byte)(byteSize >> 24)); 277 outStream->writeInt(0); // 0x0006: Reserved 278 outStream->writeByte(54); // 0x000A: Start of pixel data 279 outStream->writeByte(0); 280 outStream->writeByte(0); 281 outStream->writeByte(0); 282 outStream->writeByte(40); // 0x000E: Size of secondary header 283 outStream->writeByte(0); 284 outStream->writeByte(0); 285 outStream->writeByte(0); 286 outStream->writeByte((byte)(width >> 0)); // 0x0012: Image width, in pixels 287 outStream->writeByte((byte)(width >> 8)); 288 outStream->writeByte((byte)(width >> 16)); 289 outStream->writeByte((byte)(width >> 24)); 290 outStream->writeByte((byte)(height >> 0)); // 0x0016: Image height, in pixels 291 outStream->writeByte((byte)(height >> 8)); 292 outStream->writeByte((byte)(height >> 16)); 293 outStream->writeByte((byte)(height >> 24)); 294 outStream->writeByte(1); // 0x001A: Number of color planes, must be 1 295 outStream->writeByte(0); 296 outStream->writeByte(32); // 0x001C: Bit depth (32bpp) 297 outStream->writeByte(0); 298 outStream->writeInt(0); // 0x001E: Compression mode (BI_RGB, uncompressed) 299 int bufSize = width * height * 4; 300 outStream->writeInt((byte)(bufSize >> 0)); // 0x0022: Raw size of bitmap data 301 outStream->writeInt((byte)(bufSize >> 8)); 302 outStream->writeInt((byte)(bufSize >> 16)); 303 outStream->writeInt((byte)(bufSize >> 24)); 304 outStream->writeInt(0); // 0x0026: Horizontal resolution in ppm 305 outStream->writeInt(0); // 0x002A: Vertical resolution in ppm 306 outStream->writeInt(0); // 0x002E: Palette size (0 to match bit depth) 307 outStream->writeInt(0); // 0x0032: Number of important colors, 0 for all 308 309 // Pixels follow in inverted Y order 310 byte[] bytes = new byte[width * height * 4]; 311 data.position(0); 312 data.get(bytes); 313 for (int y = height - 1; y >= 0; y--) 314 { 315 int line = y * width * 4; 316 for (int x = 0; x < width; x++) 317 { 318 outStream->writeByte(bytes[line + x * 4 + 2]); 319 outStream->writeByte(bytes[line + x * 4 + 1]); 320 outStream->writeByte(bytes[line + x * 4 + 0]); 321 outStream->writeByte(bytes[line + x * 4 + 3]); 322 } 323 } 324 325 outStream->close(); 326 //} catch (IOException e) { 327 // Unable to write to the file for some reason 328 // return; 329 //} 330#endif 331} 332 333void Texture::writeAsPNG(const wstring &filename) 334{ 335 // 4J Don't need 336#if 0 337 BufferedImage *image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 338 ByteBuffer *buffer = this->getData(); 339 byte[] bytes = new byte[width * height * 4]; 340 341 buffer.position(0); 342 buffer.get(bytes); 343 344 for (int x = 0; x < width; x++) 345 { 346 for (int y = 0; y < height; y++) 347 { 348 int pos = (y * width * 4) + x * 4; 349 int col = 0; 350 351 col |= (bytes[pos + 2] & 0xFF) << 0; 352 col |= (bytes[pos + 1] & 0xFF) << 8; 353 col |= (bytes[pos + 0] & 0xFF) << 16; 354 col |= (bytes[pos + 3] & 0xFF) << 24; 355 356 image.setRGB(x, y, col); 357 } 358 } 359 360 data.position(width * height * 4); 361 362 //try { 363 ImageIO::write(image, L"png", new File(Minecraft.getWorkingDirectory(), filename)); 364 //} catch (IOException e) { 365 // e.printStackTrace(); 366 //} 367#endif 368} 369 370void Texture::blit(int x, int y, Texture *source) 371{ 372 blit(x, y, source, false); 373} 374 375void Texture::blit(int x, int y, Texture *source, bool rotated) 376{ 377 // 4J Remove 3D 378 //if (type == GL_TEXTURE_3D) 379 //{ 380 // return; 381 //} 382 383 for(unsigned int level = 0; level < m_iMipLevels; ++level) 384 { 385 ByteBuffer *srcBuffer = source->getData(level); 386 387 if(srcBuffer == NULL) break; 388 389 int yy = y >> level; 390 int xx = x >> level; 391 int hh = height >> level; 392 int ww = width >> level; 393 int shh = source->getHeight() >> level; 394 int sww = source->getWidth() >> level; 395 396 data[level]->position(0); 397 srcBuffer->position(0); 398 399#if defined __PS3__ && !defined DISABLE_SPU_CODE 400 if(g_texBlitJobQueuePort->hasCompleted()) 401 { 402 // all outstanding blits have completed, so reset to the start of the blit list 403 g_currentTexBlit = 0; 404 } 405 Texture_blit_DataIn& dataIn = g_textureBlitDataIn[g_currentTexBlit]; 406 g_currentTexBlit++; 407 if(g_currentTexBlit >= sc_maxTextureBlits) 408 { 409 app.DebugPrintf("ran out of tex blit slots, stalling for completion\n"); 410 g_texBlitJobQueuePort->waitForCompletion(); 411 g_currentTexBlit = 0; 412 } 413 dataIn.pSrcData = srcBuffer->getBuffer(); 414 dataIn.pDstData = data[level]->getBuffer(); 415 dataIn.yy = yy; 416 dataIn.xx = xx; 417 dataIn.hh = hh; 418 dataIn.ww = ww; 419 dataIn.shh = shh; 420 dataIn.sww = sww; 421 dataIn.rotated = rotated; 422 423 C4JSpursJob_Texture_blit blitJob(&dataIn); 424 g_texBlitJobQueuePort->submitJob(&blitJob); 425// p.waitForCompletion(); 426 427#elif __PSVITA__ 428 unsigned int *src = (unsigned int *) srcBuffer->getBuffer(); 429 unsigned int *dst = (unsigned int *) data[level]->getBuffer(); 430 431 for (int srcY = 0; srcY < shh; srcY++) 432 { 433 int dstY = yy + srcY; 434 int srcLine = srcY * sww; 435 int dstLine = dstY * ww; 436 437 if (rotated) 438 { 439 dstY = yy + (shh - srcY); 440 } 441 442 if (!rotated) 443 { 444 memcpy(dst + dstLine + xx, src + srcLine, sww * 4); 445 } 446 else 447 { 448 for (int srcX = 0; srcX < sww; srcX++) 449 { 450 int dstPos = dstLine + (srcX + xx); 451 int srcPos = srcLine + srcX; 452 453 if (rotated) 454 { 455 dstPos = (xx + srcX * ww) + dstY; 456 } 457 458 dst[dstPos] = src[srcPos]; 459 } 460 } 461 } 462#else 463 464 for (int srcY = 0; srcY < shh; srcY++) 465 { 466 int dstY = yy + srcY; 467 int srcLine = srcY * sww * 4; 468 int dstLine = dstY * ww * 4; 469 470 if (rotated) 471 { 472 dstY = yy + (shh - srcY); 473 } 474 475 for (int srcX = 0; srcX < sww; srcX++) 476 { 477 int dstPos = dstLine + (srcX + xx) * 4; 478 int srcPos = srcLine + srcX * 4; 479 480 if (rotated) 481 { 482 dstPos = (xx + srcX * ww * 4) + dstY * 4; 483 } 484 485 data[level]->put(dstPos + 0, srcBuffer->get(srcPos + 0)); 486 data[level]->put(dstPos + 1, srcBuffer->get(srcPos + 1)); 487 data[level]->put(dstPos + 2, srcBuffer->get(srcPos + 2)); 488 data[level]->put(dstPos + 3, srcBuffer->get(srcPos + 3)); 489 } 490 } 491 // Don't delete this, as it belongs to the source texture 492 //delete srcBuffer; 493#endif 494 data[level]->position(ww * hh * 4); 495 } 496 497 if (immediateUpdate) 498 { 499 updateOnGPU(); 500 } 501 else 502 { 503 updated = false; 504 } 505} 506 507void Texture::transferFromBuffer(intArray buffer) 508{ 509 if (depth == 1) 510 { 511 return; 512 } 513 514// #ifdef __PS3__ 515// int byteRemapRGBA[] = { 3, 0, 1, 2 }; 516// int byteRemapBGRA[] = { 3, 2, 1, 0 }; 517// #else 518 int byteRemapRGBA[] = { 0, 1, 2, 3 }; 519 int byteRemapBGRA[] = { 2, 1, 0, 3 }; 520// #endif 521 int *byteRemap = ((format == TFMT_BGRA) ? byteRemapBGRA : byteRemapRGBA); 522 523 for (int z = 0; z < depth; z++) 524 { 525 int plane = z * height * width * 4; 526 for (int y = 0; y < height; y++) 527 { 528 int column = plane + y * width * 4; 529 for (int x = 0; x < width; x++) 530 { 531 int texel = column + x * 4; 532 data[0]->position(0); 533 data[0]->put(texel + byteRemap[0], (byte)((buffer[texel >> 2] >> 24) & 0xff)); 534 data[0]->put(texel + byteRemap[1], (byte)((buffer[texel >> 2] >> 16) & 0xff)); 535 data[0]->put(texel + byteRemap[2], (byte)((buffer[texel >> 2] >> 8) & 0xff)); 536 data[0]->put(texel + byteRemap[3], (byte)((buffer[texel >> 2] >> 0) & 0xff)); 537 } 538 } 539 } 540 541 data[0]->position(width * height * depth * 4); 542 543 updateOnGPU(); 544} 545 546void Texture::transferFromImage(BufferedImage *image) 547{ 548 // 4J Remove 3D 549 //if (type == GL_TEXTURE_3D) 550 //{ 551 // return; 552 //} 553 554 int imgWidth = image->getWidth(); 555 int imgHeight = image->getHeight(); 556 if (imgWidth > width || imgHeight > height) 557 { 558 //Minecraft::GetInstance().getLogger().warning("transferFromImage called with a BufferedImage with dimensions (" + 559 // imgWidth + ", " + imgHeight + ") larger than the Texture dimensions (" + width + 560 // ", " + height + "). Ignoring."); 561 app.DebugPrintf("transferFromImage called with a BufferedImage with dimensions (%d, %d) larger than the Texture dimensions (%d, %d). Ignoring.\n", imgWidth, imgHeight, width, height); 562 return; 563 } 564 565// #ifdef __PS3__ 566// int byteRemapRGBA[] = { 0, 1, 2, 3 }; 567// int byteRemapBGRA[] = { 2, 1, 0, 3 }; 568// #else 569#ifdef _XBOX 570 int byteRemapRGBA[] = { 0, 1, 2, 3 }; 571#else 572 int byteRemapRGBA[] = { 3, 0, 1, 2 }; 573#endif 574 int byteRemapBGRA[] = { 3, 2, 1, 0 }; 575// #endif 576 int *byteRemap = ((format == TFMT_BGRA) ? byteRemapBGRA : byteRemapRGBA); 577 578 intArray tempPixels = intArray(width * height); 579 int transparency = image->getTransparency(); 580 image->getRGB(0, 0, width, height, tempPixels, 0, imgWidth); 581 582 byteArray tempBytes = byteArray(width * height * 4); 583 for (int y = 0; y < height; y++) 584 { 585 for (int x = 0; x < width; x++) 586 { 587 int intIndex = y * width + x; 588 int byteIndex = intIndex * 4; 589 590 // Pull ARGB bytes into either RGBA or BGRA depending on format 591 592 tempBytes[byteIndex + byteRemap[0]] = (byte)((tempPixels[intIndex] >> 24) & 0xff); 593 tempBytes[byteIndex + byteRemap[1]] = (byte)((tempPixels[intIndex] >> 16) & 0xff); 594 tempBytes[byteIndex + byteRemap[2]] = (byte)((tempPixels[intIndex] >> 8) & 0xff); 595 tempBytes[byteIndex + byteRemap[3]] = (byte)((tempPixels[intIndex] >> 0) & 0xff); 596 } 597 } 598 599 for(int i = 0; i < 10; i++ ) 600 { 601 if(data[i] != NULL) 602 { 603 delete data[i]; 604 data[i] = NULL; 605 } 606 } 607 608 MemSect(51); 609#ifdef __PS3__ 610 data[0] = new ByteBuffer_IO(tempBytes.length); 611#else 612 data[0] = ByteBuffer::allocateDirect(tempBytes.length); 613#endif // __{S3__ 614 MemSect(0); 615 data[0]->clear(); 616 data[0]->put(tempBytes); 617 data[0]->limit(tempBytes.length); 618 619 delete [] tempBytes.data; 620 621 if(mipmapped || image->getData(1) != NULL) 622 { 623 mipmapped = true; 624 for(unsigned int level = 1; level < MAX_MIP_LEVELS; ++level) 625 { 626 int ww = width >> level; 627 int hh = height >> level; 628 629 byteArray tempBytes = byteArray(ww * hh * 4); 630 unsigned int *tempData = new unsigned int[ww * hh]; 631 632 if( image->getData( level ) ) 633 { 634 memcpy( tempData, image->getData( level ), ww * hh * 4); 635 for (int y = 0; y < hh; y++) 636 { 637 for (int x = 0; x < ww; x++) 638 { 639 int intIndex = y * ww + x; 640 int byteIndex = intIndex * 4; 641 642 // Pull ARGB bytes into either RGBA or BGRA depending on format 643 644 tempBytes[byteIndex + byteRemap[0]] = (byte)((tempData[intIndex] >> 24) & 0xff); 645 tempBytes[byteIndex + byteRemap[1]] = (byte)((tempData[intIndex] >> 16) & 0xff); 646 tempBytes[byteIndex + byteRemap[2]] = (byte)((tempData[intIndex] >> 8) & 0xff); 647 tempBytes[byteIndex + byteRemap[3]] = (byte)((tempData[intIndex] >> 0) & 0xff); 648 } 649 } 650 } 651 else 652 { 653 int ow = width >> (level - 1); 654 655 for (int x = 0; x < ww; x++) 656 for (int y = 0; y < hh; y++) 657 { 658 int c0 = data[level - 1]->getInt(((x * 2 + 0) + (y * 2 + 0) * ow) * 4); 659 int c1 = data[level - 1]->getInt(((x * 2 + 1) + (y * 2 + 0) * ow) * 4); 660 int c2 = data[level - 1]->getInt(((x * 2 + 1) + (y * 2 + 1) * ow) * 4); 661 int c3 = data[level - 1]->getInt(((x * 2 + 0) + (y * 2 + 1) * ow) * 4); 662#ifndef _XBOX 663 // 4J - convert our RGBA texels to ARGB that crispBlend is expecting 664 c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( c0 << 24 ); 665 c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( c1 << 24 ); 666 c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( c2 << 24 ); 667 c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( c3 << 24 ); 668#endif 669 int col = crispBlend(crispBlend(c0, c1), crispBlend(c2, c3)); 670 // 4J - and back from ARGB -> RGBA 671 //col = ( col << 8 ) | (( col >> 24 ) & 0xff); 672 //tempData[x + y * ww] = col; 673 674 int intIndex = y * ww + x; 675 int byteIndex = intIndex * 4; 676 677 // Pull ARGB bytes into either RGBA or BGRA depending on format 678 679 tempBytes[byteIndex + byteRemap[0]] = (byte)((col >> 24) & 0xff); 680 tempBytes[byteIndex + byteRemap[1]] = (byte)((col >> 16) & 0xff); 681 tempBytes[byteIndex + byteRemap[2]] = (byte)((col >> 8) & 0xff); 682 tempBytes[byteIndex + byteRemap[3]] = (byte)((col >> 0) & 0xff); 683 } 684 } 685 686 MemSect(51); 687#ifdef __PS3__ 688 data[level] = new ByteBuffer_IO(tempBytes.length); 689#else 690 data[level] = ByteBuffer::allocateDirect(tempBytes.length); 691#endif // __{S3__ 692 MemSect(0); 693 data[level]->clear(); 694 data[level]->put(tempBytes); 695 data[level]->limit(tempBytes.length); 696 delete [] tempBytes.data; 697 delete [] tempData; 698 } 699 } 700 701 delete [] tempPixels.data; 702 703 if (immediateUpdate) 704 { 705 updateOnGPU(); 706 } 707 else 708 { 709 updated = false; 710 } 711} 712 713// 4J Kept from older versions for where we create mip-maps for levels that do not have pre-made graphics 714int Texture::crispBlend(int c0, int c1) 715{ 716 int a0 = (int) (((c0 & 0xff000000) >> 24)) & 0xff; 717 int a1 = (int) (((c1 & 0xff000000) >> 24)) & 0xff; 718 719 int a = 255; 720 if (a0 + a1 < 255) 721 { 722 a = 0; 723 a0 = 1; 724 a1 = 1; 725 } 726 else if (a0 > a1) 727 { 728 a0 = 255; 729 a1 = 1; 730 } 731 else 732 { 733 a0 = 1; 734 a1 = 255; 735 736 } 737 738 int r0 = ((c0 >> 16) & 0xff) * a0; 739 int g0 = ((c0 >> 8) & 0xff) * a0; 740 int b0 = ((c0) & 0xff) * a0; 741 742 int r1 = ((c1 >> 16) & 0xff) * a1; 743 int g1 = ((c1 >> 8) & 0xff) * a1; 744 int b1 = ((c1) & 0xff) * a1; 745 746 int r = (r0 + r1) / (a0 + a1); 747 int g = (g0 + g1) / (a0 + a1); 748 int b = (b0 + b1) / (a0 + a1); 749 750 return (a << 24) | (r << 16) | (g << 8) | b; 751} 752 753int Texture::getManagerId() 754{ 755 return managerId; 756} 757 758int Texture::getGlId() 759{ 760 return glId; 761} 762 763int Texture::getWidth() 764{ 765 return width; 766} 767 768int Texture::getHeight() 769{ 770 return height; 771} 772 773wstring Texture::getName() 774{ 775 return name; 776} 777 778void Texture::setImmediateUpdate(bool immediateUpdate) 779{ 780 this->immediateUpdate = immediateUpdate; 781} 782 783void Texture::bind(int mipMapIndex) 784{ 785 // 4J Removed 3D 786 //if (depth == 1) 787 //{ 788 glEnable(GL_TEXTURE_2D); 789 //} 790 //else 791 //{ 792 // glEnable(GL_TEXTURE_3D); 793 //} 794 795 glActiveTexture(GL_TEXTURE0 + mipMapIndex); 796 glBindTexture(type, glId); 797 if (!updated) 798 { 799 updateOnGPU(); 800 } 801} 802 803void Texture::updateOnGPU() 804{ 805 data[0]->flip(); 806 if(mipmapped) 807 { 808 for (int level = 1; level < m_iMipLevels; level++) 809 { 810 if(data[level] == NULL) break; 811 812 data[level]->flip(); 813 } 814 } 815 // 4J remove 3D and 1D 816 //if (height != 1 && depth != 1) 817 //{ 818 // glTexImage3D(type, 0, format, width, height, depth, 0, format, GL_UNSIGNED_BYTE, data); 819 //} 820 //else if(height != 1) 821 //{ 822 // 4J Added check so we can differentiate between which RenderManager function to call 823 if(!m_bInitialised) 824 { 825 RenderManager.TextureSetTextureLevels(m_iMipLevels); // 4J added 826 827#ifdef __PSVITA__ 828 // AP - replace the dynamic ram buffer to one that points to a newly allocated video ram texture buffer. This means we don't have to memcpy 829 // the ram based buffer to it any more inside RenderManager.TextureDataUpdate 830 unsigned char *newData = RenderManager.TextureData(width,height,data[0]->getBuffer(),0,C4JRender::TEXTURE_FORMAT_RxGyBzAw); 831 ByteBuffer *oldBuffer = data[0]; 832 data[0] = new ByteBuffer(data[0]->getSize(), (byte*) newData); 833 delete oldBuffer; 834 newData += width * height * 4; 835#else 836 RenderManager.TextureData(width,height,data[0]->getBuffer(),0,C4JRender::TEXTURE_FORMAT_RxGyBzAw); 837#endif 838 839 if(mipmapped) 840 { 841 for (int level = 1; level < m_iMipLevels; level++) 842 { 843 int levelWidth = width >> level; 844 int levelHeight = height >> level; 845 846#ifdef __PSVITA__ 847 // AP - replace the dynamic ram buffer to one that points to a newly allocated video ram texture buffer. This means we don't have to memcpy 848 // the ram based buffer to it any more inside RenderManager.TextureDataUpdate 849 RenderManager.TextureDataUpdate(0, 0,levelWidth,levelHeight,data[level]->getBuffer(),level); 850 ByteBuffer *oldBuffer = data[level]; 851 data[level] = new ByteBuffer(data[level]->getSize(), (byte*) newData); 852 delete oldBuffer; 853 newData += levelWidth * levelHeight * 4; 854#else 855 RenderManager.TextureData(levelWidth,levelHeight,data[level]->getBuffer(),level,C4JRender::TEXTURE_FORMAT_RxGyBzAw); 856#endif 857 } 858 } 859 860 m_bInitialised = true; 861 } 862 else 863 { 864#ifdef _XBOX 865 RenderManager.TextureDataUpdate(data[0]->getBuffer(),0); 866#else 867 RenderManager.TextureDataUpdate(0, 0,width,height,data[0]->getBuffer(),0); 868#endif 869 870 if(mipmapped) 871 { 872 if (RenderManager.TextureGetTextureLevels() > 1) 873 { 874 for (int level = 1; level < m_iMipLevels; level++) 875 { 876 int levelWidth = width >> level; 877 int levelHeight = height >> level; 878 879#ifdef _XBOX 880 RenderManager.TextureDataUpdate(data[level]->getBuffer(),level); 881#else 882 RenderManager.TextureDataUpdate(0, 0,levelWidth,levelHeight,data[level]->getBuffer(),level); 883#endif 884 } 885 } 886 } 887 } 888 //glTexImage2D(type, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); 889 //} 890 //else 891 //{ 892 // glTexImage1D(type, 0, format, width, 0, format, GL_UNSIGNED_BYTE, data); 893 //} 894 updated = true; 895} 896 897ByteBuffer *Texture::getData(unsigned int level) 898{ 899 return data[level]; 900}