diff options
| author | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
|---|---|---|
| committer | daoge_cmd <3523206925@qq.com> | 2026-03-01 12:16:08 +0800 |
| commit | b691c43c44ff180d10e7d4a9afc83b98551ff586 (patch) | |
| tree | 3e9849222cbc6ba49f2f1fc6e5fe7179632c7390 /Minecraft.Client/Texture.cpp | |
| parent | def8cb415354ac390b7e89052a50605285f1aca9 (diff) | |
Initial commit
Diffstat (limited to 'Minecraft.Client/Texture.cpp')
| -rw-r--r-- | Minecraft.Client/Texture.cpp | 899 |
1 files changed, 899 insertions, 0 deletions
diff --git a/Minecraft.Client/Texture.cpp b/Minecraft.Client/Texture.cpp new file mode 100644 index 00000000..e287c177 --- /dev/null +++ b/Minecraft.Client/Texture.cpp @@ -0,0 +1,899 @@ +#include "stdafx.h" +#include "..\Minecraft.World\ByteBuffer.h" +#include "Rect2i.h" +#include "TextureManager.h" +#include "Texture.h" + +#ifdef __PS3__ +#include "PS3\SPU_Tasks\Texture_blit\Texture_blit.h" +#include "C4JSpursJob.h" +static const int sc_maxTextureBlits = 256; +static Texture_blit_DataIn g_textureBlitDataIn[sc_maxTextureBlits] __attribute__((__aligned__(16))); +static int g_currentTexBlit = 0; +C4JSpursJobQueue::Port* g_texBlitJobQueuePort; +#endif //__PS3__ + +#define MAX_MIP_LEVELS 5 + +Texture::Texture(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, bool mipMap) +{ + _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, mipMap); +} + +void Texture::_init(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, bool mipMap) +{ +#ifdef __PS3__ + if(g_texBlitJobQueuePort == NULL) + g_texBlitJobQueuePort = new C4JSpursJobQueue::Port("C4JSpursJob_Texture_blit"); +#endif + this->name = name; + this->mode = mode; + this->width = width; + this->height = height; + this->depth = depth; + this->format = format; + this->minFilter = minFilter; + this->magFilter = magFilter; + this->wrapMode = wrapMode; + immediateUpdate = false; + m_bInitialised = false; + for( int i = 0 ; i < 10; i++ ) + { + data[i] = NULL; + } + + rect = new Rect2i(0, 0, width, height); + // 4J Removed 1D and 3D + //if (height == 1 && depth == 1) + //{ + // type = GL_TEXTURE_1D; + //} + //else if(depth == 1) + //{ + type = GL_TEXTURE_2D; + //} + //else + //{ + // type = GL_TEXTURE_3D; + //} + + mipmapped = mipMap || (minFilter != GL_NEAREST && minFilter != GL_LINEAR) || + (magFilter != GL_NEAREST && magFilter != GL_LINEAR); + m_iMipLevels=1; + + if(mipmapped) + { + // 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! + int iWidthMips=1; + int iHeightMips=1; + while((8<<iWidthMips)<width) iWidthMips++; + while((8<<iHeightMips)<height) iHeightMips++; + + m_iMipLevels=(iWidthMips<iHeightMips)?iWidthMips:iHeightMips; + + // TODO - The render libs currently limit max mip map levels to 5 + if(m_iMipLevels > MAX_MIP_LEVELS) m_iMipLevels = MAX_MIP_LEVELS; + } + +#ifdef __PSVITA__ + // 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 + if( name == L"terrain" ) + { + m_iMipLevels = 3; + } +#endif + + if (mode != TM_CONTAINER) + { + glId = glGenTextures(); + + glBindTexture(type, glId); + glTexParameteri(type, GL_TEXTURE_MIN_FILTER, minFilter); + glTexParameteri(type, GL_TEXTURE_MAG_FILTER, magFilter); + glTexParameteri(type, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(type, GL_TEXTURE_WRAP_T, wrapMode); + } + else + { + glId = -1; + } + + managerId = TextureManager::getInstance()->createTextureID(); +} + +void 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) +{ + _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, mipMap); + if (image == NULL) + { + if (width == -1 || height == -1) + { + valid = false; + } + else + { + byteArray tempBytes = byteArray(width * height * depth * 4); + for (int index = 0; index < tempBytes.length; index++) + { + tempBytes[index] = 0; + } +#ifdef __PS3__ + data[0] = new ByteBuffer_IO(tempBytes.length); +#else + data[0] = ByteBuffer::allocateDirect(tempBytes.length); +#endif // __{S3__ + data[0]->clear(); + data[0]->put(tempBytes); + data[0]->position(0)->limit(tempBytes.length); + + delete [] tempBytes.data; + + if(mipmapped) + { + for(unsigned int level = 1; level < m_iMipLevels; ++level) + { + int ww = width >> level; + int hh = height >> height; + + byteArray tempBytes = byteArray(ww * hh * depth * 4); + for (int index = 0; index < tempBytes.length; index++) + { + tempBytes[index] = 0; + } + +#ifdef __PS3__ + data[level] = new ByteBuffer_IO(tempBytes.length); +#else + data[level] = ByteBuffer::allocateDirect(tempBytes.length); +#endif // __PS3__ + data[level]->clear(); + data[level]->put(tempBytes); + data[level]->position(0)->limit(tempBytes.length); + + delete [] tempBytes.data; + } + } + + if (immediateUpdate) + { + updateOnGPU(); + } + else + { + updated = false; + } + } + } + else + { + valid = true; + + transferFromImage(image); + + if (mode != TM_CONTAINER) + { + updateOnGPU(); + immediateUpdate = false; + } + } +} + +Texture::Texture(const wstring &name, int mode, int width, int height, int wrapMode, int format, int minFilter, int magFilter, BufferedImage *image, bool mipMap) +{ + _init(name, mode, width, height, 1, wrapMode, format, minFilter, magFilter, image, mipMap); +} + +Texture::Texture(const wstring &name, int mode, int width, int height, int depth, int wrapMode, int format, int minFilter, int magFilter, BufferedImage *image, bool mipMap) +{ + _init(name, mode, width, height, depth, wrapMode, format, minFilter, magFilter, image, mipMap); +} + +Texture::~Texture() +{ + delete rect; + + for(int i = 0; i < 10; i++ ) + { + if(data[i] != NULL) delete data[i]; + } + + if(glId >= 0) + { + glDeleteTextures(glId); + } +} + +const Rect2i *Texture::getRect() +{ + return rect; +} + +void Texture::fill(const Rect2i *rect, int color) +{ + // 4J Remove 3D + //if (type == GL_TEXTURE_3D) + //{ + // return; + //} + + Rect2i *myRect = new Rect2i(0, 0, width, height); + myRect->intersect(rect); + data[0]->position(0); + for (int y = myRect->getY(); y < (myRect->getY() + myRect->getHeight()); y++) + { + int line = y * width * 4; + for (int x = myRect->getX(); x < (myRect->getX() + myRect->getWidth()); x++) + { + data[0]->put(line + x * 4 + 0, (BYTE)((color >> 24) & 0x000000ff)); + data[0]->put(line + x * 4 + 1, (BYTE)((color >> 16) & 0x000000ff)); + data[0]->put(line + x * 4 + 2, (BYTE)((color >> 8) & 0x000000ff)); + data[0]->put(line + x * 4 + 3, (BYTE)((color >> 0) & 0x000000ff)); + } + } + delete myRect; + + if (immediateUpdate) + { + updateOnGPU(); + } + else + { + updated = false; + } +} + +void Texture::writeAsBMP(const wstring &name) +{ + // 4J Don't need +#if 0 + if (type == GL_TEXTURE_3D) + { + return; + } + + File *outFile = new File(name); + if (outFile.exists()) + { + outFile.delete(); + } + + DataOutputStream *outStream = NULL; + //try { + outStream = new DataOutputStream(new FileOutputStream(outFile)); + //} catch (IOException e) { + // Unable to open file for writing for some reason + // return; + //} + + //try { + // Write the header + outStream->writeShort((short)0x424d); // 0x0000: ID - 'BM' + int byteSize = width * height * 4 + 54; + outStream->writeByte((byte)(byteSize >> 0)); // 0x0002: Raw file size + outStream->writeByte((byte)(byteSize >> 8)); + outStream->writeByte((byte)(byteSize >> 16)); + outStream->writeByte((byte)(byteSize >> 24)); + outStream->writeInt(0); // 0x0006: Reserved + outStream->writeByte(54); // 0x000A: Start of pixel data + outStream->writeByte(0); + outStream->writeByte(0); + outStream->writeByte(0); + outStream->writeByte(40); // 0x000E: Size of secondary header + outStream->writeByte(0); + outStream->writeByte(0); + outStream->writeByte(0); + outStream->writeByte((byte)(width >> 0)); // 0x0012: Image width, in pixels + outStream->writeByte((byte)(width >> 8)); + outStream->writeByte((byte)(width >> 16)); + outStream->writeByte((byte)(width >> 24)); + outStream->writeByte((byte)(height >> 0)); // 0x0016: Image height, in pixels + outStream->writeByte((byte)(height >> 8)); + outStream->writeByte((byte)(height >> 16)); + outStream->writeByte((byte)(height >> 24)); + outStream->writeByte(1); // 0x001A: Number of color planes, must be 1 + outStream->writeByte(0); + outStream->writeByte(32); // 0x001C: Bit depth (32bpp) + outStream->writeByte(0); + outStream->writeInt(0); // 0x001E: Compression mode (BI_RGB, uncompressed) + int bufSize = width * height * 4; + outStream->writeInt((byte)(bufSize >> 0)); // 0x0022: Raw size of bitmap data + outStream->writeInt((byte)(bufSize >> 8)); + outStream->writeInt((byte)(bufSize >> 16)); + outStream->writeInt((byte)(bufSize >> 24)); + outStream->writeInt(0); // 0x0026: Horizontal resolution in ppm + outStream->writeInt(0); // 0x002A: Vertical resolution in ppm + outStream->writeInt(0); // 0x002E: Palette size (0 to match bit depth) + outStream->writeInt(0); // 0x0032: Number of important colors, 0 for all + + // Pixels follow in inverted Y order + byte[] bytes = new byte[width * height * 4]; + data.position(0); + data.get(bytes); + for (int y = height - 1; y >= 0; y--) + { + int line = y * width * 4; + for (int x = 0; x < width; x++) + { + outStream->writeByte(bytes[line + x * 4 + 2]); + outStream->writeByte(bytes[line + x * 4 + 1]); + outStream->writeByte(bytes[line + x * 4 + 0]); + outStream->writeByte(bytes[line + x * 4 + 3]); + } + } + + outStream->close(); + //} catch (IOException e) { + // Unable to write to the file for some reason + // return; + //} +#endif +} + +void Texture::writeAsPNG(const wstring &filename) +{ + // 4J Don't need +#if 0 + BufferedImage *image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + ByteBuffer *buffer = this->getData(); + byte[] bytes = new byte[width * height * 4]; + + buffer.position(0); + buffer.get(bytes); + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + int pos = (y * width * 4) + x * 4; + int col = 0; + + col |= (bytes[pos + 2] & 0xFF) << 0; + col |= (bytes[pos + 1] & 0xFF) << 8; + col |= (bytes[pos + 0] & 0xFF) << 16; + col |= (bytes[pos + 3] & 0xFF) << 24; + + image.setRGB(x, y, col); + } + } + + data.position(width * height * 4); + + //try { + ImageIO::write(image, L"png", new File(Minecraft.getWorkingDirectory(), filename)); + //} catch (IOException e) { + // e.printStackTrace(); + //} +#endif +} + +void Texture::blit(int x, int y, Texture *source) +{ + blit(x, y, source, false); +} + +void Texture::blit(int x, int y, Texture *source, bool rotated) +{ + // 4J Remove 3D + //if (type == GL_TEXTURE_3D) + //{ + // return; + //} + + for(unsigned int level = 0; level < m_iMipLevels; ++level) + { + ByteBuffer *srcBuffer = source->getData(level); + + if(srcBuffer == NULL) break; + + int yy = y >> level; + int xx = x >> level; + int hh = height >> level; + int ww = width >> level; + int shh = source->getHeight() >> level; + int sww = source->getWidth() >> level; + + data[level]->position(0); + srcBuffer->position(0); + +#if defined __PS3__ && !defined DISABLE_SPU_CODE + if(g_texBlitJobQueuePort->hasCompleted()) + { + // all outstanding blits have completed, so reset to the start of the blit list + g_currentTexBlit = 0; + } + Texture_blit_DataIn& dataIn = g_textureBlitDataIn[g_currentTexBlit]; + g_currentTexBlit++; + if(g_currentTexBlit >= sc_maxTextureBlits) + { + app.DebugPrintf("ran out of tex blit slots, stalling for completion\n"); + g_texBlitJobQueuePort->waitForCompletion(); + g_currentTexBlit = 0; + } + dataIn.pSrcData = srcBuffer->getBuffer(); + dataIn.pDstData = data[level]->getBuffer(); + dataIn.yy = yy; + dataIn.xx = xx; + dataIn.hh = hh; + dataIn.ww = ww; + dataIn.shh = shh; + dataIn.sww = sww; + dataIn.rotated = rotated; + + C4JSpursJob_Texture_blit blitJob(&dataIn); + g_texBlitJobQueuePort->submitJob(&blitJob); +// p.waitForCompletion(); + +#elif __PSVITA__ + unsigned int *src = (unsigned int *) srcBuffer->getBuffer(); + unsigned int *dst = (unsigned int *) data[level]->getBuffer(); + + for (int srcY = 0; srcY < shh; srcY++) + { + int dstY = yy + srcY; + int srcLine = srcY * sww; + int dstLine = dstY * ww; + + if (rotated) + { + dstY = yy + (shh - srcY); + } + + if (!rotated) + { + memcpy(dst + dstLine + xx, src + srcLine, sww * 4); + } + else + { + for (int srcX = 0; srcX < sww; srcX++) + { + int dstPos = dstLine + (srcX + xx); + int srcPos = srcLine + srcX; + + if (rotated) + { + dstPos = (xx + srcX * ww) + dstY; + } + + dst[dstPos] = src[srcPos]; + } + } + } +#else + + for (int srcY = 0; srcY < shh; srcY++) + { + int dstY = yy + srcY; + int srcLine = srcY * sww * 4; + int dstLine = dstY * ww * 4; + + if (rotated) + { + dstY = yy + (shh - srcY); + } + + for (int srcX = 0; srcX < sww; srcX++) + { + int dstPos = dstLine + (srcX + xx) * 4; + int srcPos = srcLine + srcX * 4; + + if (rotated) + { + dstPos = (xx + srcX * ww * 4) + dstY * 4; + } + + data[level]->put(dstPos + 0, srcBuffer->get(srcPos + 0)); + data[level]->put(dstPos + 1, srcBuffer->get(srcPos + 1)); + data[level]->put(dstPos + 2, srcBuffer->get(srcPos + 2)); + data[level]->put(dstPos + 3, srcBuffer->get(srcPos + 3)); + } + } + // Don't delete this, as it belongs to the source texture + //delete srcBuffer; +#endif + data[level]->position(ww * hh * 4); + } + + if (immediateUpdate) + { + updateOnGPU(); + } + else + { + updated = false; + } +} + +void Texture::transferFromBuffer(intArray buffer) +{ + if (depth == 1) + { + return; + } + +// #ifdef __PS3__ +// int byteRemapRGBA[] = { 3, 0, 1, 2 }; +// int byteRemapBGRA[] = { 3, 2, 1, 0 }; +// #else + int byteRemapRGBA[] = { 0, 1, 2, 3 }; + int byteRemapBGRA[] = { 2, 1, 0, 3 }; +// #endif + int *byteRemap = ((format == TFMT_BGRA) ? byteRemapBGRA : byteRemapRGBA); + + for (int z = 0; z < depth; z++) + { + int plane = z * height * width * 4; + for (int y = 0; y < height; y++) + { + int column = plane + y * width * 4; + for (int x = 0; x < width; x++) + { + int texel = column + x * 4; + data[0]->position(0); + data[0]->put(texel + byteRemap[0], (byte)((buffer[texel >> 2] >> 24) & 0xff)); + data[0]->put(texel + byteRemap[1], (byte)((buffer[texel >> 2] >> 16) & 0xff)); + data[0]->put(texel + byteRemap[2], (byte)((buffer[texel >> 2] >> 8) & 0xff)); + data[0]->put(texel + byteRemap[3], (byte)((buffer[texel >> 2] >> 0) & 0xff)); + } + } + } + + data[0]->position(width * height * depth * 4); + + updateOnGPU(); +} + +void Texture::transferFromImage(BufferedImage *image) +{ + // 4J Remove 3D + //if (type == GL_TEXTURE_3D) + //{ + // return; + //} + + int imgWidth = image->getWidth(); + int imgHeight = image->getHeight(); + if (imgWidth > width || imgHeight > height) + { + //Minecraft::GetInstance().getLogger().warning("transferFromImage called with a BufferedImage with dimensions (" + + // imgWidth + ", " + imgHeight + ") larger than the Texture dimensions (" + width + + // ", " + height + "). Ignoring."); + app.DebugPrintf("transferFromImage called with a BufferedImage with dimensions (%d, %d) larger than the Texture dimensions (%d, %d). Ignoring.\n", imgWidth, imgHeight, width, height); + return; + } + +// #ifdef __PS3__ +// int byteRemapRGBA[] = { 0, 1, 2, 3 }; +// int byteRemapBGRA[] = { 2, 1, 0, 3 }; +// #else +#ifdef _XBOX + int byteRemapRGBA[] = { 0, 1, 2, 3 }; +#else + int byteRemapRGBA[] = { 3, 0, 1, 2 }; +#endif + int byteRemapBGRA[] = { 3, 2, 1, 0 }; +// #endif + int *byteRemap = ((format == TFMT_BGRA) ? byteRemapBGRA : byteRemapRGBA); + + intArray tempPixels = intArray(width * height); + int transparency = image->getTransparency(); + image->getRGB(0, 0, width, height, tempPixels, 0, imgWidth); + + byteArray tempBytes = byteArray(width * height * 4); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int intIndex = y * width + x; + int byteIndex = intIndex * 4; + + // Pull ARGB bytes into either RGBA or BGRA depending on format + + tempBytes[byteIndex + byteRemap[0]] = (byte)((tempPixels[intIndex] >> 24) & 0xff); + tempBytes[byteIndex + byteRemap[1]] = (byte)((tempPixels[intIndex] >> 16) & 0xff); + tempBytes[byteIndex + byteRemap[2]] = (byte)((tempPixels[intIndex] >> 8) & 0xff); + tempBytes[byteIndex + byteRemap[3]] = (byte)((tempPixels[intIndex] >> 0) & 0xff); + } + } + + for(int i = 0; i < 10; i++ ) + { + if(data[i] != NULL) + { + delete data[i]; + data[i] = NULL; + } + } + + MemSect(51); +#ifdef __PS3__ + data[0] = new ByteBuffer_IO(tempBytes.length); +#else + data[0] = ByteBuffer::allocateDirect(tempBytes.length); +#endif // __{S3__ + MemSect(0); + data[0]->clear(); + data[0]->put(tempBytes); + data[0]->limit(tempBytes.length); + + delete [] tempBytes.data; + + if(mipmapped || image->getData(1) != NULL) + { + mipmapped = true; + for(unsigned int level = 1; level < MAX_MIP_LEVELS; ++level) + { + int ww = width >> level; + int hh = height >> level; + + byteArray tempBytes = byteArray(ww * hh * 4); + unsigned int *tempData = new unsigned int[ww * hh]; + + if( image->getData( level ) ) + { + memcpy( tempData, image->getData( level ), ww * hh * 4); + for (int y = 0; y < hh; y++) + { + for (int x = 0; x < ww; x++) + { + int intIndex = y * ww + x; + int byteIndex = intIndex * 4; + + // Pull ARGB bytes into either RGBA or BGRA depending on format + + tempBytes[byteIndex + byteRemap[0]] = (byte)((tempData[intIndex] >> 24) & 0xff); + tempBytes[byteIndex + byteRemap[1]] = (byte)((tempData[intIndex] >> 16) & 0xff); + tempBytes[byteIndex + byteRemap[2]] = (byte)((tempData[intIndex] >> 8) & 0xff); + tempBytes[byteIndex + byteRemap[3]] = (byte)((tempData[intIndex] >> 0) & 0xff); + } + } + } + else + { + int ow = width >> (level - 1); + + for (int x = 0; x < ww; x++) + for (int y = 0; y < hh; y++) + { + int c0 = data[level - 1]->getInt(((x * 2 + 0) + (y * 2 + 0) * ow) * 4); + int c1 = data[level - 1]->getInt(((x * 2 + 1) + (y * 2 + 0) * ow) * 4); + int c2 = data[level - 1]->getInt(((x * 2 + 1) + (y * 2 + 1) * ow) * 4); + int c3 = data[level - 1]->getInt(((x * 2 + 0) + (y * 2 + 1) * ow) * 4); +#ifndef _XBOX + // 4J - convert our RGBA texels to ARGB that crispBlend is expecting + c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( c0 << 24 ); + c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( c1 << 24 ); + c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( c2 << 24 ); + c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( c3 << 24 ); +#endif + int col = crispBlend(crispBlend(c0, c1), crispBlend(c2, c3)); + // 4J - and back from ARGB -> RGBA + //col = ( col << 8 ) | (( col >> 24 ) & 0xff); + //tempData[x + y * ww] = col; + + int intIndex = y * ww + x; + int byteIndex = intIndex * 4; + + // Pull ARGB bytes into either RGBA or BGRA depending on format + + tempBytes[byteIndex + byteRemap[0]] = (byte)((col >> 24) & 0xff); + tempBytes[byteIndex + byteRemap[1]] = (byte)((col >> 16) & 0xff); + tempBytes[byteIndex + byteRemap[2]] = (byte)((col >> 8) & 0xff); + tempBytes[byteIndex + byteRemap[3]] = (byte)((col >> 0) & 0xff); + } + } + + MemSect(51); +#ifdef __PS3__ + data[level] = new ByteBuffer_IO(tempBytes.length); +#else + data[level] = ByteBuffer::allocateDirect(tempBytes.length); +#endif // __{S3__ + MemSect(0); + data[level]->clear(); + data[level]->put(tempBytes); + data[level]->limit(tempBytes.length); + delete [] tempBytes.data; + delete [] tempData; + } + } + + delete [] tempPixels.data; + + if (immediateUpdate) + { + updateOnGPU(); + } + else + { + updated = false; + } +} + +// 4J Kept from older versions for where we create mip-maps for levels that do not have pre-made graphics +int Texture::crispBlend(int c0, int c1) +{ + int a0 = (int) (((c0 & 0xff000000) >> 24)) & 0xff; + int a1 = (int) (((c1 & 0xff000000) >> 24)) & 0xff; + + int a = 255; + if (a0 + a1 < 255) + { + a = 0; + a0 = 1; + a1 = 1; + } + else if (a0 > a1) + { + a0 = 255; + a1 = 1; + } + else + { + a0 = 1; + a1 = 255; + + } + + int r0 = ((c0 >> 16) & 0xff) * a0; + int g0 = ((c0 >> 8) & 0xff) * a0; + int b0 = ((c0) & 0xff) * a0; + + int r1 = ((c1 >> 16) & 0xff) * a1; + int g1 = ((c1 >> 8) & 0xff) * a1; + int b1 = ((c1) & 0xff) * a1; + + int r = (r0 + r1) / (a0 + a1); + int g = (g0 + g1) / (a0 + a1); + int b = (b0 + b1) / (a0 + a1); + + return (a << 24) | (r << 16) | (g << 8) | b; +} + +int Texture::getManagerId() +{ + return managerId; +} + +int Texture::getGlId() +{ + return glId; +} + +int Texture::getWidth() +{ + return width; +} + +int Texture::getHeight() +{ + return height; +} + +wstring Texture::getName() +{ + return name; +} + +void Texture::setImmediateUpdate(bool immediateUpdate) +{ + this->immediateUpdate = immediateUpdate; +} + +void Texture::bind(int mipMapIndex) +{ + // 4J Removed 3D + //if (depth == 1) + //{ + glEnable(GL_TEXTURE_2D); + //} + //else + //{ + // glEnable(GL_TEXTURE_3D); + //} + + glActiveTexture(GL_TEXTURE0 + mipMapIndex); + glBindTexture(type, glId); + if (!updated) + { + updateOnGPU(); + } +} + +void Texture::updateOnGPU() +{ + data[0]->flip(); + if(mipmapped) + { + for (int level = 1; level < m_iMipLevels; level++) + { + if(data[level] == NULL) break; + + data[level]->flip(); + } + } + // 4J remove 3D and 1D + //if (height != 1 && depth != 1) + //{ + // glTexImage3D(type, 0, format, width, height, depth, 0, format, GL_UNSIGNED_BYTE, data); + //} + //else if(height != 1) + //{ + // 4J Added check so we can differentiate between which RenderManager function to call + if(!m_bInitialised) + { + RenderManager.TextureSetTextureLevels(m_iMipLevels); // 4J added + +#ifdef __PSVITA__ + // 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 + // the ram based buffer to it any more inside RenderManager.TextureDataUpdate + unsigned char *newData = RenderManager.TextureData(width,height,data[0]->getBuffer(),0,C4JRender::TEXTURE_FORMAT_RxGyBzAw); + ByteBuffer *oldBuffer = data[0]; + data[0] = new ByteBuffer(data[0]->getSize(), (byte*) newData); + delete oldBuffer; + newData += width * height * 4; +#else + RenderManager.TextureData(width,height,data[0]->getBuffer(),0,C4JRender::TEXTURE_FORMAT_RxGyBzAw); +#endif + + if(mipmapped) + { + for (int level = 1; level < m_iMipLevels; level++) + { + int levelWidth = width >> level; + int levelHeight = height >> level; + +#ifdef __PSVITA__ + // 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 + // the ram based buffer to it any more inside RenderManager.TextureDataUpdate + RenderManager.TextureDataUpdate(0, 0,levelWidth,levelHeight,data[level]->getBuffer(),level); + ByteBuffer *oldBuffer = data[level]; + data[level] = new ByteBuffer(data[level]->getSize(), (byte*) newData); + delete oldBuffer; + newData += levelWidth * levelHeight * 4; +#else + RenderManager.TextureData(levelWidth,levelHeight,data[level]->getBuffer(),level,C4JRender::TEXTURE_FORMAT_RxGyBzAw); +#endif + } + } + + m_bInitialised = true; + } + else + { +#ifdef _XBOX + RenderManager.TextureDataUpdate(data[0]->getBuffer(),0); +#else + RenderManager.TextureDataUpdate(0, 0,width,height,data[0]->getBuffer(),0); +#endif + + if(mipmapped) + { + if (RenderManager.TextureGetTextureLevels() > 1) + { + for (int level = 1; level < m_iMipLevels; level++) + { + int levelWidth = width >> level; + int levelHeight = height >> level; + +#ifdef _XBOX + RenderManager.TextureDataUpdate(data[level]->getBuffer(),level); +#else + RenderManager.TextureDataUpdate(0, 0,levelWidth,levelHeight,data[level]->getBuffer(),level); +#endif + } + } + } + } + //glTexImage2D(type, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + //} + //else + //{ + // glTexImage1D(type, 0, format, width, 0, format, GL_UNSIGNED_BYTE, data); + //} + updated = true; +} + +ByteBuffer *Texture::getData(unsigned int level) +{ + return data[level]; +} |
