def setupTexture(self): """ This is the overlay/decal/etc. which contains the typed characters. The texture size and the font size are currently tied together. :return: """ self.texImage = PNMImage(1024, 1024) self.texImage.addAlpha() self.texImage.fill(1.0) self.texImage.alphaFill(1.0) self.tex = Texture('typing') self.tex.setMagfilter(Texture.FTLinear) self.tex.setMinfilter(Texture.FTLinear) self.typingStage = TextureStage('typing') self.typingStage.setMode(TextureStage.MModulate) self.tex.load(self.texImage) # ensure we can quickly update subimages self.tex.setKeepRamImage(True) # temp for drawing chars self.chImage = PNMImage(*self.fontCharSize)
def __init__(self, parent, minSat, maxSat, minVal, maxVal, callback, pos=(0, 0, 0)): NodePath.__init__(self, 'colorPicker') self.reparentTo(parent) self.setPos(pos) self.minSat = minSat self.maxSat = maxSat self.minVal = minVal self.maxVal = maxVal self.callback = callback self.lastColor = None self.image = PNMImage(int((self.maxSat - self.minSat) * 100), int((self.maxVal - self.minVal) * 100)) self.slider = DirectSlider(self, relief=None, image='phase_3/maps/color_picker_hue.jpg', scale=0.3, pos=(0.2, 0, 0), image_scale=(0.1, 1.0, 1.0), pageSize=5, orientation=DGG.VERTICAL, command=self.__chooseHue) self.button = DirectButton(self, relief=None, image=OTPGlobals.getTransparentTexture(), scale=0.3, pos=(-0.2, 0, 0), frameColor=(1, 1, 1, 0.1), pressEffect=0) self.button.bind(DGG.B1PRESS, self.__startPick) self.button.bind(DGG.B1RELEASE, self.__stopPick) self.__chooseHue() return
def doFreezeCam(self): taskMgr.remove("lookAtKiller") self.frameBuffer = PNMImage() base.win.getScreenshot(self.frameBuffer) self.freezeCamTex = Texture() self.freezeCamTex.load(self.frameBuffer) self.freezeCamImage = OnscreenImage(image = self.freezeCamTex, parent=render2d)
def test_sphere_into_heightfield(): root = NodePath("root") world = BulletWorld() # Create PNMImage to construct Heightfield with img = PNMImage(10, 10, 1) img.fill_val(255) # Make our nodes heightfield = make_node("Heightfield", BulletHeightfieldShape, img, 1, ZUp) sphere = make_node("Sphere", BulletSphereShape, 1) # Attach to world np1 = root.attach_new_node(sphere) np1.set_pos(0, 0, 1) world.attach(sphere) np2 = root.attach_new_node(heightfield) np2.set_pos(0, 0, 0) world.attach(heightfield) assert world.get_num_rigid_bodies() == 2 test = world.contact_test_pair(sphere, heightfield) assert test.get_num_contacts() > 0 assert test.get_contact(0).get_node0() == sphere assert test.get_contact(0).get_node1() == heightfield # Increment sphere's Z coordinate, no longer colliding np1.set_pos(0, 0, 2) test = world.contact_test_pair(sphere, heightfield) assert test.get_num_contacts() == 0
def __init__(self): load_prc_file_data("", """ textures-power-2 none window-type offscreen win-size 100 100 gl-coordinate-system default notify-level-display error print-pipe-types #f """) ShowBase.__init__(self) dest_tex = Texture() dest_tex.setup_2d_texture(2048, 2048, Texture.T_unsigned_byte, Texture.F_rgba8) cshader = Shader.load_compute(Shader.SL_GLSL, "grain.compute.glsl") node = NodePath("") node.set_shader(cshader) node.set_shader_input("DestTex", dest_tex) attr = node.get_attrib(ShaderAttrib) self.graphicsEngine.dispatch_compute( (2048 // 16, 2048 // 16, 1), attr, self.win.get_gsg()) base.graphicsEngine.extract_texture_data(dest_tex, base.win.get_gsg()) # Convert to single channel img = PNMImage(2048, 2048, 1, 255) dest_tex.store(img) img.set_num_channels(1) tex = Texture() tex.load(img) tex.write("grain.txo.pz")
def setupBackgroundImage(self): image_file = Filename(TestGameBase.__BACKGROUND_IMAGE_PATH__) # check if image can be loaded img_head = PNMImageHeader() if not img_head.readHeader(image_file ): raise IOError("PNMImageHeader could not read file %s. Try using absolute filepaths"%(image_file.c_str())) sys.exit() # Load the image with a PNMImage w = img_head.getXSize() h = img_head.getYSize() img = PNMImage(w,h) #img.alphaFill(0) img.read(image_file) texture = Texture() texture.setXSize(w) texture.setYSize(h) texture.setZSize(1) texture.load(img) texture.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image texture.setWrapV(Texture.WM_border_color) texture.setBorderColor(LColor(0,0,0,0)) # creating CardMaker to hold the texture cm = CardMaker('background') cm.setFrame(-0.5*w,0.5*w,-0.5*h,0.5*h) # This configuration places the image's topleft corner at the origin (left, right, bottom, top) background_np = NodePath(cm.generate()) background_np.setTexture(texture) background_np.reparentTo(self.render) background_np.setPos(TestGameBase.__BACKGROUND_POSITION__) background_np.setScale(TestGameBase.__BACKGROUND_SCALE__)
def __init__(self, world, app): self.world = world self.image = PNMImage(self.world.width, 256) for z in self.world.zlevels(): for x in range(self.world.height): mix = sum([ZMap.COLORS[self.world.get_block(x, y, z).substance] for y in range(self.world.height)], VBase3F(0.0)) self.image.setXel(x, z, mix / float(self.world.height)) self.texture = Texture() self.texture.load(self.image) self.texture.setMagfilter(Texture.FTNearest) self.texture.setMinfilter(Texture.FTNearest) cm = CardMaker('zmap') cm.setFrame(0.95, 1, -1, 1) cm.setUvRange(Point2(1.0, 1.0), Point2(0.0, 1.0 - self.world.depth / 256.0)) self.zcard = app.render2d.attachNewNode(cm.generate()) self.zcard.setTexture(self.texture) cm = CardMaker('zpointer') cm.setFrame(0, 0.05, 0, 1.0 / self.world.depth) self.zpointer = app.render2d.attachNewNode(cm.generate()) self.zpointer.setColorScale(1.0, 0.0, 0.0, 0.4) self.accept('slice-changed', self.slice_changed)
def GenerateNavmeshCSV(map, output): #check the map size map_size = map.getReadXSize() #make it square if map.getReadYSize() != map_size: new_map = PNMImage(map_size, map_size) new_map.boxFilterFrom(0.0, map) map = new_map #generate data nods = [] for y in range(0, map_size): for x in range(0, map_size): nods += GetNeighbors((x, y), map, map_size) #write data with open(output, 'w') as output_file: #header output_file.write('Grid Size,' + str(map_size) + '\n') output_file.write( 'NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ\n') #data... for nod in nods: output_file.write( '{NULL},{NodeType},{GridX},{GridY},{Length},{Width},{Height},{PosX},{PosY},{PosZ}\n' .format(**nod))
def __init__(self, base: ShowBase, pick_colour_callback: Callable[ [Tuple[float, float, float, float]], None], **kwargs) -> None: self.__base = base self.pick_colour_callback = pick_colour_callback self.enabled = True # PALETTE # palette_filename = os.path.join(GUI_DATA_PATH, "colour_palette.png") self.__palette_img = PNMImage( Filename.fromOsSpecific(palette_filename)) self.__palette_size = (self.__palette_img.getReadXSize(), self.__palette_img.getReadYSize()) self.__palette_frame = DirectFrame(image=palette_filename, **kwargs) self.__palette_frame['state'] = DGG.NORMAL self.__palette_frame.bind(DGG.B1PRESS, command=self.__pick) # MARKER # self.__marker = DirectFrame(parent=self.__palette_frame, frameColor=(0.0, 0.0, 0.0, 1.0), frameSize=(-0.08, .08, -.08, .08), pos=(0.0, 0.0, 0.0)) self.__marker_center = DirectFrame(parent=self.__marker, frameSize=(-0.03, 0.03, -0.03, 0.03)) self.__marker.hide()
def test_pnmimage_to_val(): img = PNMImage(1, 1) assert img.to_val(-0.5) == 0 assert img.to_val(0.0) == 0 assert img.to_val(0.5) == 128 assert img.to_val(1.0) == 255 assert img.to_val(2.0) == 255
def loadFlatQuad(self, fullFilename): cm = CardMaker('cm-%s' % fullFilename) cm.setColor(1.0, 1.0, 1.0, 1.0) aspect = base.camLens.getAspectRatio() htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH) htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT) cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0) bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1) bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1) cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1)) card = cm.generate() quad = NodePath(card) jpgFile = PNMImage(WEB_WIDTH, WEB_HEIGHT) smallerJpgFile = PNMImage() readFile = smallerJpgFile.read(Filename(fullFilename)) if readFile: jpgFile.copySubImage(smallerJpgFile, 0, 0) guiTex = Texture('guiTex') guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba) guiTex.setMinfilter(Texture.FTLinear) guiTex.load(jpgFile) guiTex.setWrapU(Texture.WMClamp) guiTex.setWrapV(Texture.WMClamp) ts = TextureStage('webTS') quad.setTexture(ts, guiTex) quad.setTransparency(0) quad.setTwoSided(True) quad.setColor(1.0, 1.0, 1.0, 1.0) result = quad else: result = None Texture.setTexturesPower2(1) return result
def __init__(self): load_prc_file_data( "", """ textures-power-2 none window-type offscreen win-size 100 100 gl-coordinate-system default notify-level-display error print-pipe-types #f """) ShowBase.__init__(self) dest_tex = Texture() dest_tex.setup_2d_texture(2048, 2048, Texture.T_unsigned_byte, Texture.F_rgba8) cshader = Shader.load_compute(Shader.SL_GLSL, "grain.compute.glsl") node = NodePath("") node.set_shader(cshader) node.set_shader_input("DestTex", dest_tex) attr = node.get_attrib(ShaderAttrib) self.graphicsEngine.dispatch_compute((2048 // 16, 2048 // 16, 1), attr, self.win.get_gsg()) base.graphicsEngine.extract_texture_data(dest_tex, base.win.get_gsg()) # Convert to single channel img = PNMImage(2048, 2048, 1, 255) dest_tex.store(img) img.set_num_channels(1) tex = Texture() tex.load(img) tex.write("grain.txo.pz")
def _createMapTextureCard(self): mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION) mapImage.fill(*self._bgColor) fgColor = VBase4D(*self._fgColor) for x in xrange(self._mazeHeight): for y in xrange(self._mazeWidth): if self._mazeCollTable[y][x] == 1: ax = float(x) / self._mazeWidth * MAP_RESOLUTION invertedY = self._mazeHeight - 1 - y ay = float(invertedY) / self._mazeHeight * MAP_RESOLUTION self._drawSquare(mapImage, int(ax), int(ay), 10, fgColor) mapTexture = Texture('mapTexture') mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba) mapTexture.setMinfilter(Texture.FTLinear) mapTexture.load(mapImage) mapTexture.setWrapU(Texture.WMClamp) mapTexture.setWrapV(Texture.WMClamp) mapImage.clear() del mapImage cm = CardMaker('map_cardMaker') cm.setFrame(-1.0, 1.0, -1.0, 1.0) map = self.attachNewNode(cm.generate()) map.setTexture(mapTexture, 1) return map
def load_image(self, category, grayscale=False): image = PNMImage() if image.read(self.get_terrain_file_name(category)): if grayscale: image.makeGrayscale() return image else: return None
def setHeightfield(self, heightfield): '''Loads the heighmap image. Currently only accepts PNMIMage TODO: str path, FileName''' if type(heightfield) is str: heightfield = PNMImage(heightfield) self.heightfield = heightfield self.xsize = heightfield.getXSize() self.ysize = heightfield.getYSize()
def __init__(self, verbose_name, source_path): self.name = verbose_name self.path = source_path self.tex = PNMImage(source_path) self.w = self.tex.get_x_size() self.h = self.tex.get_y_size() self.area = self.w * self.h self.assigned_pos = None
def fixGrayscaleTextures(np): for tex in np.findAllTextures(): if (tex.getFormat() == Texture.F_luminance): print "Fixing grayscale texture", tex.getName() img = PNMImage() tex.store(img) img.makeRgb() tex.load(img)
def terrainFromHeightMap(self, main): self.parentNodePath = NodePath("FloorNodePath") self.parentNodePath.setPos(0, 0, -2) self.parentNodePath.setScale(5, 5, 0.75) # Heightfield (static) height = 8.0 img = PNMImage(Filename('models/elevation.png')) xdim = img.getXSize() ydim = img.getYSize() shape = BulletHeightfieldShape(img, height, ZUp) shape.setUseDiamondSubdivision(True) self.rigidNode = BulletRigidBodyNode('Heightfield') self.rigidNode.notifyCollisions(False) self.rigidNodePath = self.parentNodePath.attachNewNode(self.rigidNode) self.rigidNodePath.node().addShape(shape) self.rigidNodePath.setPos(0, 0, 0) self.rigidNodePath.setCollideMask(BitMask32.allOn()) self.rigidNodePath.node().notifyCollisions(False) main.world.attachRigidBody(self.rigidNodePath.node()) self.hf = self.rigidNodePath.node() # To enable/disable debug visualisation self.terrain = GeoMipTerrain('terrain') self.terrain.setHeightfield(img) self.terrain.setBlockSize(32) self.terrain.setNear(50) self.terrain.setFar(100) self.terrain.setFocalPoint(base.camera) rootNP = self.terrain.getRoot() rootNP.reparentTo(self.parentNodePath) rootNP.setSz(8.0) offset = img.getXSize() / 2.0 - 0.5 rootNP.setPos(-offset, -offset, -height / 2.0) self.terrain.generate() # Apply texture diffuseTexture = loader.loadTexture(Filename('models/diffuseMap.jpg')) diffuseTexture.setWrapU(Texture.WMRepeat) diffuseTexture.setWrapV(Texture.WMRepeat) rootNP.setTexture(diffuseTexture) # Normal map texStage = TextureStage('texStageNormal') texStage.setMode(TextureStage.MNormal) normalTexture = loader.loadTexture(Filename('models/normalMap.jpg')) rootNP.setTexture(texStage, normalTexture) # Glow map texStage = TextureStage('texStageNormal') texStage.setMode(TextureStage.MGlow) glowTexture = loader.loadTexture(Filename('models/glowMap.jpg')) rootNP.setTexture(texStage, glowTexture)
def capture(self): img = PNMImage() self.pg_world.win.getScreenshot(img) img.write("main.jpg") for name, sensor in self.vehicle.image_sensors.items(): if name == "mini_map": name = "lidar" sensor.save_image("{}.jpg".format(name))
def _load_noise_tex(self): """ Loads the default 4x4 noise tex """ random.seed(42) img = PNMImage(4, 4, 3) for x in range(16): img.set_xel(x%4, x//4, random.random(), random.random(), random.random()) tex = Texture("Random4x4") tex.load(img) self._pipeline.stage_mgr.add_input("Noise4x4", tex)
def load_terrain_map(self): image = PNMImage() if image.read(self.get_terrain_file_name()): for y in range(self.patch.r_height): for x in range(self.patch.r_width): self.patch.set_height(x, y, image.getGray(x, y)) return True else: return False
def main(): sff_file ='' output_dir='' if len(sys.argv) >= 2: sff_file = sys.argv[1] else: logging.error('Usage: sff-test ssf_file [output_dir]') return if len(sys.argv) >= 3: output_dir = sys.argv[2] #checking output dir if (output_dir != '') and (not os.path.exists(output_dir)): os.makedirs(output_dir) else: logging.info("Output directory not set from command line, skipping image save") fh = open(sff_file, 'rb') header = sff1_file.parse(fh.read(512)) print(header) next_subfile = header.next_subfile count = 0 while next_subfile and count < header.image_total: fh.seek(next_subfile) subfile = sff1_subfile_header.parse(fh.read(32)) next_subfile = subfile.next_subfile try: buff = StringIO(fh.read(subfile.length)) image = Image.open(buff) buff = StringIO() image.save(buff,'PNG') output = PNMImage() if not output.read(StringStream(buff.getvalue()), "i.png"): logging.error("Failed to read image from buffer") raise ValueError("Invalid image!") print("Image Group: %i, no: %i, size: %i x %i ,offset: (%i , %i), palette %i"%(subfile.groupno,subfile.imageno, image.size[0],image.size[1],subfile.axisx,subfile.axisy,subfile.palette)) except IOError: print(("ioerror", subfile.groupno, subfile.imageno)) pass else: # image.save(output_dir + "/g{0}-i{1}.png".format(subfile.groupno, subfile.imageno)) if len(output_dir) > 0: output.write(output_dir + "/g{0}-i{1}.png".format(subfile.groupno, subfile.imageno)) count+=1
def createGround(self, terrainData): """Create ground using a heightmap""" # Create heightfield for physics heightRange = terrainData["heightRange"] # Image needs to have dimensions that are a power of 2 + 1 heightMap = PNMImage(self.basePath + terrainData["elevation"]) xdim = heightMap.getXSize() ydim = heightMap.getYSize() shape = BulletHeightfieldShape(heightMap, heightRange, ZUp) shape.setUseDiamondSubdivision(True) np = self.outsideWorldRender.attachNewNode(BulletRigidBodyNode("terrain")) np.node().addShape(shape) np.setPos(0, 0, 0) self.physicsWorld.attachRigidBody(np.node()) # Create graphical terrain from same height map terrain = GeoMipTerrain("terrain") terrain.setHeightfield(heightMap) terrain.setBlockSize(32) terrain.setBruteforce(True) rootNP = terrain.getRoot() rootNP.reparentTo(self.worldRender) rootNP.setSz(heightRange) offset = xdim / 2.0 - 0.5 rootNP.setPos(-offset, -offset, -heightRange / 2.0) terrain.generate() # Apply texture diffuse = self.loader.loadTexture(Filename(self.basePath + terrainData["texture"])) diffuse.setWrapU(Texture.WMRepeat) diffuse.setWrapV(Texture.WMRepeat) rootNP.setTexture(diffuse) textureSize = 6.0 ts = TextureStage.getDefault() rootNP.setTexScale(ts, xdim / textureSize, ydim / textureSize) # Create planes around area to prevent player flying off the edge # Levels can define barriers around them but it's probably a good # idea to leave this here just in case sides = ( (Vec3(1, 0, 0), -xdim / 2.0), (Vec3(-1, 0, 0), -xdim / 2.0), (Vec3(0, 1, 0), -ydim / 2.0), (Vec3(0, -1, 0), -ydim / 2.0), ) for sideNum, side in enumerate(sides): normal, offset = side sideShape = BulletPlaneShape(normal, offset) sideNode = BulletRigidBodyNode("side%d" % sideNum) sideNode.addShape(sideShape) self.physicsWorld.attachRigidBody(sideNode)
def create_noise_textures(self): # Always generate the same random textures seed(42) img = PNMImage(4, 4, 3) for x in range(4): for y in range(4): img.set_xel(x, y, random(), random(), random()) tex = Texture("Rand4x4") tex.load(img) self._target.set_shader_input("Noise4x4", tex)
def __apply_Textures(self, recipe, tex_dict): for i, ter_dict in enumerate(recipe['terrains']): tex_img = PNMImage() tex_img.read(Filename("{}/tex/{}".format(recipe['planet_path'], ter_dict['texture']))) tex = Texture() tex.load(tex_img) tex.setMinfilter(Texture.FTLinear) ts = TextureStage(str(i)) ts.setSort(i) self.NP.setTexture(ts, tex, i*10)
def generate(self): '''(Re)generate the entire terrain erasing any current changes''' factor = self.blockSize*self.chunkSize #print "Factor:", factor for terrain in self.terrains: terrain.getRoot().removeNode() self.terrains = [] # Breaking master heightmap into subimages heightmaps = [] self.xchunks = (self.heightfield.getXSize()-1)/factor self.ychunks = (self.heightfield.getYSize()-1)/factor #print "X,Y chunks:", self.xchunks, self.ychunks n = 0 for y in range(0, self.ychunks): for x in range(0, self.xchunks): heightmap = PNMImage(factor+1, factor+1) heightmap.copySubImage(self.heightfield, 0, 0, xfrom = x*factor, yfrom = y*factor) heightmaps.append(heightmap) n += 1 # Generate GeoMipTerrains n = 0 y = self.ychunks-1 x = 0 for heightmap in heightmaps: terrain = GeoMipTerrain(str(n)) terrain.setHeightfield(heightmap) terrain.setBruteforce(self.bruteForce) terrain.setBlockSize(self.blockSize) terrain.generate() self.terrains.append(terrain) root = terrain.getRoot() root.reparentTo(self.root) root.setPos(n%self.xchunks*factor, (y)*factor, 0) # In order to texture span properly we need to reiterate through every vertex # and redefine the uv coordinates based on our size, not the subGeoMipTerrain's root = terrain.getRoot() children = root.getChildren() for child in children: geomNode = child.node() for i in range(geomNode.getNumGeoms()): geom = geomNode.modifyGeom(i) vdata = geom.modifyVertexData() texcoord = GeomVertexWriter(vdata, 'texcoord') vertex = GeomVertexReader(vdata, 'vertex') while not vertex.isAtEnd(): v = vertex.getData3f() t = texcoord.setData2f((v[0]+ self.blockSize/2 + self.blockSize*x)/(self.xsize - 1), (v[1] + self.blockSize/2 + self.blockSize*y)/(self.ysize - 1)) x += 1 if x >= self.xchunks: x = 0 y -= 1 n += 1
def generate_atlas(files, dest_dat, dest_png): entries = [] virtual_atlas_size = 32 all_entries_matched = False print("Loading", len(files), "entries ..") for verbose_name, source in files: entries.append(AtlasEntry(verbose_name, source)) entries = sorted(entries, key=lambda a: -a.area) while not all_entries_matched: print("Trying to pack into a", virtual_atlas_size, "x", virtual_atlas_size, "atlas ..") packer = LUIAtlasPacker(virtual_atlas_size) all_entries_matched = True for entry in entries: print("Finding position for", entry.w, entry.h) uv = packer.find_position(entry.w, entry.h) if uv.get_x() < 0: # print " Not all images matched, trying next power of 2" all_entries_matched = False virtual_atlas_size *= 2 break entry.assigned_pos = uv print("Matched entries, writing atlas ..") atlas_description_content = "" dest = PNMImage(virtual_atlas_size, virtual_atlas_size, 4) for entry in entries: if not entry.tex.has_alpha(): entry.tex.add_alpha() entry.tex.alpha_fill(1.0) dest.copy_sub_image( entry.tex, int(entry.assigned_pos.get_x()), int(entry.assigned_pos.get_y())) atlas_description_content += "{0} {1} {2} {3} {4}\n".format( entry.name.replace(" ", "_"), int(entry.assigned_pos.get_x()), int(entry.assigned_pos.get_y()), entry.w, entry.h) print("Writing", entry.name,"with dimensions", entry.w, entry.h) dest.write(dest_png) with open(dest_dat, "w") as handle: handle.write(atlas_description_content)
def generate(self): p = PNMImage(self.size, self.size, num_channels=2) for y in range(self.size): ry = (y - self.half_size + 0.5) / self.size for x in range(self.size): rx = (x - self.half_size + 0.5) / self.size dist = sqrt(rx * rx + ry * ry) value = min(1.0, pow(self.factor, dist)) v = value * self.max_value p.set_xel_a(x, y, v, v, v, v) return p
def __apply_Textures(self, recipe, tex_dict): for i, ter_dict in enumerate(recipe['terrains']): tex_img = PNMImage() tex_img.read( Filename("{}/tex/{}".format(recipe['planet_path'], ter_dict['texture']))) tex = Texture() tex.load(tex_img) tex.setMinfilter(Texture.FTLinear) ts = TextureStage(str(i)) ts.setSort(i) self.NP.setTexture(ts, tex, i * 10)
def makeSlopeImage(self): '''Returns a greyscale PNMImage containing the slope angles. This is composited from the assorted GeoMipTerrains.''' slopeImage = PNMImage(self.heightfield.getXSize(), self.heightfield.getYSize()) factor = self.blockSize*self.chunkSize n = 0 for y in range(0, self.ychunks): for x in range(0, self.xchunks): slopei = self.terrains[n].makeSlopeImage() #slopeImage.copySubImage(slopei, x*factor, y*factor, 0, 0) slopeImage.copySubImage(slopei, x*factor, y*factor) n += 1 return slopeImage
def __build_Normal_Map(self, recipe): # Load ref image. ref_img = PNMImage() height_map_path = "{}/maps/{}".format(recipe['path'], recipe['height_map']) ref_img.read(Filename(height_map_path)) # Create normal map from height map with GPU. with GPU_Image(ref_img, print_times=True) as gpu: height_range = LVector2f(recipe['height_min'], recipe['height_max']) norm_img = gpu.generate_normal_map(height_range=height_range) norm_img.write(Filename("{}/maps/earth_norm.jpg".format(recipe['path']))) return recipe
class AtlasEntry: def __init__(self, verbose_name, source_path): self.name = verbose_name self.path = source_path self.tex = PNMImage(source_path) self.w = self.tex.get_x_size() self.h = self.tex.get_y_size() self.area = self.w * self.h self.assigned_pos = None def __repr__(self): return self.name
def read_texture(self, filename): """ Reads a texture from the Pandora resources repository. Returns a PNMImage object representing the image data. Throws a PalettizerException if file could not be found. :filename: Relative filename pointing to a texture file in the Pandora repository. """ full_filename = self.find_texture(filename) if self.debug: print(f'Reading {full_filename}...') # We've found the source file! Let's load it using Panda3D. img = PNMImage() img.read(Filename.from_os_specific(full_filename)) needs_alpha_fill = img.num_channels not in (2, 4) img.set_color_type(4) if needs_alpha_fill: # We need an alpha channel no matter what, so if the image does not have one, # it needs to be filled immediately with opaque pixels as it starts out with transparent pixels img.alpha_fill(1) return img
def generate(self): p = PNMImage(self.size, self.size, num_channels=2) sigma = self.fwhm / (2 * sqrt(2 * log(2))) inv_sig2 = 1.0 / (2 * sigma * sigma) inv_factor = 1.0 / (sigma * sqrt(2.0 * pi)) for y in range(self.size): ry = y - self.half_size + 0.5 for x in range(self.size): rx = x - self.half_size + 0.5 dist2 = rx*rx + ry*ry value = min(1.0, exp(- dist2 * inv_sig2) * inv_factor * self.fwhm) v = value * self.max_value p.set_xel_a(x, y, v, v, v, v) return p
def generateMissingImages(self): """ Generates image sizes that should be present but aren't by scaling from the next higher size. """ for required_size in (256, 128, 48, 32, 16): if required_size in self.images: continue sizes = sorted(self.images.keys()) if required_size * 2 in sizes: from_size = required_size * 2 else: from_size = 0 for from_size in sizes: if from_size > required_size: break if from_size > required_size: Icon.notify.warning( "Generating %dx%d icon by scaling down %dx%d image" % (required_size, required_size, from_size, from_size)) from_image = self.images[from_size] image = PNMImage(required_size, required_size) image.setColorType(from_image.getColorType()) if from_image.hasAlpha(): image.addAlpha() image.quickFilterFrom(from_image) self.images[required_size] = image else: Icon.notify.warning( "Cannot generate %dx%d icon; no higher resolution image available" % (required_size, required_size))
def flipImages(self,images,flipx , flipy): """ Returns a copy of the images flipped by the corresponding axes """ flipped = [] for img in images: fimg = PNMImage(img.getXSize(),img.getYSize()) fimg.copyFrom(img) fimg.flip(flipx,flipy,False) flipped.append(fimg) return flipped
def getWaterSurface(manager, polycount = 50000, size = (512,512)): # Get cache directory... cacheDir = manager.get('paths').getConfig().find('cache').get('path') # Check if the data required already exists... cachedWaterSurface = "%s/plane-%dx%d-%dk.bam" % (cacheDir, size[0], size[1], int(polycount/1000)) try: return loader.loadModel(cachedWaterSurface) except: pass # Make cache directory if needed... if not os.path.isdir(cacheDir): os.mkdir(cacheDir) # Put in an image... img = PNMImage(*size) img.makeGrayscale() img.fill(0, 0, 0) img.write("%s/black-%dx%d.png" % (cacheDir,size[0],size[1])) # Put in a mesh... ht = HeightfieldTesselator("plane") assert ht.setHeightfield(Filename("%s/black-%dx%d.png" % (cacheDir,size[0],size[1]))) ht.setPolyCount(polycount) ht.setFocalPoint(int(size[0] * 0.5), int(size[1] * 0.5)) node = ht.generate() node.setPos(-0.5 * size[0], 0.5 * size[1], 0) node.flattenLight() node.writeBamFile(cachedWaterSurface) return node
def makeSlopeImage(self): '''Returns a greyscale PNMImage containing the slope angles. This is composited from the assorted GeoMipTerrains.''' slopeImage = PNMImage(self.heightfield.getXSize(), self.heightfield.getYSize()) factor = self.blockSize * self.chunkSize n = 0 for y in range(0, self.ychunks): for x in range(0, self.xchunks): slopei = self.terrains[n].makeSlopeImage() #slopeImage.copySubImage(slopei, x*factor, y*factor, 0, 0) slopeImage.copySubImage(slopei, x * factor, y * factor) n += 1 return slopeImage
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False): card_maker = CardMaker(name) card_maker.set_frame(-1, 1, -1, 1) node_path = NodePath(name) node = card_maker.generate() final_node_path = node_path.attach_new_node(node) final_node_path.set_billboard_point_eye() from panda3d.core import Filename shaders = Shader.load(Shader.SL_GLSL, Filename('Shader/Star/vertex.glsl'), Filename('Shader/Star/fragment.glsl'), Filename(''), Filename(''), Filename('')) if not shaders: print("WARNING. STAR SHADER FAILED TO LOAD", type(shaders)) else: final_node_path.set_shader_input('cameraSpherePos', 1, 1, 1) final_node_path.set_shader_input('sphereRadius', 1.0) final_node_path.set_shader_input('myCamera', base.camera) final_node_path.set_shader(shaders) final_node_path.set_shader_input('blackbody', color) material = Material() material.set_emission(VBase4(color, 1.0)) final_node_path.set_material(material) xn = PerlinNoise3(0.5, 0.5, 0.5) #yn = PerlinNoise3(0.5, 0.5, 0.5) texture = Texture('star') texture.setup_3d_texture() for z in range(texture_size): p = PNMImage(texture_size, texture_size) for y in range(texture_size): for x in range(texture_size): p.set_gray(x, y, abs(xn.noise(x, y, z))) texture.load(p, z, 0) diffuse = texture diffuse.setMinfilter(Texture.FTLinearMipmapLinear) diffuse.setAnisotropicDegree(4) final_node_path.set_texture(diffuse) normal = sandbox.base.loader.loadTexture('data/empty_textures/empty_normal.png') normalts = TextureStage('normalts') final_node_path.set_texture(normalts, normal) specular = sandbox.base.loader.loadTexture('data/empty_textures/empty_specular.png') spects = TextureStage('spects') final_node_path.set_texture(spects, specular) roughness = sandbox.base.loader.loadTexture('data/empty_textures/empty_roughness.png') roughts= TextureStage('roughts') final_node_path.set_texture(roughts, roughness) return final_node_path
def loadTerrain(name, widthScale = 0.5, heightScale = 10.0): """load terrain stuff""" global app, terrain, terrainRootNetPos steerMgr = OSSteerManager.get_global_ptr() terrain = GeoMipTerrain("terrain") heightField = PNMImage(Filename(dataDir + "/heightfield.png")) terrain.set_heightfield(heightField) # sizing environmentWidthX = (heightField.get_x_size() - 1) * widthScale environmentWidthY = (heightField.get_y_size() - 1) * widthScale environmentWidth = (environmentWidthX + environmentWidthY) / 2.0 terrain.get_root().set_sx(widthScale) terrain.get_root().set_sy(widthScale) terrain.get_root().set_sz(heightScale) # set other terrain's properties blockSize, minimumLevel = (64, 0) nearPercent, farPercent = (0.1, 0.7) terrainLODmin = min(minimumLevel, terrain.get_max_level()) flattenMode = GeoMipTerrain.AFM_off terrain.set_block_size(blockSize) terrain.set_near(nearPercent * environmentWidth) terrain.set_far(farPercent * environmentWidth) terrain.set_min_level(terrainLODmin) terrain.set_auto_flatten(flattenMode) # terrain texturing textureStage0 = TextureStage("TextureStage0") textureImage = TexturePool.load_texture(Filename("terrain.png")) terrain.get_root().set_tex_scale(textureStage0, 1.0, 1.0) terrain.get_root().set_texture(textureStage0, textureImage, 1) # reparent this Terrain node path to the object node path terrain.get_root().reparent_to(steerMgr.get_reference_node_path()) terrain.get_root().set_collide_mask(mask) terrain.get_root().set_name(name) # brute force generation bruteForce = True terrain.set_bruteforce(bruteForce) # Generate the terrain terrain.generate() # check if terrain needs update or not if not bruteForce: # save the net pos of terrain root terrainRootNetPos = terrain.get_root().get_net_transform().get_pos() # Add a task to keep updating the terrain app.taskMgr.add(terrainUpdate, "terrainUpdate", appendTask=True) # return terrain.get_root()
def generate_dataset_texture_into(self, dest_tex, z): resolution_vertical = dest_tex.get_y_size() resolution_horizontal = dest_tex.get_x_size() dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535) for vert in range(resolution_vertical): for horiz in range(resolution_horizontal): vert_angle = vert / (resolution_vertical-1.0) vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0 horiz_angle = horiz / (resolution_horizontal-1.0) * 360.0 candela = self.get_candela_value(vert_angle, horiz_angle) dest.set_xel(vert, horiz, candela) dest_tex.load(dest, z, 0)
def takePictureRaw(self): img = PNMImage() tex = self.takePicture() tex.store(img) ss = StringStream() img.write(ss, 'jpg') if 1: # Test it img2 = PNMImage() img2.read(ss) img2.write(Filename("test_viewfinder.jpg")) return ss.getData()
def getScreenshot(p3dApp): p3dApp.taskMgr.step() p3dApp.taskMgr.step() pnmss = PNMImage() p3dApp.win.getScreenshot(pnmss) resulting_ss = StringStream() pnmss.write(resulting_ss, "screenshot.png") screenshot_buffer = resulting_ss.getData() pilimage = Image.open(StringIO(screenshot_buffer)) pilimage.load() #pnmimage will sometimes output as palette mode for 8-bit png so convert pilimage = pilimage.convert('RGBA') return pilimage
def generate_dataset_texture_into(self, dest_tex, layer_index): resolution_vertical = dest_tex.get_y_size() resolution_horizontal = dest_tex.get_x_size() dest = PNMImage(resolution_vertical, resolution_horizontal, 1, 65535) for vert in range(resolution_vertical): for horiz in range(resolution_horizontal): vert_angle = vert / (resolution_vertical - 1.0) vert_angle = math.cos(vert_angle * math.pi) * 90.0 + 90.0 horiz_angle = horiz / (resolution_horizontal - 1.0) * 360.0 candela = self.get_candela_value(vert_angle, horiz_angle) dest.set_xel(vert, horiz, candela) dest_tex.load(dest, layer_index, 0)
def generate(self): p = PNMImage(self.size, self.size, num_channels=2, maxval=65535) for y in range(self.size): ry = (y - self.half_size + 0.5) / (self.half_size - 1) for x in range(self.size): rx = (x - self.half_size + 0.5) / (self.half_size - 1) r = sqrt(rx * rx + ry * ry) if r > 1.0: r = 0.0 elif r > 0.5: r = 2 * (1 - r) else: r = 1.0 r *= self.max_value p.set_xel_a(x, y, r, r, r, r) return p
def __build_Normal_Map(self, recipe): # Load ref image. ref_img = PNMImage() height_map_path = "{}/maps/{}".format(recipe['path'], recipe['height_map']) ref_img.read(Filename(height_map_path)) # Create normal map from height map with GPU. with GPU_Image(ref_img, print_times=True) as gpu: height_range = LVector2f(recipe['height_min'], recipe['height_max']) norm_img = gpu.generate_normal_map(height_range=height_range) norm_img.write( Filename("{}/maps/earth_norm.jpg".format(recipe['path']))) return recipe
def __init__(self, loader, parentNodePath): w = loader.loadModel("plane") w.reparentTo(parentNodePath) size = 6 w.setPos(3.5, 15, size / 2 - 3) w.setColor(1, 0, 0) w.setHpr(0, 180, 0) w.setScale(size, 1, size / 1.33) w.setTwoSided(True) self.tx = Texture("video") self.tx.setup2dTexture(self.res, self.res, Texture.TUnsignedByte, Texture.FRgb8) # this makes some important setup call self.tx.load(PNMImage(self.res, self.res)) w.setTexture(self.tx) m = Material("vid") m.setTwoside(True) m.setEmission(VBase4(1, 1, 1, 1)) w.setMaterial(m) w.setFogOff()
def SetupBulletTerrain(self): self.worldNP = self.render.attachNewNode('World') self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) img = PNMImage(Filename(self.PngDEM)) if self.MeterScale < 1.1: shape = BulletHeightfieldShape(img, self.HeightRange, ZUp) else: shape = BulletHeightfieldShape(img, self.HeightRange, ZUp) shape.setUseDiamondSubdivision(True) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Heightfield')) np.node().addShape(shape) offset = self.MeterScale * self.PixelNr / 2.0 np.setPos(+offset, +offset, +(self.HeightRange / 2.0) + self.OffsetHeight) np.setSx(self.MeterScale) np.setSy(self.MeterScale) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node())
def filter_cubemap(orig_pth): if not os.path.isdir("Filtered/"): os.makedirs("Filtered/") # Copy original cubemap for i in range(6): shutil.copyfile(orig_pth.replace("#", str(i)), "Filtered/0-" + str(i) + ".png") mip = 0 while True: print("Filtering mipmap", mip) mip += 1 pth = "Filtered/" + str(mip - 1) + "-#.png" dst_pth = "Filtered/" + str(mip) + "-#.png" first_img = load_nth_face(pth, 0) size = first_img.get_x_size() // 2 if size < 1: break blur_size = size * 0.002 blur_size += mip * 0.85 blur_size = int(blur_size) effective_size = size + 2 * blur_size faces = [load_nth_face(pth, i) for i in range(6)] cubemap = loader.loadCubeMap(pth) node = NodePath("") node.set_shader(compute_shader) node.set_shader_input("SourceCubemap", cubemap) node.set_shader_input("size", size) node.set_shader_input("blurSize", blur_size) node.set_shader_input("effectiveSize", effective_size) final_img = PNMImage(size, size, 3) for i in range(6): face_dest = dst_pth.replace("#", str(i)) dst = Texture("Face-" + str(i)) dst.setup_2d_texture(effective_size, effective_size, Texture.T_float, Texture.F_rgba16) # Execute compute shader node.set_shader_input("faceIndex", i) node.set_shader_input("DestTex", dst) attr = node.get_attrib(ShaderAttrib) base.graphicsEngine.dispatch_compute(( (effective_size+15) // 16, (effective_size+15) // 16, 1), attr, base.win.get_gsg()) base.graphicsEngine.extract_texture_data(dst, base.win.get_gsg()) img = PNMImage(effective_size, effective_size, 3) dst.store(img) img.gaussian_filter(blur_size) final_img.copy_sub_image(img, 0, 0, blur_size, blur_size, size, size) final_img.write(face_dest)
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False): card_maker = CardMaker(name) card_maker.set_frame(-1, 1, -1, 1) node_path = NodePath(name) node = card_maker.generate() final_node_path = node_path.attach_new_node(node) final_node_path.set_billboard_point_eye() shaders = Shader.load(Shader.SLGLSL, 'Shader/Star/vertex.glsl', 'Shader/Star/fragment.glsl') final_node_path.set_shader_input(b'cameraSpherePos', 1, 1, 1) final_node_path.set_shader_input(b'sphereRadius', 1.0) final_node_path.set_shader_input(b'myCamera', base.camera) final_node_path.set_shader(shaders) final_node_path.set_shader_input(b'blackbody', color) material = Material() material.set_emission(VBase4(color, 1.0)) final_node_path.set_material(material) xn = PerlinNoise3(0.5, 0.5, 0.5) #yn = PerlinNoise3(0.5, 0.5, 0.5) texture = Texture('star') texture.setup_3d_texture() for z in range(texture_size): p = PNMImage(texture_size, texture_size) for y in range(texture_size): for x in range(texture_size): p.set_gray(x, y, abs(xn.noise(x, y, z))) texture.load(p, z, 0) diffuse = texture diffuse.setMinfilter(Texture.FTLinearMipmapLinear) diffuse.setAnisotropicDegree(4) final_node_path.set_texture(diffuse) normal = base.loader.loadTexture('Data/Textures/EmptyNormalTexture.png') normalts = TextureStage('normalts') final_node_path.set_texture(normalts, normal) specular = base.loader.loadTexture('Data/Textures/EmptySpecularTexture.png') spects = TextureStage('spects') final_node_path.set_texture(spects, specular) roughness = base.loader.loadTexture('Data/Textures/EmptyRoughnessTexture.png') roughts= TextureStage('roughts') final_node_path.set_texture(roughts, roughness) return final_node_path
def createMap(self): height = 10.0 img = PNMImage(Filename('resources/map1.bmp')) shape = BulletHeightfieldShape(img, height, ZUp) node = BulletRigidBodyNode('Map') node.setMass(99999999) node.addShape(shape) self.world.attachRigidBody(node) offset = img.getXSize() / 2.0 - 0.5 terrain = GeoMipTerrain('terrain') terrain.setHeightfield(img) terrainNP = terrain.getRoot() terrainNP.setSz(height) terrainNP.setPos(-offset, -offset, -height / 2.0) #terrain.setColorMap('resources/map1color.bmp') terrain.setAutoFlatten(GeoMipTerrain.AFMOff) terrain.generate() return Map(terrainNP,node)
def load_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None): """ Loads a texture from the given filename and dimensions. If only one dimensions is specified, the other dimensions are assumed to be equal. This internally loads the texture into ram, splits it into smaller sub-images, and then calls the load_3d_texture from the Panda loader """ # Generate a unique name to prevent caching tempfile_name = "$$SliceLoaderTemp-" + str(time.time()) + "/" # For quaddratic textures tile_size_y = tile_size_x if tile_size_y is None else tile_size_y num_tiles = tile_size_x if num_tiles is None else num_tiles # Load sliced image from disk source = PNMImage(fname) width = source.get_x_size() # Find slice properties num_cols = width // tile_size_x temp = PNMImage( tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval()) # Construct a ramdisk to write the files to vfs = VirtualFileSystem.get_global_ptr() ramdisk = VirtualFileMountRamdisk() vfs.mount(ramdisk, tempfile_name, 0) # Extract all slices and write them to the virtual disk for z_slice in range(num_tiles): slice_x = (z_slice % num_cols) * tile_size_x slice_y = (z_slice // num_cols) * tile_size_y temp.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y) temp.write(tempfile_name + str(z_slice) + ".png") # Load the de-sliced texture from the ramdisk texture_handle = Globals.loader.load3DTexture(tempfile_name + "/#.png") # This should never trigger, but can't hurt to have assert texture_handle.get_x_size() == tile_size_x assert texture_handle.get_y_size() == tile_size_y assert texture_handle.get_z_size() == num_tiles # Finally unmount the ramdisk vfs.unmount(ramdisk) return texture_handle
def textureFromData(image_data, filename=""): tex = None if image_data: myTexture = Texture() myImage = PNMImage() success = myImage.read(StringStream(image_data), filename) if success == 1: #PNMImage can handle most texture formats myTexture.load(myImage) else: #Except for DDS, which PNMImage.read will return 0, so try to load as DDS success = myTexture.readDds(StringStream(image_data)) if success != 0: tex = myTexture tex.setMinfilter(Texture.FTLinearMipmapLinear) return tex
def __makeSprite__(self,pnm_img,subfile,flip): img = None if flip: img = PNMImage(pnm_img.getXSize(),pnm_img.getYSize()) img.copyFrom(pnm_img) img.flip(True ,False,False) else: img = pnm_img sff_image = Sprite() sff_image.setXSize(img.getXSize()) sff_image.setYSize(pnm_img.getYSize()) sff_image.setZSize(1) sff_image.axisx = -subfile.axisx if (not flip ) else subfile.axisx sff_image.axisy = subfile.axisy sff_image.group = subfile.groupno sff_image.no = subfile.imageno sff_image.load(img) sff_image.setWrapU(Texture.WM_border_color) # gets rid of odd black edges around image sff_image.setWrapV(Texture.WM_border_color) sff_image.setBorderColor(LColor(0,0,0,0)) return sff_image
def __map_Topography(self, planet, model, pts=[]): height_map = PNMImage() height_map_path = "{}/maps/{}".format(planet.path, planet.height_map) height_map.read(Filename(height_map_path)) _hu_size = height_map.getXSize()-1 _hv_size = height_map.getYSize()-1 radius = planet.radius bottom = radius + planet.height_min elev_range = planet.height_max - planet.height_min _has_sea = "sea_level" in planet.__dict__ if _has_sea: sea_level = planet.sea_level + planet.radius if not pts: pts = model.read("vertex") for pt in pts: u, v = self.__get_Pt_Uv(pt, _hu_size, _hv_size) height_val = height_map.getGray(u, v) ## watch when extending w colours. height = bottom + elev_range*height_val ratio = height / radius pt *= ratio # If planet has sea then raise vert to sea level. if _has_sea: len_pt = pt.length() if len_pt <= sea_level: ratio = sea_level/len_pt pt *= ratio model.modify("vertex", pts)
def GenerateNavmeshCSV(map, output): #check the map size map_size=map.getReadXSize() #make it square if map.getReadYSize()!=map_size: new_map=PNMImage(map_size,map_size) new_map.boxFilterFrom(0.0,map) map=new_map #generate data nods=[] for y in range(0,map_size): for x in range(0,map_size): nods+=GetNeighbors((x,y), map, map_size) #write data with open(output, 'w') as output_file: #header output_file.write('Grid Size,'+str(map_size)+'\n') output_file.write('NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ\n') #data... for nod in nods: output_file.write('{NULL},{NodeType},{GridX},{GridY},{Length},{Width},{Height},{PosX},{PosY},{PosZ}\n'.format(**nod))
def _storeIESProfile(self, name, lampRadialGradientData, lampGradientData): """ Internal method to convert the array of data into a texture to load into the texture array """ def interpolateValue(dataset, percentageVal): """ Interpolates over an array, accepting float values from 0.0 to 1.0 """ percentageValClamped = max(0.0, min(0.99999, percentageVal)) scaledVal = percentageValClamped * len(dataset) index = int(scaledVal) indexBy1 = min(index + 1, len(dataset) -1) lerpFactor = scaledVal % 1.0 return dataset[indexBy1] * lerpFactor + dataset[index] * (1.0 - lerpFactor) # Add profile name to the list of loaded profiles if name in self.profileNames: # self.error("Cannot register profile",name,"twice") return False profileIndex = len(self.profileNames) self.profileNames.append(name) # Generate gradient texture img = PNMImage(self.IESTableResolution, 1, 4, 2 ** 16 - 1) for offset in xrange(self.IESTableResolution): radialGradientValR = interpolateValue(lampRadialGradientData, (offset + 5.0) / float(self.IESTableResolution)) radialGradientValG = interpolateValue(lampRadialGradientData, offset / float(self.IESTableResolution)) radialGradientValB = interpolateValue(lampRadialGradientData, (offset - 5.0) / float(self.IESTableResolution)) gradientVal = interpolateValue(lampGradientData, offset / float(self.IESTableResolution)) img.setXelA(offset, 0, radialGradientValR, radialGradientValG, radialGradientValB, gradientVal) # Store gradient texture self.storage.load(img, profileIndex, 0)