OSStatus VisualTextureContainer::initWithFramebuffer(UInt32 xPos, UInt32 yPos, UInt32 width, UInt32 height) { VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); this->releaseTextureData(); this->textureName = theVisualGraphics->getNextFreeTextureName(); this->textureIsSet = true; VisualTextureContainer::textureRefCountMap[this->textureName] = 1; this->useRectExtension = theVisualGraphics->canUseTextureRectExtension(); int prevReadBuffer = theVisualGraphics->getCurrentColorBufferForPixelReadingOperations(); theVisualGraphics->setColorBufferForPixelReadingOperations(kGL_BACK_COLOR_BUFFER); int prevDrawBuffer = theVisualGraphics->getCurrentColorBufferForPixelDrawingOperations(); theVisualGraphics->setColorBufferForPixelDrawingOperations(kGL_BACK_COLOR_BUFFER); theVisualGraphics->enableTexturing(this->useRectExtension); theVisualGraphics->copyFramebufferToTexture(this->textureName, this->useRectExtension, xPos, yPos, width, height, this->pixelFormat, this->dataType); theVisualGraphics->disableTexturing(this->useRectExtension); theVisualGraphics->setColorBufferForPixelDrawingOperations(prevDrawBuffer); theVisualGraphics->setColorBufferForPixelReadingOperations(prevReadBuffer); return noErr; }
PixelColor* VisualTextureContainer::createARGBImagePixels(bool debug) { PixelColor* pixelBuffer = NULL; VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); if (debug == true) { pixelBuffer = VisualColorTools::createARGBCheckPixels(this->textureRect.width, this->textureRect.height); return pixelBuffer; } theVisualGraphics->enableTexturing(this->useRectExtension); theVisualGraphics->bindTexture(this->textureName, this->useRectExtension); theVisualGraphics->setPixelStorageParams(); uint16 format = kGL_BGRA; uint16 type; // GL_BGRA/GL_UNSIGNED_BYTE and GL_BGRA/GL_UNSIGNED_INT_8_8_8_8_REV are equivalent on little endian machines if (this->useRectExtension == false) { pixelBuffer = (PixelColor*)malloc(this->textureRect.width * this->textureRect.height * sizeof(PixelColor)); type = kGL_UNSIGNED_BYTE; theVisualGraphics->getPixelsOfCurrentTexture(this->useRectExtension, format, type, &(pixelBuffer)); #if __BIG_ENDIAN__ VisualColorTools::convertInterleavedPixels1234To4321(pixelBuffer, this->textureRect.width * this->textureRect.height); #endif if ((this->textureRect.width != this->imageRect.width) || (this->textureRect.height != this->imageRect.height)) { // copy actual image pixel data out of texture pixel data Pixel topLeftPosition; topLeftPosition.x = 0; topLeftPosition.y = 0; TopLeftPositionedPixelRect clipRect; clipRect.topLeftPixel = topLeftPosition; clipRect.pixelRect = this->imageRect; PixelColor* clippedPixelData = theVisualGraphics->clipPixelData(pixelBuffer, this->textureRect, clipRect); free(pixelBuffer); pixelBuffer = clippedPixelData; } } else { pixelBuffer = (PixelColor*)malloc(this->imageRect.width * this->imageRect.height * sizeof(PixelColor)); type = kGL_UNSIGNED_INT_8_8_8_8_REV; theVisualGraphics->getPixelsOfCurrentTexture(this->useRectExtension, format, type, &pixelBuffer); } theVisualGraphics->disableTexturing(this->useRectExtension); return pixelBuffer; }
bool VisualTextureContainer::initWithFramebuffer(const BottomLeftPositionedPixelRect& clipRect) { bool success = true; uint16 dataType; uint16 pixelFormat = kGL_BGRA; // BGRA on intel machines and ARGB on ppc #if TARGET_OS_WIN dataType = kGL_UNSIGNED_BYTE; #else #if __BIG_ENDIAN__ dataType = kGL_UNSIGNED_INT_8_8_8_8_REV; #else dataType = kGL_UNSIGNED_INT_8_8_8_8; #endif #endif VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); this->releaseTextureData(); this->textureName = theVisualGraphics->getNextFreeTextureName(); this->aTextureIsSet = true; VisualTextureContainer::textureRefCountMap[this->textureName] = 1; this->useRectExtension = theVisualGraphics->canUseTextureRectExtension(); int prevReadBuffer = theVisualGraphics->getCurrentColorBufferForPixelReadingOperations(); theVisualGraphics->setColorBufferForPixelReadingOperations(kGL_BACK_COLOR_BUFFER); int prevDrawBuffer = theVisualGraphics->getCurrentColorBufferForPixelDrawingOperations(); theVisualGraphics->setColorBufferForPixelDrawingOperations(kGL_BACK_COLOR_BUFFER); theVisualGraphics->enableTexturing(this->useRectExtension); theVisualGraphics->copyFramebufferToTexture(this->textureName, this->useRectExtension, clipRect, pixelFormat, dataType); theVisualGraphics->disableTexturing(this->useRectExtension); theVisualGraphics->setColorBufferForPixelDrawingOperations(prevDrawBuffer); theVisualGraphics->setColorBufferForPixelReadingOperations(prevReadBuffer); this->imageRect.width = clipRect.pixelRect.width; this->imageRect.height = clipRect.pixelRect.height; this->useRectExtension = theVisualGraphics->canUseTextureRectExtension(); if (this->useRectExtension == false) { this->textureRect.width = theVisualGraphics->power2Ceiling(this->imageRect.width); this->textureRect.height = theVisualGraphics->power2Ceiling(this->imageRect.height); } else { this->textureRect.width = this->imageRect.width; this->textureRect.height = this->imageRect.height; } return success; }
void VisualTextureContainer::applyConvolutionFilter(const VisualConvolutionFilter& aConvolutionFilter) { VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); uint16 dataType; uint16 pixelFormat = kGL_BGRA; // BGRA on intel machines and ARGB on ppc #if TARGET_OS_WIN dataType = kGL_UNSIGNED_BYTE; #else #if __BIG_ENDIAN__ dataType = kGL_UNSIGNED_INT_8_8_8_8_REV; #else dataType = kGL_UNSIGNED_INT_8_8_8_8; #endif #endif if (theVisualGraphics->doesSupportGLConvolutionFilter()) { int prevReadBuffer = theVisualGraphics->getCurrentColorBufferForPixelReadingOperations(); theVisualGraphics->setColorBufferForPixelReadingOperations(kGL_BACK_COLOR_BUFFER); int prevDrawBuffer = theVisualGraphics->getCurrentColorBufferForPixelDrawingOperations(); theVisualGraphics->setColorBufferForPixelDrawingOperations(kGL_BACK_COLOR_BUFFER); uint32* prevPixels = NULL; char errStr[512]; uint8 numberOfBytesPerChannel = 0; uint8 numberOfChannels = 0; // channel == color resp. alpha channel uint8 numberOfBytesPerPixel = 0; uint32 numberOfBytesPerRow = 0; if ((pixelFormat == kGL_RGBA) || (pixelFormat == kGL_BGRA)) { numberOfChannels = 4; } else { sprintf(errStr, "unknown format %d in file: %s (line: %d) [%s])", pixelFormat, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return; } if ((dataType == kGL_UNSIGNED_INT_8_8_8_8_REV) || (dataType == kGL_UNSIGNED_INT_8_8_8_8) || (dataType == kGL_UNSIGNED_BYTE)) { numberOfBytesPerChannel = 1; // // 1 byte (== 8 bits) per color/channel } else { sprintf(errStr, "unknown type %d in file: %s (line: %d) [%s])", dataType, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return; } numberOfBytesPerPixel = numberOfBytesPerChannel * numberOfChannels; numberOfBytesPerRow = numberOfBytesPerPixel * this->textureRect.width; // read previous pixels if ((pixelFormat == kGL_RGBA) || (pixelFormat == kGL_BGRA)) { prevPixels = (uint32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureRect.height, numberOfBytesPerPixel); } VisualCamera aCamera; aCamera.setOrthographicProjection(); theVisualGraphics->readPixels(aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->textureRect.width, this->textureRect.height, &prevPixels, pixelFormat, dataType, aCamera); PixelColor* pixels = NULL; pixels = this->createARGBImagePixels(); if (pixels == NULL) { sprintf(errStr, "pixels == NULL in file: %s (line: %d) [%s])", __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return; } theVisualGraphics->drawPixels(&pixels, aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->imageRect.width, this->imageRect.height, pixelFormat, dataType, &aConvolutionFilter); free(pixels); pixels = NULL; BottomLeftPositionedPixelRect clipRect; clipRect.bottomLeftPixel.x = 0; clipRect.bottomLeftPixel.y = 0; clipRect.pixelRect.width = this->textureRect.width; clipRect.pixelRect.height = this->textureRect.height; theVisualGraphics->enableTexturing(this->useRectExtension); theVisualGraphics->copyFramebufferToTexture(this->textureName, this->useRectExtension, clipRect, pixelFormat, dataType); theVisualGraphics->disableTexturing(this->useRectExtension); // restore previous pixels theVisualGraphics->drawPixels(&prevPixels, aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->textureRect.width, this->textureRect.height, pixelFormat, dataType); free(prevPixels); theVisualGraphics->setColorBufferForPixelDrawingOperations(prevDrawBuffer); theVisualGraphics->setColorBufferForPixelReadingOperations(prevReadBuffer); } else { PixelColor* pixels = this->createARGBImagePixels(); PixelColor* filteredPixels = NULL; aConvolutionFilter.applyToPixelData(pixels, this->imageRect.width, this->imageRect.height, pixelFormat, dataType, &filteredPixels); free(pixels); pixels = NULL; bool success = false; const PixelColor* constFilteredPixels = const_cast<const PixelColor*>(filteredPixels); success = theVisualGraphics->copyARGBBitmapDataToTexture(this->textureName, this->imageRect.width, this->imageRect.height, this->useRectExtension, &constFilteredPixels); if (filteredPixels != NULL) { free(filteredPixels); } } }
UInt32* VisualTextureContainer::getTexturePixels(const UInt16 format, const UInt16 type) { bool debug = false; UInt8* pixelBuffer8Bit = NULL; char errStr[256]; VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); if (debug == true) { if (this->pixelBuffer != NULL) { free(this->pixelBuffer); this->pixelBuffer = NULL; } this->pixelBuffer = theVisualGraphics->createARGBCheckPixels(this->textureWidth, this->textureHeight); return this->pixelBuffer; } if ((debug == false) && (this->pixelBuffer != NULL)) { //return this->pixelBuffer; } UInt8 numberOfBytesPerChannel = 0; UInt8 numberOfChannels = 0; // channel == color resp. alpha channel UInt8 numberOfBytesPerPixel = 0; UInt32 numberOfBytesPerRow = 0; if ((format == kGL_RGBA) || (format == kGL_BGRA)) { numberOfChannels = 4; } else { sprintf(errStr, "unknown format %d in file: %s (line: %d) [%s])", format, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return this->pixelBuffer; } if ((type == kGL_UNSIGNED_INT_8_8_8_8_REV) || (type == kGL_UNSIGNED_INT_8_8_8_8) || (type == kGL_UNSIGNED_BYTE)) { numberOfBytesPerChannel = 1; // 1 byte (== 8 bits) per color/channel } else { sprintf(errStr, "unknown type %d in file: %s (line: %d) [%s])", type, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return this->pixelBuffer; } if (this->pixelBuffer != NULL) { free(this->pixelBuffer); this->pixelBuffer = NULL; } if (this->useRectExtension == false) { numberOfBytesPerPixel = numberOfBytesPerChannel * numberOfChannels; numberOfBytesPerRow = numberOfBytesPerPixel * this->textureWidth; if ((format == kGL_RGBA) || (format == kGL_BGRA)) { if ((type == kGL_UNSIGNED_INT_8_8_8_8_REV) || (type == kGL_UNSIGNED_INT_8_8_8_8)) { this->pixelBuffer = (UInt32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureHeight, numberOfBytesPerPixel); } else if (type == kGL_UNSIGNED_BYTE) { this->pixelBuffer = (UInt32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureHeight, numberOfBytesPerPixel); pixelBuffer8Bit = (UInt8*)malloc(this->textureWidth * this->textureHeight * 4); } } theVisualGraphics->enableTexturing(this->useRectExtension); theVisualGraphics->bindTexture(this->textureName, this->useRectExtension); theVisualGraphics->setPixelStorageParams(); if ((type == kGL_UNSIGNED_INT_8_8_8_8_REV) || (type == kGL_UNSIGNED_INT_8_8_8_8)) { theVisualGraphics->get32BitPixelsOfCurrentTexture(this->useRectExtension, format, type, &(this->pixelBuffer)); } else if (type == kGL_UNSIGNED_BYTE) { theVisualGraphics->get8BitPixelsOfCurrentTexture(this->useRectExtension, format, type, &pixelBuffer8Bit); } theVisualGraphics->disableTexturing(this->useRectExtension); } else { #if TARGET_OS_MAC // glGetTexImage() does not always reliably return the pixelBuffer // of npot (non-power-of-two, GL_TEXTURE_RECTANGLE_EXT) textures // because of inconsistencies with Nvidia's GeForce4 MX card (1.4.18) [only with some not all textures the pixel data was returned] // we grab the pixels with glReadPixels() // (HW, 20070208) this->pixelBuffer = this->getRectPixels(format, type); #endif } if (type == kGL_UNSIGNED_BYTE) { UInt32 b, g, r, a, color32bit; UInt32 pixelBufferIdx = 0; UInt32 pixelBuffer8BitIdx = 0; for (UInt32 i = 0; i < this->textureHeight; i++) { for (UInt32 k = 0; k < this->textureWidth; k++) { b = pixelBuffer8Bit[pixelBuffer8BitIdx + 0] << 24; g = pixelBuffer8Bit[pixelBuffer8BitIdx + 1] << 16; r = pixelBuffer8Bit[pixelBuffer8BitIdx + 2] << 8; a = pixelBuffer8Bit[pixelBuffer8BitIdx + 3]; color32bit = b | g | r | a; this->pixelBuffer[pixelBufferIdx] = color32bit; pixelBufferIdx++; pixelBuffer8BitIdx += 4; } } free(pixelBuffer8Bit); } return this->pixelBuffer; }