[SOLVED] Overriding texture compression

I seem to have stumbled upon the same issue here (Using the global compressed-textures flag means you can’t overwrite it on a case-by-case basis):
bugs.launchpad.net/panda3d/+bug/1034100

Namely, I’d like to turn off compression for one of my textures, since I’m editing it on the fly using PNMImage.setRed(). With compression on, this leads to rather imprecise results.

The workaround stated says about converting the PNMImage into a bytestream, which can then passed to Texture.setRamImage()

How exactly does one get a bytestream from a PNMImage? I can’t see anything in the documentation to support it?

Or should I just forget about using PNMImage in this usecase, and initially use a Texture(), which I can then use Texture.modifyRamImage()?

Heres a python snippet that replicates the bug. with compression off, out.png should be the same as out2.png.

from pandac.PandaModules import loadPrcFileData

loadPrcFileData('', 'compressed-textures 1')

import random
from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import PNMImage
from pandac.PandaModules import Texture
from panda3d.core import Filename

class Game(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        img = PNMImage()
        img.read(Filename('in.png'))


        img.setRed(10,10,255)
        img.write(Filename('out.png'))

        myTex = Texture()
        myTex.setCompression(Texture.CMOff)
        myTex.load(img)
        myTex.setCompression(Texture.CMOff)

        myTex.write(Filename('out2.png'))

game = Game()
game.run()

Durrr, I dont need to use PNMImage at all.

For anyone playing along, heres a snippet that’ll change one pixel using modifyRamImage, which seems to honor compression being turned off:

from pandac.PandaModules import loadPrcFileData

loadPrcFileData('', 'compressed-textures 1')

import random, array
from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import PNMImage
from pandac.PandaModules import Texture
from panda3d.core import Filename

class Game(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        img = PNMImage(64,64)

        myTex = loader.loadTexture("in.png")
        myTex.setCompression(Texture.CMOff)
        myTex.store(img, 64, 64)

        img2 = myTex.modifyRamImage()
        buf = array.array('B')
        buf.fromstring(img2.getData())

        buf[0] = int(255)
        buf[1] = int(255) 
        buf[2] = int(255) 

        img2.setData(buf.tostring())

        myTex.write(Filename('out2.png'))


game = Game()
game.run()