the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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}