OK the following is what I've come up with, and it seems to be working. Please review provide any additional help or optimizations.
first, to setup the texture and image I the following, once, beforehand.
Code: Select all
Ogre::Image2 createImageData() {
const Ogre::uint32 texWidth = 512;
const Ogre::uint32 texHeight = 512;
const Ogre::PixelFormatGpu texFormat = Ogre::PixelFormatGpu::PFG_RGBA8_UNORM_SRGB;
//Fill the texture with a hollow rectangle, 10-pixel thick.
size_t sizeBytes = Ogre::PixelFormatGpuUtils::calculateSizeBytes(
texWidth, texHeight, 1u, 1u, texFormat, 1u, 4u);
Ogre::uint8* data = reinterpret_cast<Ogre::uint8*>(
OGRE_MALLOC_SIMD(sizeBytes, Ogre::MEMCATEGORY_GENERAL));
Ogre::Image2 image;
image.loadDynamicImage(data, texWidth, texHeight, 1u,
Ogre::TextureTypes::Type2D, texFormat,
true, 1u);
return image;
}
Ogre::Image2 createManualTexture(Graphics& graphics, GraphicalObject::Ptr obj) {
Ogre::Root* root = graphics.getRoot();
Ogre::TextureGpuManager* textureMgr = root->getRenderSystem()->getTextureGpuManager();
Ogre::TextureGpu* manualTex =
textureMgr->createOrRetrieveTexture(
"manualTexture",
Ogre::GpuPageOutStrategy::AlwaysKeepSystemRamCopy,
Ogre::TextureFlags::AutomaticBatching,
Ogre::TextureTypes::Type2D, Ogre::BLANKSTRING);
manualTex->setNumMipmaps(1);
manualTex->setResolution(512, 512);
manualTex->setPixelFormat(Ogre::PixelFormatGpu::PFG_RGBA8_UNORM_SRGB);
Ogre::Image2 image = createImageData();
bool canUseSynchronousUpload = manualTex->getNextResidencyStatus() == Ogre::GpuResidency::Resident && manualTex->isDataReady();
if (!canUseSynchronousUpload) {
manualTex->waitForData();
}
manualTex->scheduleTransitionTo(Ogre::GpuResidency::Resident, &image, false);
Ogre::HlmsManager* hlmsManager = graphics.getRoot()->getHlmsManager();
Ogre::HlmsPbs* hlmsPbs = static_cast<Ogre::HlmsPbs*>(hlmsManager->getHlms(Ogre::HLMS_PBS));
Ogre::String dataBlockName = "customDataBlock";
Ogre::HlmsPbsDatablock* datablock = static_cast<Ogre::HlmsPbsDatablock*>(
hlmsPbs->createDatablock(dataBlockName,
dataBlockName,
Ogre::HlmsMacroblock(),
Ogre::HlmsBlendblock(),
Ogre::HlmsParamVec()
));
datablock->setTexture(Ogre::PbsTextureTypes::PBSM_DIFFUSE, manualTex);
obj->getItem()->setDatablock(datablock);
return image;
}
now each frame, I do the following to change the color/data:
Code: Select all
void setRandomColor(Graphics& graphics, Ogre::Image2& image) {
Ogre::uint8* data = reinterpret_cast<Ogre::uint8*>(image.getData(0).data);
int r = rand() % 2 * 255;
int g = rand() % 2 * 255;
int b = rand() % 2 * 255;
for (size_t y = 0; y < image.getHeight(); ++y) {
for (size_t x = 0; x < image.getWidth(); ++x) {
*data++ = r;
*data++ = g;
*data++ = b;
*data++ = 255;
}
}
Ogre::TextureGpuManager* textureMgr = graphics.getRoot()->getRenderSystem()->getTextureGpuManager();
Ogre::TextureGpu* manualTexture = textureMgr->findTextureNoThrow("manualTexture");
bool canUseSynchronousUpload = manualTexture->getNextResidencyStatus() == Ogre::GpuResidency::Resident && manualTexture->isDataReady();
if (!canUseSynchronousUpload) {
manualTexture->waitForData();
}
image.uploadTo(manualTexture, 0, 0);
}
finally, to clean up:
Code: Select all
void cleanUp(Graphics& graphics, Ogre::Image2& image) {
Ogre::TextureGpuManager* textureMgr = graphics.getRoot()->getRenderSystem()->getTextureGpuManager();
Ogre::TextureGpu* manualTexture = textureMgr->findTextureNoThrow("manualTexture");
textureMgr->destroyTexture(manualTexture);
image.freeMemory();
}
Thanks for the help!