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); } } }
void VisualTextureContainer::applyConvolutionFilter(const VisualConvolutionFilter& aConvolutionFilter) { VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); 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 ((this->pixelFormat == kGL_RGBA) || (this->pixelFormat == kGL_BGRA)) { numberOfChannels = 4; } else { sprintf(errStr, "unknown format %d in file: %s (line: %d) [%s])", this->pixelFormat, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return; } if ((this->dataType == kGL_UNSIGNED_INT_8_8_8_8_REV) || (this->dataType == kGL_UNSIGNED_INT_8_8_8_8) || (this->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])", this->dataType, __FILE__, __LINE__, __FUNCTION__); writeLog(errStr); return; } numberOfBytesPerPixel = numberOfBytesPerChannel * numberOfChannels; numberOfBytesPerRow = numberOfBytesPerPixel * this->textureWidth; // read previous pixels if ((this->pixelFormat == kGL_RGBA) || (this->pixelFormat == kGL_BGRA)) { prevPixels = (UInt32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureHeight, numberOfBytesPerPixel); } theVisualGraphics->readPixels(theVisualGraphics->getMaxLeftCoordOfCanvas(), theVisualGraphics->getMaxBottomCoordOfCanvas(), this->textureWidth, this->textureHeight, &prevPixels, this->pixelFormat, this->dataType); UInt32* pixels = this->getTexturePixels(this->pixelFormat, this->dataType); UInt32* passedPixels = (UInt32*)malloc(this->textureWidth * this->textureHeight * 4); memcpy(passedPixels, pixels, this->textureWidth * this->textureHeight * 4); // VisualStudio does not like when we pass a non-const pointer to instance variable (crashes in runtime) theVisualGraphics->drawPixels((UInt32**)&(passedPixels), theVisualGraphics->getMaxLeftCoordOfCanvas(), theVisualGraphics->getMaxBottomCoordOfCanvas(), this->textureWidth, this->textureHeight, this->pixelFormat, this->dataType, &aConvolutionFilter); if (passedPixels != NULL) { free(passedPixels); passedPixels = NULL; } theVisualGraphics->copyFramebufferToTexture(this->textureName, this->useRectExtension, 0, 0, this->textureWidth, this->textureHeight, this->pixelFormat, this->dataType); // restore previous pixels theVisualGraphics->drawPixels(&prevPixels, theVisualGraphics->getMaxLeftCoordOfCanvas(), theVisualGraphics->getMaxBottomCoordOfCanvas(), this->textureWidth, this->textureHeight, this->pixelFormat, this->dataType); free(prevPixels); theVisualGraphics->setColorBufferForPixelDrawingOperations(prevDrawBuffer); theVisualGraphics->setColorBufferForPixelReadingOperations(prevReadBuffer); if (this->pixelBuffer != NULL) { free(this->pixelBuffer); this->pixelBuffer = NULL; } }
PixelColor* VisualTextureContainer::createReadPixels(const uint16 format, const uint16 type) { PixelColor* pixels = NULL; PixelColor* prevPixels = NULL; char errStr[512]; double scaleFactor = 1.0; 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 pixels; } 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 pixels; } numberOfBytesPerPixel = numberOfBytesPerChannel * numberOfChannels; numberOfBytesPerRow = numberOfBytesPerPixel * this->textureRect.width; VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); Coord coord; VisualCamera aCamera; aCamera.setOrthographicProjection(); coord.x = aCamera.getMaxLeftCoord() * scaleFactor; coord.y = (aCamera.getMaxBottomCoord() + theVisualGraphics->yPixelToCoord(this->textureRect.height, aCamera)) * scaleFactor; coord.z = aCamera.getMaxNearPos(); VertexChain aVertexChain; TexCoord texCoord; texCoord.s = 0.0; texCoord.t = this->getTextureLogicalHeight(); VisualVertex* topLeftFrontVertex = new VisualVertex(coord, texCoord, white); aVertexChain.push_back(topLeftFrontVertex); coord.x = aCamera.getMaxLeftCoord() * scaleFactor; coord.y = aCamera.getMaxBottomCoord() * scaleFactor; coord.z = aCamera.getMaxNearPos(); texCoord.s = 0.0; texCoord.t = 0.0; VisualVertex* bottomLeftFrontVertex = new VisualVertex(coord, texCoord, white); aVertexChain.push_back(bottomLeftFrontVertex); coord.x = (aCamera.getMaxLeftCoord() + theVisualGraphics->xPixelToCoord(this->textureRect.width, aCamera)) * scaleFactor; coord.y = aCamera.getMaxBottomCoord() * scaleFactor; coord.z = aCamera.getMaxNearPos(); texCoord.s = this->getTextureLogicalWidth(); texCoord.t = 0.0; VisualVertex* bottomRightFrontVertex = new VisualVertex(coord, texCoord, white); aVertexChain.push_back(bottomRightFrontVertex); coord.x = (aCamera.getMaxLeftCoord() + theVisualGraphics->xPixelToCoord(this->textureRect.width, aCamera)) * scaleFactor; coord.y = (aCamera.getMaxBottomCoord() + theVisualGraphics->yPixelToCoord(this->textureRect.height, aCamera)) * scaleFactor; coord.z = aCamera.getMaxNearPos(); texCoord.s = this->getTextureLogicalWidth(); texCoord.t = this->getTextureLogicalHeight(); VisualVertex* topRightFrontVertex = new VisualVertex(coord, texCoord, white); aVertexChain.push_back(topRightFrontVertex); // read previous pixels if ((format == kGL_RGBA) || (format == kGL_BGRA)) { prevPixels = (uint32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureRect.height, numberOfBytesPerPixel); } theVisualGraphics->readPixels(aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->textureRect.width, this->textureRect.height, &prevPixels, format, type, aCamera); // draw current texture theVisualGraphics->drawTexture(this->textureName, &aVertexChain, this->getUseRectExtension(), kReplace); // read pixels of current texture if ((format == kGL_RGBA) || (format == kGL_BGRA)) { pixels = (uint32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureRect.height, numberOfBytesPerPixel); } theVisualGraphics->readPixels(aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->textureRect.width, this->textureRect.height, &pixels, format, type, aCamera); // restore previous pixels theVisualGraphics->drawPixels(&prevPixels, aCamera.getMaxLeftCoord(), aCamera.getMaxBottomCoord(), this->textureRect.width, this->textureRect.height, format, type); for (VertexChainIterator chainIt = aVertexChain.begin(); chainIt != aVertexChain.end(); chainIt++) { delete *chainIt; *chainIt = NULL; } aVertexChain.clear(); free(prevPixels); return pixels; }
UInt32* VisualTextureContainer::getRectPixels(const UInt16 format, const UInt16 type) { UInt32* pixels = NULL; UInt32* prevPixels = NULL; char errStr[512]; double scaleFactor = 1.0; 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 pixels; } 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 pixels; } numberOfBytesPerPixel = numberOfBytesPerChannel * numberOfChannels; numberOfBytesPerRow = numberOfBytesPerPixel * this->textureWidth; VisualStageBox stageBox; VisualStagePosition position; position.horizontalAlignment = kLeftAligned; position.verticalAlignment = kBottomAligned; stageBox.setVisualStagePosition(position); stageBox.setContentPixelWidth(this->getImageWidth()); stageBox.setContentPixelHeight(this->getImageHeight()); VertexChain aVertexChain; Vertex* topLeftFrontVertex = new Vertex; topLeftFrontVertex->vertexPosition.xPos = stageBox.getLeftCoord() * scaleFactor; topLeftFrontVertex->vertexPosition.yPos = stageBox.getTopCoord() * scaleFactor; topLeftFrontVertex->vertexPosition.zPos = stageBox.getFrontPosition(); topLeftFrontVertex->vertexColor.r = 1.0f; topLeftFrontVertex->vertexColor.g = 1.0f; topLeftFrontVertex->vertexColor.b = 1.0f; topLeftFrontVertex->vertexColor.a = 1.0f; topLeftFrontVertex->texCoordPosition.sPos = 0.0f; topLeftFrontVertex->texCoordPosition.tPos = this->getTextureLogicalHeight(); aVertexChain.push_back(topLeftFrontVertex); Vertex* bottomLeftFrontVertex = new Vertex; bottomLeftFrontVertex->vertexPosition.xPos = stageBox.getLeftCoord() * scaleFactor; bottomLeftFrontVertex->vertexPosition.yPos = stageBox.getBottomCoord() * scaleFactor; bottomLeftFrontVertex->vertexPosition.zPos = stageBox.getFrontPosition(); bottomLeftFrontVertex->vertexColor.r = 1.0f; bottomLeftFrontVertex->vertexColor.g = 1.0f; bottomLeftFrontVertex->vertexColor.b = 1.0f; bottomLeftFrontVertex->vertexColor.a = 1.0f; bottomLeftFrontVertex->texCoordPosition.sPos = 0.0f; bottomLeftFrontVertex->texCoordPosition.tPos = 0.0f; aVertexChain.push_back(bottomLeftFrontVertex); Vertex* bottomRightFrontVertex = new Vertex; bottomRightFrontVertex->vertexPosition.xPos = stageBox.getRightCoord() * scaleFactor; bottomRightFrontVertex->vertexPosition.yPos = stageBox.getBottomCoord() * scaleFactor; bottomRightFrontVertex->vertexPosition.zPos = stageBox.getFrontPosition(); bottomRightFrontVertex->vertexColor.r = 1.0f; bottomRightFrontVertex->vertexColor.g = 1.0f; bottomRightFrontVertex->vertexColor.b = 1.0f; bottomRightFrontVertex->vertexColor.a = 1.0f; bottomRightFrontVertex->texCoordPosition.sPos = this->getTextureLogicalWidth(); bottomRightFrontVertex->texCoordPosition.tPos = 0.0f; aVertexChain.push_back(bottomRightFrontVertex); Vertex* topRightFrontVertex = new Vertex; topRightFrontVertex->vertexPosition.xPos = stageBox.getRightCoord() * scaleFactor; topRightFrontVertex->vertexPosition.yPos = stageBox.getTopCoord() * scaleFactor; topRightFrontVertex->vertexPosition.zPos = stageBox.getFrontPosition(); topRightFrontVertex->vertexColor.r = 1.0f; topRightFrontVertex->vertexColor.g = 1.0f; topRightFrontVertex->vertexColor.b = 1.0f; topRightFrontVertex->vertexColor.a = 1.0f; topRightFrontVertex->texCoordPosition.sPos = this->getTextureLogicalWidth(); topRightFrontVertex->texCoordPosition.tPos = this->getTextureLogicalHeight(); aVertexChain.push_back(topRightFrontVertex); VisualGraphics* theVisualGraphics = VisualGraphics::getInstance(); // read previous pixels if ((format == kGL_RGBA) || (format == kGL_BGRA)) { prevPixels = (UInt32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureHeight, numberOfBytesPerPixel); } theVisualGraphics->readPixels(stageBox.getLeftCoord(), stageBox.getBottomCoord(), this->textureWidth, this->textureHeight, &prevPixels, format, type); // draw current texture theVisualGraphics->drawTexture(this->textureName, &aVertexChain, this->getUseRectExtension(), kReplace); // read pixels of current texture if ((format == kGL_RGBA) || (format == kGL_BGRA)) { pixels = (UInt32*)calloc((numberOfBytesPerRow / numberOfBytesPerPixel) * this->textureHeight, numberOfBytesPerPixel); } theVisualGraphics->readPixels(stageBox.getLeftCoord(), stageBox.getBottomCoord(), this->textureWidth, this->textureHeight, &pixels, format, type); // restore previous pixels theVisualGraphics->drawPixels(&prevPixels, stageBox.getLeftCoord(), stageBox.getBottomCoord(), this->textureWidth, this->textureHeight, format, type); for (VertexChainIterator chainIt = aVertexChain.begin(); chainIt != aVertexChain.end(); chainIt++) { delete *chainIt; *chainIt = NULL; } aVertexChain.clear(); free(prevPixels); return pixels; }