def write(self, pth): """ Writes the image to disk """ Globals.base.graphicsEngine.extract_texture_data(self, Globals.base.win.get_gsg()) if self.get_texture_type() in [Texture.TT_3d_texture, Texture.TT_cube_map]: Texture.write(self, "#_" + pth, 0, 0, True, False) else: Texture.write(self, pth)
def makeTextureMap(self): '''Citymania function that generates and sets the 4 channel texture map''' self.colorTextures = [] for terrain in self.terrains: terrain.getRoot().clearTexture() heightmap = terrain.heightfield() colormap = PNMImage(heightmap.getXSize()-1, heightmap.getYSize()-1) colormap.addAlpha() slopemap = terrain.makeSlopeImage() for x in range(0, colormap.getXSize()): for y in range(0, colormap.getYSize()): # Else if statements used to make sure one channel is used per pixel # Also for some optimization # Snow. We do things funky here as alpha will be 1 already. if heightmap.getGrayVal(x, y) < 200: colormap.setAlpha(x, y, 0) else: colormap.setAlpha(x, y, 1) # Beach. Estimations from http://www.simtropolis.com/omnibus/index.cfm/Main.SimCity_4.Custom_Content.Custom_Terrains_and_Using_USGS_Data if heightmap.getGrayVal(x,y) < 62: colormap.setBlue(x, y, 1) # Rock elif slopemap.getGrayVal(x, y) > 170: colormap.setRed(x, y, 1) else: colormap.setGreen(x, y, 1) colorTexture = Texture() colorTexture.load(colormap) colorTS = TextureStage('color') colorTS.setSort(0) colorTS.setPriority(1) self.colorTextures.append((colorTexture, colorTS))
def createTexture(self, image): (width, height) = cv.GetSize(image) #Panda3D interpreta las imagenes al reves que OpenCV (verticalmente invertidas), por lo que es necesario tener esto en cuenta cv.Flip(image, image, 0) #OpenCV permite convertir la representacion interna de las imagenes a un formato descomprimido que puede ser guardado en un archivo. #Esto puede utilizarse desde Panda3D para tomar la imagen y utilizarla como una textura. imageString = image.tostring() #PTAUchar es una clase que permite tomar un bloque de datos y utilizarlo desde componentes de Panda3D (en particular es util para texturas) imagePointer = PTAUchar.emptyArray(0) imagePointer.setData(imageString) try: self.count += 1 #Crea un nuevo objeto textura texture = Texture('image' + str(self.count)) #Establece propiedades de la textura, como tamanio, tipo de datos y modelo de color. Las imagenes de OpenCV las estamos manejando #como RGB, donde cada canal es de 8bits (un numero entero) texture.setup2dTexture(width, height, Texture.TUnsignedByte, Texture.FRgb) #Indicamos que utilice el bloque de datos obtenido anteriormente como origen de datos para la textura texture.setRamImage(CPTAUchar(imagePointer), MovieTexture.CMOff) except: texture = None return texture
def getTextureRAM(mesh): total_image_area = 0 for cimg in mesh.images: pilimg = cimg.pilimage if pilimg: total_image_area += pilimg.size[0] * pilimg.size[1] * len(pilimg.getbands()) else: # PIL doesn't support DDS, so if loading failed, try and load it as a DDS with panda3d imgdata = cimg.data # if we can't even load the image's data, can't convert if imgdata is None: continue try: from panda3d.core import Texture from panda3d.core import StringStream except ImportError: # if panda3d isn't installed and PIL failed, can't convert continue t = Texture() try: success = t.readDds(StringStream(imgdata)) except: success = 1 if success == 0: # failed to load as DDS, so let's give up continue total_image_area += t.getXSize() * t.getYSize() * 3 return total_image_area
class MatPlotLibDemo(ShowBase): def __init__(self): ShowBase.__init__(self) base.setFrameRateMeter(True) m = loader.loadModel("models/smiley") m.reparent_to(render) m.set_pos(0, 5, 0) x_size, y_size = 640, 480 xy_ratio = float(y_size) / float(x_size) self.plot = Plot(x_size, y_size) self.input_img = PNMImage(x_size, y_size) self.input_tex = Texture() self.input_tex.load(self.input_img) self.card = CardMaker('pygame_card') self.card.setUvRange(Point2(0, 1), # ll Point2(1, 1), # lr Point2(1, 0), # ur Point2(0, 0)) # ul self.screen = render.attach_new_node(self.card.generate()) self.screen.set_scale(1, 1, xy_ratio) self.screen.set_pos(-0.5, 2, -0.5 * xy_ratio) self.screen.setTexture(self.input_tex) # FIXME: Apparently mpl's print_to_buffer() doesn't write # alpha values properly. self.screen.setTransparency(TransparencyAttrib.MAlpha) taskMgr.add(self.update, "update plot") def update(self, task): self.input_tex.set_ram_image_as(self.plot.draw(), "RGBA") return task.cont
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 create(self): """ Creates the passes """ self.cloudStartHeight = 900.0 self.cloudEndHeight = 3300.0 self.cloudResolution = 768 self.cloudResolutionH = 128 self.voxelGrid = Texture("CloudVoxelGrid") self.voxelGrid.setup3dTexture(self.cloudResolution, self.cloudResolution, self.cloudResolutionH, Texture.TFloat, Texture.FR16) self.voxelGrid.setWrapU(Texture.WMRepeat) self.voxelGrid.setWrapV(Texture.WMRepeat) self.voxelGrid.setWrapW(Texture.WMClamp) self.cloudNoise = Texture("CloudNoise") self.cloudNoise.setup3dTexture(64, 64, 64, Texture.TFloat, Texture.FR16) self.cloudNoise.setWrapU(Texture.WMRepeat) self.cloudNoise.setWrapV(Texture.WMRepeat) self.cloudNoise.setWrapW(Texture.WMRepeat) MemoryMonitor.addTexture("CloudVoxelGrid", self.voxelGrid) MemoryMonitor.addTexture("CloudNoise", self.cloudNoise) self._createInitialGrid() self.renderPass = CloudRenderPass() self.pipeline.getRenderPassManager().registerPass(self.renderPass) self.pipeline.getRenderPassManager().registerStaticVariable("cloudVoxelGrid", self.voxelGrid) self.pipeline.getRenderPassManager().registerStaticVariable("cloudStartHeight", self.cloudStartHeight) self.pipeline.getRenderPassManager().registerStaticVariable("cloudEndHeight", self.cloudEndHeight) self.pipeline.getRenderPassManager().registerStaticVariable("cloudNoise", self.cloudNoise) self.pipeline.getRenderPassManager().registerDefine("CLOUDS_ENABLED", 1)
def createMaskedTexture(self, name): name = self.prepTextureName(name) original_name = name[len('masked-'):] if self.textures.has_key(original_name): tc = self.textures[original_name] # get the original texture bm = tc.image_file img_type = tc.image_type if img_type == 'DDS': mtex = TextureContainer(name, tc.panda_texture, tc.image_file, img_type) self.textures[name] = mtex return mtex if img_type != 'IMG': print 'ERROR in createMaskedTexture(): cant create masked texture from non IMG type image' return None # print type(bm) # print len(bm) # FIXME: this just copies the original right now! Need to implement the alpha-mask bit still m_img = self.maskImg(bm, tc.panda_texture.getXSize() * tc.panda_texture.getYSize()) t = Texture() # create empty texture object component_type = Texture.TUnsignedByte format = Texture.FRgba t.setup2dTexture(tc.panda_texture.getXSize(),tc.panda_texture.getYSize(), component_type, format) t.setRamImage(m_img) mtex = TextureContainer(name, t, m_img, img_type) self.textures[name] = mtex return mtex else: print 'TextureManager::createMaskedTexture() failed, original texture:%s not found' % (original_name) return None
def __init__(self, N, sourceTex, normalizationFactor): """ Creates a new fft instance. The source texture has to specified from the begining, as the shaderAttributes are pregenerated for performance reasons """ DebugObject.__init__(self, "GPU-FFT") self.size = N self.log2Size = int(math.log(N, 2)) self.normalizationFactor = normalizationFactor # Create a ping and a pong texture, because we can't write to the # same texture while reading to it (that would lead to unexpected # behaviour, we could solve that by using an appropriate thread size, # but it works fine so far) self.pingTexture = Texture("FFTPing") self.pingTexture.setup2dTexture( self.size, self.size, Texture.TFloat, Texture.FRgba32) self.pongTexture = Texture("FFTPong") self.pongTexture.setup2dTexture( self.size, self.size, Texture.TFloat, Texture.FRgba32) self.sourceTex = sourceTex for tex in [self.pingTexture, self.pongTexture, sourceTex]: tex.setMinfilter(Texture.FTNearest) tex.setMagfilter(Texture.FTNearest) tex.setWrapU(Texture.WMClamp) tex.setWrapV(Texture.WMClamp) # Pregenerate weights & indices for the shaders self._computeWeighting() # Pre generate the shaders, we have 2 passes: Horizontal and Vertical # which both execute log2(N) times with varying radii self.horizontalFFTShader = BetterShader.loadCompute( "Shader/Water/HorizontalFFT.compute") self.horizontalFFT = NodePath("HorizontalFFT") self.horizontalFFT.setShader(self.horizontalFFTShader) self.horizontalFFT.setShaderInput( "precomputedWeights", self.weightsLookupTex) self.horizontalFFT.setShaderInput("N", LVecBase2i(self.size)) self.verticalFFTShader = BetterShader.loadCompute( "Shader/Water/VerticalFFT.compute") self.verticalFFT = NodePath("VerticalFFT") self.verticalFFT.setShader(self.verticalFFTShader) self.verticalFFT.setShaderInput( "precomputedWeights", self.weightsLookupTex) self.verticalFFT.setShaderInput("N", LVecBase2i(self.size)) # Create a texture where the result is stored self.resultTexture = Texture("Result") self.resultTexture.setup2dTexture( self.size, self.size, Texture.TFloat, Texture.FRgba16) self.resultTexture.setMinfilter(Texture.FTLinear) self.resultTexture.setMagfilter(Texture.FTLinear) # Prepare the shader attributes, so we don't have to regenerate them # every frame -> That is VERY slow (3ms per fft instance) self._prepareAttributes()
def __init__(self, name): """ Internal method to create a new image """ RPObject.__init__(self, name) Texture.__init__(self, name) Image.REGISTERED_IMAGES.append(self) self.set_clear_color(0) self.clear_image() self.sort = RenderTarget.CURRENT_SORT
def add_render_texture(output, mode=None, bitplane=None): """Add render texture to `output`. Args: output (GraphicsOutput): Graphics output. Keyword Args: mode (GraphicsOutput.RenderTextureMode): | RTMNode | RTMBindOrCopy | RTMCopyTexture | RTMCopyRam | RTMTriggeredCopyTexture | RTMTriggeredCopyRam bitplane (DrawableRegion.RenderTexturePlane): | RTPStencil | RTPDepthStencil | RTPColor | RTPAuxRgba0 | RTPAuxRgba1 | RTPAuxRgba2 | RTPAuxRgba3 | RTPAuxHrgba0 | RTPAuxHrgba1 | RTPAuxHrgba2 | RTPAuxHrgba3 | RTPAuxFloat0 | RTPAuxFloat1 | RTPAuxFloat2 | RTPAuxFloat3 | RTPDepth | RTPCOUNT Return: (Texture): Texture object. """ # Mode. if mode is None: mode = GraphicsOutput.RTMBindOrCopy elif isinstance(mode, str): mode = getattr(GraphicsOutput, mode) if bitplane is None: bitplane = GraphicsOutput.RTPColor elif isinstance(bitplane, str): bitplane = getattr(GraphicsOutput, bitplane) # Bitplane. if bitplane is GraphicsOutput.RTPColor: fmt = Texture.FLuminance elif bitplane is GraphicsOutput.RTPDepth: fmt = Texture.FDepthComponent # Get a handle to the texture. tex = Texture() tex.setFormat(fmt) # Add the texture to the buffer. output.addRenderTexture(tex, mode, bitplane) tex.clearRamImage() return tex
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 initTransparencyPass(self): """ Creates the pass which renders the transparent objects into the scene """ self.transparencyPass = TransparencyPass() self.pipeline.getRenderPassManager().registerPass(self.transparencyPass) # Create the atomic counter which stores the amount of rendered transparent # pixels. For now this a 1x1 texture, as atomic counters are not implemented. self.pixelCountBuffer = Texture("MaterialCountBuffer") self.pixelCountBuffer.setup2dTexture(1, 1, Texture.TInt, Texture.FR32i) # Creates the buffer which stores all transparent pixels. Pixels are inserted # into the buffer in the order they are rendered, using the pixelCountBuffer # to determine their index self.materialDataBuffer = Texture("MaterialDataBuffer") self.materialDataBuffer.setupBufferTexture(self.maxPixelCount, Texture.TFloat, Texture.FRgba32, GeomEnums.UH_static) # Creates the list head buffer, which stores the first transparent pixel for # each window pixel. The index stored in this buffer is the index into the # materialDataBuffer self.listHeadBuffer = Texture("ListHeadBuffer") self.listHeadBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, Texture.TInt, Texture.FR32i) # Creates the spinlock buffer, which ensures that writing to the listHeadBuffer # is sequentially self.spinLockBuffer = Texture("SpinLockBuffer") self.spinLockBuffer.setup2dTexture(self.pipeline.getSize().x, self.pipeline.getSize().y, Texture.TInt, Texture.FR32i) # Set the buffers as input to the main scene. Maybe we can do this more elegant target = self.pipeline.showbase.render target.setShaderInput("pixelCountBuffer", self.pixelCountBuffer) target.setShaderInput("spinLockBuffer", self.spinLockBuffer) target.setShaderInput("materialDataBuffer", self.materialDataBuffer) target.setShaderInput("listHeadBuffer", self.listHeadBuffer) # Provides the buffers as global shader inputs self.pipeline.getRenderPassManager().registerStaticVariable("transpPixelCountBuffer", self.pixelCountBuffer) self.pipeline.getRenderPassManager().registerStaticVariable("transpSpinLockBuffer", self.spinLockBuffer) self.pipeline.getRenderPassManager().registerStaticVariable("transpListHeadBuffer", self.listHeadBuffer) self.pipeline.getRenderPassManager().registerStaticVariable("transpMaterialDataBuffer", self.materialDataBuffer) # Registers the transparency settings to the shaders self.pipeline.getRenderPassManager().registerDefine("USE_TRANSPARENCY", 1) self.pipeline.getRenderPassManager().registerDefine("MAX_TRANSPARENCY_LAYERS", self.pipeline.settings.maxTransparencyLayers) self.pixelCountBuffer.setClearColor(Vec4(0, 0, 0, 0)) self.spinLockBuffer.setClearColor(Vec4(0, 0, 0, 0)) self.listHeadBuffer.setClearColor(Vec4(0, 0, 0, 0)) MemoryMonitor.addTexture("MaterialCountBuffer", self.pixelCountBuffer) MemoryMonitor.addTexture("MaterialDataBuffer", self.materialDataBuffer) MemoryMonitor.addTexture("ListHeadBuffer", self.listHeadBuffer) MemoryMonitor.addTexture("SpinLockBuffer", self.spinLockBuffer)
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 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 __init__(self): Texture.__init__(self) self.axisx = 0 # offset distance to the right side of the sprite from the origin. X+ is to the right self.axisy = 0 # offset distance to the top side of the sprite from the origin. Y+ is up self.group = 0 self.no = 0 self.hit_boxes = [] self.damage_boxes = []
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 setOwnerTextures(self): self.ownerview = True root = self.terrain.getRoot() root.clearShader() root.clearTexture() cityTexture = Texture() cityTexture.load(self.citymap) cityTS = TextureStage('citymap') cityTS.setSort(0) root.setTexture( self.gridTS, self.gridTexture ) root.setTexScale(self.gridTS, self.terrain.xchunks, self.terrain.ychunks) root.setTexture(cityTS, cityTexture, 1)
def __get_Texture(self, ref_img): # Convert ref_img into texture. with TimeIt() as prep_timer: ref_tex = Texture() # Ensure ref image has an alpha channel. if not ref_img.hasAlpha(): ref_img.addAlpha() ref_img.alphaFill(1.0) # Load tex and set format ref_tex.load(ref_img) ref_tex.setFormat(self.img_format) self.prepare_time += round(prep_timer.total_time, 3) return ref_tex
class ScatteringCubemapPass(RenderPass): """ This pass computes the scattering to a cubemap """ def __init__(self): RenderPass.__init__(self) self.cubemapSize = 256 def getID(self): return "ScatteringCubemapPass" def getRequiredInputs(self): return { # Scattering "transmittanceSampler": ["Variables.transmittanceSampler", "Variables.emptyTextureWhite"], "inscatterSampler": ["Variables.inscatterSampler", "Variables.emptyTextureWhite"], "scatteringOptions": ["Variables.scatteringOptions", "Variables.null"], "mainRender": "Variables.mainRender", "cameraPosition": "Variables.cameraPosition", "mainCam": "Variables.mainCam", "wsPositionTex": "DeferredScenePass.wsPosition", "wsNormalTex": "DeferredScenePass.wsNormal", "basecolorTex": "DeferredScenePass.data3", # "viewSpacePosition": "ViewSpacePass.position" "cloudsTex": ["CloudRenderPass.resultTex", "Variables.emptyTextureWhite"] } def create(self): self.cubemap = Texture("Scattering Cubemap") self.cubemap.setupCubeMap(self.cubemapSize, Texture.TFloat, Texture.FRgba16) self.cubemap.setMinfilter(Texture.FTLinearMipmapLinear) self.cubemap.setMagfilter(Texture.FTLinearMipmapLinear) self.cubemap.setKeepRamImage(False) self.target = RenderTarget("ScatteringCubemap") self.target.setSize(self.cubemapSize * 6, self.cubemapSize) self.target.addColorTexture() # self.target.addAuxTexture() # self.target.setAuxBits(16) # self.target.setColorBits(16) self.target.prepareOffscreenBuffer() self.target.setShaderInput("cubemapSize", self.cubemapSize) self.target.setShaderInput("cubemapDest", self.cubemap) def setShaders(self): shader = Shader.load(Shader.SLGLSL, "Shader/DefaultPostProcess.vertex", "Shader/ScatteringCubemapPass.fragment") self.target.setShader(shader) return [shader] def getOutputs(self): return { "ScatteringCubemapPass.resultCubemap": lambda: self.cubemap, }
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 peek_tex_with_clear_color(component_type, format, clear_color): """ Creates a 1-pixel texture with the given settings and clear color, then peeks the value at this pixel and returns it. """ tex = Texture("") tex.setup_1d_texture(1, component_type, format) tex.set_clear_color(clear_color) tex.make_ram_image() col = LColor() tex.peek().fetch_pixel(col, 0, 0) return col
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 _createDofStorage(self): """ Creates the texture where the dof factor is stored in, so we don't recompute it each pass """ self.dofStorage = Texture("DOFStorage") self.dofStorage.setup2dTexture( self.showbase.win.getXSize(), self.showbase.win.getYSize(), Texture.TFloat, Texture.FRg16)
def setupTexture(self): cm = CardMaker('quadMaker') 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() self.quad = NodePath(card) self.quad.reparentTo(self.parent_) self.guiTex = Texture('guiTex') self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba) self.guiTex.setMinfilter(Texture.FTLinear) self.guiTex.setKeepRamImage(True) self.guiTex.makeRamImage() self.guiTex.setWrapU(Texture.WMRepeat) self.guiTex.setWrapV(Texture.WMRepeat) ts = TextureStage('webTS') self.quad.setTexture(ts, self.guiTex) self.quad.setTexScale(ts, 1.0, -1.0) self.quad.setTransparency(0) self.quad.setTwoSided(True) self.quad.setColor(1.0, 1.0, 1.0, 1.0) self.calcMouseLimits()
def loadTexture(self, texname, container): # Note that we reference the texture files by name. This works under the # assumption that texture names are unique! if self.findTexture(texname) == True: return # texture already loaded before # print 'loading texture:', texname t_type = '' s3dentry = container.s3d_file_obj.getFile(texname) if s3dentry != None: texfile = s3dentry.data (magic,) = struct.unpack('<2s', texfile[0:2]) if magic == 'BM': t_type = 'IMG' # raw 32 bit rgba (actually argb) # Generic BMP file # patch up the sometimes irregular bmp headers texfile = self.checkBmp(texfile, texname) if texfile == None: return # turn bmp into a 32bit rgba true color image # returns a tuple of (img, width, height) img = self.createAlphaBMP(texfile, texname) texfile = img[0] # so that the addTexture() at the bottom works t = Texture() # create empty texture object component_type = Texture.TUnsignedByte format = Texture.FRgba t.setup2dTexture(img[1], img[2], component_type, format) t.setRamImage(img[0]) #t.load(ti) # load texture from pnmimage elif magic == 'DD': t_type = 'DDS' # DDS file dds = DDSFile(texfile) dds.patchHeader() # dds.dumpHeader() # dds.uncompressToBmp() # dds.save(texname+'.dds') ts = StringStream(dds.buf) # turn into an istream t = Texture() # create texture object t.readDds(ts) # load texture from dds ram image else: print 'Error unsupported texture: %s magic:%s referenced in fragment: %i' % (texname, magic, f.id) return else: print 'Error: texture %s not found in s3d archive' % (texname) return # t.setWrapU(Texture.WMClamp) # t.setWrapV(Texture.WMClamp) self.addTexture(texname, t, texfile, t_type)
def _createLastFrameBuffers(self): """ Creates the buffers which store the last frame depth, as the render target matcher cannot handle this """ self.lastFrameDepth = Texture("LastFrameDepth") self.lastFrameDepth.setup2dTexture(self.showbase.win.getXSize(), self.showbase.win.getYSize(), Texture.TFloat, Texture.FR32) BufferViewerGUI.registerTexture("LastFrameDepth", self.lastFrameDepth) self.renderPassManager.registerStaticVariable("lastFrameDepth", self.lastFrameDepth)
def _createLastFrameBuffers(self): """ Creates the buffers which store the last frame depth, as the render target matcher cannot handle this """ self.lastFrameDepth = Texture("LastFrameDepth") self.lastFrameDepth.setup2dTexture(Globals.resolution.x, Globals.resolution.y, Texture.TFloat, Texture.FR32) BufferViewerGUI.registerTexture("LastFrameDepth", self.lastFrameDepth) MemoryMonitor.addTexture("LastFrameDepth", self.lastFrameDepth) self.renderPassManager.registerStaticVariable("lastFrameDepth", self.lastFrameDepth)
def debug3DTexture(self, tex, dest): """ Writes a 3D Texture to disk """ effectiveHeight = (tex.getYSize()+1) * (tex.getZSize()) effectiveHeight -= 1 effectiveWidth = (tex.getXSize()+1)*3 effectiveHeight = tex.getYSize() effectiveWidth = tex.getXSize() self.debug("Texture Size =",tex.getXSize(),"x",tex.getYSize(),"x",tex.getZSize()) self.debug("EffectiveHeight = ", effectiveHeight, "Layers=",tex.getZSize()) store = Texture("store") store.setup2dTexture( effectiveWidth, effectiveHeight, Texture.TFloat, Texture.FRgba16) TextureCleaner.clearTexture(store, Vec4(1,0,1,1)) # Create a dummy node and apply the shader to it shader = BetterShader.loadCompute("Shader/Write3DTexture.compute") dummy = NodePath("dummy") dummy.setShader(shader) dummy.setShaderInput("source", tex) dummy.setShaderInput("height", tex.getYSize() + 1) dummy.setShaderInput("width", tex.getXSize() + 1) dummy.setShaderInput("layerCount", tex.getZSize()) dummy.setShaderInput("destination", store) # Retrieve the underlying ShaderAttrib sattr = dummy.get_attrib(ShaderAttrib) # Dispatch the compute shader, right now! Globals.base.graphicsEngine.dispatch_compute( (tex.getXSize() / 16, tex.getYSize() / 16, tex.getZSize()), sattr, base.win.get_gsg()) Globals.base.graphicsEngine.extract_texture_data( store, Globals.base.win.getGsg()) store.write(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 reconfigure(self, fullrebuild, changed): """ Reconfigure is called whenever any configuration change is made. """ configuration = self.configuration if (fullrebuild): self.cleanup() if (len(configuration) == 0): return if not self.manager.win.gsg.getSupportsBasicShaders(): return False auxbits = 0 needtex = set(["color"]) needtexcoord = set(["color"]) if ("CartoonInk" in configuration): needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("aux") if ("AmbientOcclusion" in configuration): needtex.add("depth") needtex.add("ssao0") needtex.add("ssao1") needtex.add("ssao2") needtex.add("aux") auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add("ssao2") if ("BlurSharpen" in configuration): needtex.add("blur0") needtex.add("blur1") needtexcoord.add("blur1") if ("Bloom" in configuration): needtex.add("bloom0") needtex.add("bloom1") needtex.add("bloom2") needtex.add("bloom3") auxbits |= AuxBitplaneAttrib.ABOGlow needtexcoord.add("bloom3") if ("ViewGlow" in configuration): auxbits |= AuxBitplaneAttrib.ABOGlow if ("VolumetricLighting" in configuration): needtex.add(configuration["VolumetricLighting"].source) for tex in needtex: self.textures[tex] = Texture("scene-" + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if (self.finalQuad == None): self.cleanup() return False if ("BlurSharpen" in configuration): blur0 = self.textures["blur0"] blur1 = self.textures["blur1"] self.blur.append( self.manager.renderQuadInto("filter-blur0", colortex=blur0, div=2)) self.blur.append( self.manager.renderQuadInto("filter-blur1", colortex=blur1)) self.blur[0].setShaderInput("src", self.textures["color"]) self.blur[0].setShader(Shader.make(BLUR_X, Shader.SL_Cg)) self.blur[1].setShaderInput("src", blur0) self.blur[1].setShader(Shader.make(BLUR_Y, Shader.SL_Cg)) if ("AmbientOcclusion" in configuration): ssao0 = self.textures["ssao0"] ssao1 = self.textures["ssao1"] ssao2 = self.textures["ssao2"] self.ssao.append( self.manager.renderQuadInto("filter-ssao0", colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto("filter-ssao1", colortex=ssao1, div=2)) self.ssao.append( self.manager.renderQuadInto("filter-ssao2", colortex=ssao2)) self.ssao[0].setShaderInput("depth", self.textures["depth"]) self.ssao[0].setShaderInput("normal", self.textures["aux"]) self.ssao[0].setShaderInput( "random", loader.loadTexture("maps/random.rgb")) self.ssao[0].setShader( Shader.make( SSAO_BODY % configuration["AmbientOcclusion"].numsamples, Shader.SL_Cg)) self.ssao[1].setShaderInput("src", ssao0) self.ssao[1].setShader(Shader.make(BLUR_X, Shader.SL_Cg)) self.ssao[2].setShaderInput("src", ssao1) self.ssao[2].setShader(Shader.make(BLUR_Y, Shader.SL_Cg)) if ("Bloom" in configuration): bloomconf = configuration["Bloom"] bloom0 = self.textures["bloom0"] bloom1 = self.textures["bloom1"] bloom2 = self.textures["bloom2"] bloom3 = self.textures["bloom3"] if (bloomconf.size == "large"): scale = 8 downsamplerName = "filter-down4" downsampler = DOWN_4 elif (bloomconf.size == "medium"): scale = 4 downsamplerName = "filter-copy" downsampler = COPY else: scale = 2 downsamplerName = "filter-copy" downsampler = COPY self.bloom.append( self.manager.renderQuadInto("filter-bloomi", colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(downsamplerName, colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto("filter-bloomx", colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto("filter-bloomy", colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput("src", self.textures["color"]) self.bloom[0].setShader(Shader.make(BLOOM_I, Shader.SL_Cg)) self.bloom[1].setShaderInput("src", bloom0) self.bloom[1].setShader(Shader.make(downsampler, Shader.SL_Cg)) self.bloom[2].setShaderInput("src", bloom1) self.bloom[2].setShader(Shader.make(BLOOM_X, Shader.SL_Cg)) self.bloom[3].setShaderInput("src", bloom2) self.bloom[3].setShader(Shader.make(BLOOM_Y, Shader.SL_Cg)) texcoords = {} texcoordPadding = {} for tex in needtexcoord: if self.textures[tex].getAutoTextureScale() != ATSNone or \ "HalfPixelShift" in configuration: texcoords[tex] = "l_texcoord_" + tex texcoordPadding["l_texcoord_" + tex] = tex else: # Share unpadded texture coordinates. texcoords[tex] = "l_texcoord" texcoordPadding["l_texcoord"] = None texcoordSets = list(enumerate(texcoordPadding.keys())) text = "//Cg\n" text += "void vshader(float4 vtx_position : POSITION,\n" text += " out float4 l_position : POSITION,\n" for texcoord, padTex in texcoordPadding.items(): if padTex is not None: text += " uniform float4 texpad_tx%s,\n" % (padTex) if ("HalfPixelShift" in configuration): text += " uniform float4 texpix_tx%s,\n" % (padTex) for i, name in texcoordSets: text += " out float2 %s : TEXCOORD%d,\n" % (name, i) text += " uniform float4x4 mat_modelproj)\n" text += "{\n" text += " l_position = mul(mat_modelproj, vtx_position);\n" for texcoord, padTex in texcoordPadding.items(): if padTex is None: text += " %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n" % ( texcoord) else: text += " %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n" % ( texcoord, padTex, padTex) if ("HalfPixelShift" in configuration): text += " %s += texpix_tx%s.xy * 0.5;\n" % (texcoord, padTex) text += "}\n" text += "void fshader(\n" for i, name in texcoordSets: text += " float2 %s : TEXCOORD%d,\n" % (name, i) for key in self.textures: text += " uniform sampler2D k_tx" + key + ",\n" if ("CartoonInk" in configuration): text += " uniform float4 k_cartoonseparation,\n" text += " uniform float4 k_cartooncolor,\n" text += " uniform float4 texpix_txaux,\n" if ("BlurSharpen" in configuration): text += " uniform float4 k_blurval,\n" if ("VolumetricLighting" in configuration): text += " uniform float4 k_casterpos,\n" text += " uniform float4 k_vlparams,\n" text += " out float4 o_color : COLOR)\n" text += "{\n" text += " o_color = tex2D(k_txcolor, %s);\n" % ( texcoords["color"]) if ("CartoonInk" in configuration): text += CARTOON_BODY % {"texcoord": texcoords["aux"]} if ("AmbientOcclusion" in configuration): text += " o_color *= tex2D(k_txssao2, %s).r;\n" % ( texcoords["ssao2"]) if ("BlurSharpen" in configuration): text += " o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n" % ( texcoords["blur1"]) if ("Bloom" in configuration): text += " o_color = saturate(o_color);\n" text += " float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n" % ( texcoords["bloom3"]) text += " o_color = 1-((1-bloom)*(1-o_color));\n" if ("ViewGlow" in configuration): text += " o_color.r = o_color.a;\n" if ("VolumetricLighting" in configuration): text += " float decay = 1.0f;\n" text += " float2 curcoord = %s;\n" % (texcoords["color"]) text += " float2 lightdir = curcoord - k_casterpos.xy;\n" text += " lightdir *= k_vlparams.x;\n" text += " half4 sample = tex2D(k_txcolor, curcoord);\n" text += " float3 vlcolor = sample.rgb * sample.a;\n" text += " for (int i = 0; i < %s; i++) {\n" % (int( configuration["VolumetricLighting"].numsamples)) text += " curcoord -= lightdir;\n" text += " sample = tex2D(k_tx%s, curcoord);\n" % ( configuration["VolumetricLighting"].source) text += " sample *= sample.a * decay;//*weight\n" text += " vlcolor += sample.rgb;\n" text += " decay *= k_vlparams.y;\n" text += " }\n" text += " o_color += float4(vlcolor * k_vlparams.z, 1);\n" if ("GammaAdjust" in configuration): gamma = configuration["GammaAdjust"] if gamma == 0.5: text += " o_color.rgb = sqrt(o_color.rgb);\n" elif gamma == 2.0: text += " o_color.rgb *= o_color.rgb;\n" elif gamma != 1.0: text += " o_color.rgb = pow(o_color.rgb, %ff);\n" % ( gamma) if ("Inverted" in configuration): text += " o_color = float4(1, 1, 1, 1) - o_color;\n" text += "}\n" shader = Shader.make(text, Shader.SL_Cg) if not shader: return False self.finalQuad.setShader(shader) for tex in self.textures: self.finalQuad.setShaderInput("tx" + tex, self.textures[tex]) self.task = taskMgr.add(self.update, "common-filters-update") if (changed == "CartoonInk") or fullrebuild: if ("CartoonInk" in configuration): c = configuration["CartoonInk"] self.finalQuad.setShaderInput( "cartoonseparation", LVecBase4(c.separation, 0, c.separation, 0)) self.finalQuad.setShaderInput("cartooncolor", c.color) if (changed == "BlurSharpen") or fullrebuild: if ("BlurSharpen" in configuration): blurval = configuration["BlurSharpen"] self.finalQuad.setShaderInput( "blurval", LVecBase4(blurval, blurval, blurval, blurval)) if (changed == "Bloom") or fullrebuild: if ("Bloom" in configuration): bloomconf = configuration["Bloom"] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput("blend", bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( "trigger", bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput("desat", bloomconf.desat) self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity) if (changed == "VolumetricLighting") or fullrebuild: if ("VolumetricLighting" in configuration): config = configuration["VolumetricLighting"] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput("vlparams", tcparam, config.decay, config.exposure, 0.0) if (changed == "AmbientOcclusion") or fullrebuild: if ("AmbientOcclusion" in configuration): config = configuration["AmbientOcclusion"] self.ssao[0].setShaderInput( "params1", config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput("params2", config.strength, config.falloff, 0, 0) self.update() return True
mat.set_emission((1.0, 1.0, 1.0, 1)) mat.set_metallic(1.0) mat.set_roughness(1.0) card_np.set_material(mat) texture_size = 256 texture_bands_x = 2 texture_bands_y = 2 # Base color, a.k.a. Modulate, a.k.a. albedo map # Gets multiplied with mat.base_color base_color_pnm = PNMImage(texture_size, texture_size) base_color_pnm.fill(0.72, 0.45, 0.2) # Copper base_color_tex = Texture("BaseColor") base_color_tex.load(base_color_pnm) ts = TextureStage('BaseColor') # a.k.a. Modulate ts.set_mode(TextureStage.M_modulate) card_np.set_texture(ts, base_color_tex) # Emission; Gets multiplied with mat.emission emission_pnm = PNMImage(texture_size, texture_size) emission_pnm.fill(0.0, 0.0, 0.0) emission_tex = Texture("Emission") emission_tex.load(emission_pnm) ts = TextureStage('Emission') ts.set_mode(TextureStage.M_emission) card_np.set_texture(ts, emission_tex)
def getPmPerceptualError(mesh, pm_filebuf, mipmap_tarfilebuf): perceptualdiff = which('perceptualdiff') if perceptualdiff is None: raise Exception("perceptualdiff exectuable not found on path") pm_chunks = [] if pm_filebuf is not None: data = pm_filebuf.read(PM_CHUNK_SIZE) refinements_read = 0 num_refinements = None while len(data) > 0: (refinements_read, num_refinements, pm_refinements, data_left) = pdae_utils.readPDAEPartial(data, refinements_read, num_refinements) pm_chunks.append(pm_refinements) data = data_left + pm_filebuf.read(PM_CHUNK_SIZE) tar = tarfile.TarFile(fileobj=mipmap_tarfilebuf) texsizes = [] largest_tarinfo = (0, None) for tarinfo in tar: tarinfo.xsize = int(tarinfo.name.split('x')[0]) if tarinfo.xsize > largest_tarinfo[0]: largest_tarinfo = (tarinfo.xsize, tarinfo) if tarinfo.xsize >= 128: texsizes.append(tarinfo) if len(texsizes) == 0: texsizes.append(largest_tarinfo[1]) texsizes = sorted(texsizes, key=lambda t: t.xsize) texims = [] first_image_data = None for tarinfo in texsizes: f = tar.extractfile(tarinfo) texdata = f.read() if first_image_data is None: first_image_data = texdata texpnm = PNMImage() texpnm.read(StringStream(texdata), 'something.jpg') newtex = Texture() newtex.load(texpnm) texims.append(newtex) mesh.images[0].setData(first_image_data) scene_members = getSceneMembers(mesh) # turn off panda3d printing to stdout nout = MultiplexStream() Notify.ptr().setOstreamPtr(nout, 0) nout.addFile(Filename(os.devnull)) base = ShowBase() rotateNode = GeomNode("rotater") rotatePath = base.render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) wrappedNode = ensureCameraAt(geomPath, base.camera) base.disableMouse() attachLights(base.render) base.render.setShaderAuto() base.render.setTransparency(TransparencyAttrib.MNone) base.render.setColorScaleOff(9999) controls.KeyboardMovement() controls.MouseDrag(wrappedNode) controls.MouseScaleZoom(wrappedNode) controls.ButtonUtils(wrappedNode) controls.MouseCamera() error_data = [] try: tempdir = tempfile.mkdtemp(prefix='meshtool-print-pm-perceptual-error') triangleCounts = [] hprs = [(0, 0, 0), (0, 90, 0), (0, 180, 0), (0, 270, 0), (90, 0, 0), (-90, 0, 0)] for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) for pm_chunk in pm_chunks: pdae_panda.add_refinements(geomPath, pm_chunk) for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) full_tris = triangleCounts[-1] full_tex = texims[-1] for numtris in triangleCounts: for texim in texims: pixel_diff = 0 for angle, hpr in enumerate(hprs): curFile = '%d_%d_%d_%d.png' % (numtris, texim.getXSize(), texim.getYSize(), angle) curFile = os.path.join(tempdir, curFile) fullFile = '%d_%d_%d_%d.png' % (full_tris, full_tex.getXSize(), full_tex.getYSize(), angle) fullFile = os.path.join(tempdir, fullFile) try: output = subprocess.check_output([ perceptualdiff, '-threshold', '1', fullFile, curFile ]) except subprocess.CalledProcessError as ex: output = ex.output output = output.strip() if len(output) > 0: pixel_diff = max(pixel_diff, int(output.split('\n')[1].split()[0])) error_data.append({ 'triangles': numtris, 'width': texim.getXSize(), 'height': texim.getYSize(), 'pixel_error': pixel_diff }) finally: shutil.rmtree(tempdir, ignore_errors=True) return error_data
def load(self, path): # vignette mask self.vignette_mask = None self.vignette_mask_small = None vfile = os.path.join(path, "vignette-mask.jpg") if os.path.exists(vfile): print("loading vignette correction mask:", vfile) self.vignette_mask = cv2.imread(vfile, flags=cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH | cv2.IMREAD_IGNORE_ORIENTATION) self.vignette_mask_small = cv2.resize(self.vignette_mask, (512, 512)) files = [] for file in sorted(os.listdir(path)): if fnmatch.fnmatch(file, '*.egg'): # print('load:', file) files.append(file) print('Loading models:') for file in tqdm(files, ascii=True): # load and reparent each egg file pandafile = Filename.fromOsSpecific(os.path.join(path, file)) model = self.loader.loadModel(pandafile) # model.set_shader(self.shader) # print(file) # self.pretty_print(model, ' ') model.reparentTo(self.render) self.models.append(model) tex = model.findTexture('*') if tex != None: tex.setWrapU(Texture.WM_clamp) tex.setWrapV(Texture.WM_clamp) self.base_textures.append(tex) # The egg model lists "dummy.jpg" as the texture model which # doesn't exists. Here we load the actual textures and # possibly apply vignette correction and adaptive histogram # equalization. print('Loading base textures:') for i, model in enumerate(tqdm(self.models, ascii=True)): base, ext = os.path.splitext(model.getName()) image_file = None dir = os.path.join(proj.analysis_dir, 'models') tmp1 = os.path.join(dir, base + '.JPG') tmp2 = os.path.join(dir, base + '.jpg') if os.path.isfile(tmp1): image_file = tmp1 elif os.path.isfile(tmp2): image_file = tmp2 #print("texture file:", image_file) if False: tex = self.loader.loadTexture(image_file) else: rgb = cv2.imread(image_file, flags=cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH | cv2.IMREAD_IGNORE_ORIENTATION) rgb = np.flipud(rgb) # vignette correction if not self.vignette_mask_small is None: rgb = rgb.astype('uint16') + self.vignette_mask_small rgb = np.clip(rgb, 0, 255).astype('uint8') # adaptive equalization hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) aeq = clahe.apply(val) # recombine hsv = cv2.merge((hue, sat, aeq)) # convert back to rgb rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) tex = Texture(base) tex.setCompression(Texture.CMOff) tex.setup2dTexture(512, 512, Texture.TUnsignedByte, Texture.FRgb) tex.setRamImage(rgb) tex.setWrapU(Texture.WM_clamp) tex.setWrapV(Texture.WM_clamp) model.setTexture(tex, 1) self.base_textures[i] = tex self.sortImages() self.annotations.rebuild(self.view_size)
class MazeMapGui(DirectFrame): notify = directNotify.newCategory('MazeMapGui') def __init__(self, mazeCollTable, maskResolution=None, radiusRatio=None, bgColor=(0.8, 0.8, 0.8), fgColor=(0.5, 0.5, 0.5, 1.0)): DirectFrame.__init__(self, relief=None, state=DGG.NORMAL, sortOrder=DGG.BACKGROUND_SORT_INDEX) self.hide() self._bgColor = bgColor self._fgColor = fgColor self._mazeCollTable = mazeCollTable self._mazeWidth = len(self._mazeCollTable[0]) self._mazeHeight = len(self._mazeCollTable) self._maskResolution = maskResolution or DEFAULT_MASK_RESOLUTION if radiusRatio is None: self._radius = self._maskResolution * DEFAULT_RADIUS_RATIO else: self._radius = self._maskResolution * radiusRatio self._revealedCells = [] for y in xrange(self._mazeHeight): self._revealedCells.append([]) for u in xrange(self._mazeWidth): self._revealedCells[y].append(False) self._revealFunctions = { MazeRevealType.SmoothCircle: self._revealSmoothCircle, MazeRevealType.HardCircle: self._revealHardCircle, MazeRevealType.Square: self._revealSquare } self._revealFunction = MAZE_REVEAL_TYPE self.map = self._createMapTextureCard() self.map.reparentTo(self) self.maskedLayer = self.attachNewNode('maskedLayer') self.mask = self._createMaskTextureCard() self.mask.reparentTo(self) self.visibleLayer = self.attachNewNode('visibleLayer') self._laffMeterModel = loader.loadModel( 'phase_3/models/gui/laff_o_meter') self._toon2marker = {} return 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 _createMaskTextureCard(self): self._maskImage = PNMImage(self._maskResolution, self._maskResolution, 4) for x in xrange(self._maskResolution): for y in xrange(self._maskResolution): self._maskImage.setXelA(x, y, 0, 0, 0, 1) self.maskTexture = Texture('maskTexture') self.maskTexture.setupTexture(Texture.TT2dTexture, self._maskResolution, self._maskResolution, 1, Texture.TUnsignedByte, Texture.FRgba) self.maskTexture.setMinfilter(Texture.FTLinear) self.maskTexture.setWrapU(Texture.WMClamp) self.maskTexture.setWrapV(Texture.WMClamp) self.maskTexture.load(self._maskImage) base.graphicsEngine.renderFrame() cm = CardMaker('mask_cardMaker') cm.setFrame(-1.1, 1.1, -1.1, 1.1) mask = self.attachNewNode(cm.generate()) mask.setTexture(self.maskTexture, 1) mask.setTransparency(1) return mask def _drawSquare(self, image, ulx, uly, size, color): x = int(ulx) while x <= ulx + size: y = int(uly) while y <= uly + size: if x > 0 and y > 0 and x < image.getXSize( ) and y < image.getYSize(): image.setXelA(x, y, color) y += 1 x += 1 def destroy(self): del self._mazeCollTable del self._maskResolution del self._radius del self._revealedCells del self._revealFunctions del self._revealFunction self.map.removeNode() del self.map self.mask.removeNode() del self.mask self.maskedLayer.removeNode() del self.maskedLayer self.visibleLayer.removeNode() del self.visibleLayer self._maskImage.clear() del self._maskImage self.maskTexture.clear() del self.maskTexture self._laffMeterModel.removeNode() del self._laffMeterModel DirectFrame.destroy(self) def _revealSmoothCircle(self, x, y, center): length = (Vec2(x, y) - center).length() goalAlpha = max(0.0, length / float(self._radius) - 0.5) self._maskImage.setXelA( x, y, VBase4D(0.0, 0.0, 0.0, min(self._maskImage.getAlpha(x, y), goalAlpha * 2.0))) def _revealHardCircle(self, x, y, center): length = (Vec2(x, y) - center).length() if length <= self._radius: self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0)) def _revealSquare(self, x, y, center): self._maskImage.setXelA(x, y, VBase4D(0, 0, 0, 0)) def _drawHole(self, x, y): center = Vec2(x, y) ul = center - Vec2(self._radius, self._radius) lr = center + Vec2(self._radius, self._radius) x = int(ul[0]) while x <= lr[0]: y = int(ul[1]) while y <= lr[1]: if x > 0 and y > 0 and x < self._maskResolution and y < self._maskResolution: self._revealFunctions[self._revealFunction](x, y, center) y += 1 x += 1 self.maskTexture.load(self._maskImage) self.mask.setTexture(self.maskTexture, 1) def _createSimpleMarker(self, size, color=(1, 1, 1)): halfSize = size * 0.5 cm = CardMaker('mazemap_simple_marker') cm.setFrame(-halfSize, halfSize, -halfSize, halfSize) markerNP = self.maskedLayer.attachNewNode(cm.generate()) markerNP.setColor(*color) return markerNP def tile2gui(self, x, y): y = self._mazeHeight - y cellWidth = self._maskResolution / self._mazeWidth cellHeight = self._maskResolution / self._mazeHeight ax = float(x) / self._mazeWidth * self._maskResolution ax += cellWidth ay = float(y) / self._mazeHeight * self._maskResolution ay += cellHeight return (ax, ay) def gui2pos(self, x, y): return (x / self._maskResolution * 2.0 - 0.97, 0, y / self._maskResolution * -2.0 + 1.02) def _getToonMarker(self, toon): hType = toon.style.getType() if hType == 'rabbit': hType = 'bunny' return self._laffMeterModel.find('**/' + hType + 'head') def addToon(self, toon, tX, tY): marker = NodePath('toon_marker-%i' % toon.doId) marker.reparentTo(self) self._getToonMarker(toon).copyTo(marker) marker.setColor(toon.style.getHeadColor()) if toon.isLocal(): marker.setScale(0.07) else: marker.setScale(0.05) marker.flattenStrong() marker.setPos(*self.gui2pos(*self.tile2gui(tX, tY))) self._toon2marker[toon] = marker def removeToon(self, toon): if toon not in self._toon2marker: return self._toon2marker[toon].removeNode() del self._toon2marker[toon] def updateToon(self, toon, tX, tY): if toon not in self._toon2marker: return x, y = self.tile2gui(tX, tY) self._toon2marker[toon].setPos(*self.gui2pos(x, y)) if tY < 0 or tY >= len(self._revealedCells): self.notify.warning('updateToon earlying out:') self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY)) self.notify.warning('len(_revealedCells): %s' % (len(self._revealedCells), )) if len(self._revealedCells) > 0: self.notify.warning('len(_revealedCells[0]): %s' % (len(self._revealedCells[0]), )) return if tX < 0 or tX >= len(self._revealedCells[tY]): self.notify.warning('updateToon earlying out:') self.notify.warning('(tX, tY): (%s, %s)' % (tX, tY)) self.notify.warning('len(_revealedCells): %s' % (len(self._revealedCells), )) if tY < len(self._revealedCells): self.notify.warning('len(_revealedCells[tY]): %s' % (len(self._revealedCells[tY]), )) elif len(self._revealedCells) > 0: self.notify.warning('len(_revealedCells[0]): %s' % (len(self._revealedCells[0]), )) return if not self._revealedCells[tY][tX]: self._drawHole(x, y) self._revealedCells[tY][tX] = True def revealCell(self, x, y): ax, ay = self.tile2gui(x, y) if not self._revealedCells[y][x]: self._drawHole(ax, ay) self._revealedCells[y][x] = True def revealAll(self): for x in xrange(self._maskResolution): for y in xrange(self._maskResolution): self._maskImage.setXelA(x, y, 0, 0, 0, 0) self.revealCell(0, 0) def reset(self): for x in xrange(self._maskResolution): for y in xrange(self._maskResolution): self._maskImage.setXelA(x, y, 0, 0, 0, 1)
def reconfigure(self, fullrebuild, changed): configuration = self.configuration if fullrebuild: self.cleanup() if len(configuration) == 0: return auxbits = 0 needtex = set(['color']) needtexcoord = set(['color']) if 'CartoonInk' in configuration: needtex.add('aux') auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add('aux') if 'AmbientOcclusion' in configuration: needtex.add('depth') needtex.add('ssao0') needtex.add('ssao1') needtex.add('ssao2') needtex.add('aux') auxbits |= AuxBitplaneAttrib.ABOAuxNormal needtexcoord.add('ssao2') if 'BlurSharpen' in configuration: needtex.add('blur0') needtex.add('blur1') needtexcoord.add('blur1') if 'Bloom' in configuration: needtex.add('bloom0') needtex.add('bloom1') needtex.add('bloom2') needtex.add('bloom3') auxbits |= AuxBitplaneAttrib.ABOGlow needtexcoord.add('bloom3') if 'ViewGlow' in configuration: auxbits |= AuxBitplaneAttrib.ABOGlow if 'VolumetricLighting' in configuration: needtex.add(configuration['VolumetricLighting'].source) for tex in needtex: self.textures[tex] = Texture('scene-' + tex) self.textures[tex].setWrapU(Texture.WMClamp) self.textures[tex].setWrapV(Texture.WMClamp) self.finalQuad = self.manager.renderSceneInto( textures=self.textures, auxbits=auxbits) if self.finalQuad == None: self.cleanup() return False if 'BlurSharpen' in configuration: blur0 = self.textures['blur0'] blur1 = self.textures['blur1'] self.blur.append( self.manager.renderQuadInto(colortex=blur0, div=2)) self.blur.append(self.manager.renderQuadInto(colortex=blur1)) self.blur[0].setShaderInput('src', self.textures['color']) self.blur[0].setShader(self.loadShader('filter-blurx.sha')) self.blur[1].setShaderInput('src', blur0) self.blur[1].setShader(self.loadShader('filter-blury.sha')) if 'AmbientOcclusion' in configuration: ssao0 = self.textures['ssao0'] ssao1 = self.textures['ssao1'] ssao2 = self.textures['ssao2'] self.ssao.append(self.manager.renderQuadInto(colortex=ssao0)) self.ssao.append( self.manager.renderQuadInto(colortex=ssao1, div=2)) self.ssao.append(self.manager.renderQuadInto(colortex=ssao2)) self.ssao[0].setShaderInput('depth', self.textures['depth']) self.ssao[0].setShaderInput('normal', self.textures['aux']) self.ssao[0].setShaderInput( 'random', loader.loadTexture('maps/random.rgb')) self.ssao[0].setShader( Shader.make( SSAO_BODY % configuration['AmbientOcclusion'].numsamples, Shader.SL_Cg)) self.ssao[1].setShaderInput('src', ssao0) self.ssao[1].setShader(self.loadShader('filter-blurx.sha')) self.ssao[2].setShaderInput('src', ssao1) self.ssao[2].setShader(self.loadShader('filter-blury.sha')) if 'Bloom' in configuration: bloomconf = configuration['Bloom'] bloom0 = self.textures['bloom0'] bloom1 = self.textures['bloom1'] bloom2 = self.textures['bloom2'] bloom3 = self.textures['bloom3'] if bloomconf.size == 'large': scale = 8 downsampler = 'filter-down4.sha' else: if bloomconf.size == 'medium': scale = 4 downsampler = 'filter-copy.sha' else: scale = 2 downsampler = 'filter-copy.sha' self.bloom.append( self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale)) self.bloom.append( self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale)) self.bloom[0].setShaderInput('src', self.textures['color']) self.bloom[0].setShader(self.loadShader('filter-bloomi.sha')) self.bloom[1].setShaderInput('src', bloom0) self.bloom[1].setShader(self.loadShader(downsampler)) self.bloom[2].setShaderInput('src', bloom1) self.bloom[2].setShader(self.loadShader('filter-bloomx.sha')) self.bloom[3].setShaderInput('src', bloom2) self.bloom[3].setShader(self.loadShader('filter-bloomy.sha')) texcoords = {} texcoordPadding = {} for tex in needtexcoord: if self.textures[tex].getAutoTextureScale( ) != ATSNone or 'HalfPixelShift' in configuration: texcoords[tex] = 'l_texcoord_' + tex texcoordPadding['l_texcoord_' + tex] = tex else: texcoords[tex] = 'l_texcoord' texcoordPadding['l_texcoord'] = None texcoordSets = list(enumerate(texcoordPadding.keys())) text = '//Cg\n' text += 'void vshader(float4 vtx_position : POSITION,\n' text += ' out float4 l_position : POSITION,\n' for texcoord, padTex in texcoordPadding.items(): if padTex is not None: text += ' uniform float4 texpad_tx%s,\n' % padTex if 'HalfPixelShift' in configuration: text += ' uniform float4 texpix_tx%s,\n' % padTex for i, name in texcoordSets: text += ' out float2 %s : TEXCOORD%d,\n' % (name, i) text += ' uniform float4x4 mat_modelproj)\n' text += '{\n' text += ' l_position = mul(mat_modelproj, vtx_position);\n' for texcoord, padTex in texcoordPadding.items(): if padTex is None: text += ' %s = vtx_position.xz * float2(0.5, 0.5) + float2(0.5, 0.5);\n' % texcoord else: text += ' %s = (vtx_position.xz * texpad_tx%s.xy) + texpad_tx%s.xy;\n' % ( texcoord, padTex, padTex) if 'HalfPixelShift' in configuration: text += ' %s += texpix_tx%s.xy * 0.5;\n' % (texcoord, padTex) text += '}\n' text += 'void fshader(\n' for i, name in texcoordSets: text += ' float2 %s : TEXCOORD%d,\n' % (name, i) for key in self.textures: text += ' uniform sampler2D k_tx' + key + ',\n' if 'CartoonInk' in configuration: text += ' uniform float4 k_cartoonseparation,\n' text += ' uniform float4 k_cartooncolor,\n' text += ' uniform float4 texpix_txaux,\n' if 'BlurSharpen' in configuration: text += ' uniform float4 k_blurval,\n' if 'VolumetricLighting' in configuration: text += ' uniform float4 k_casterpos,\n' text += ' uniform float4 k_vlparams,\n' text += ' out float4 o_color : COLOR)\n' text += '{\n' text += ' o_color = tex2D(k_txcolor, %s);\n' % texcoords['color'] if 'CartoonInk' in configuration: text += CARTOON_BODY % {'texcoord': texcoords['aux']} if 'AmbientOcclusion' in configuration: text += ' o_color *= tex2D(k_txssao2, %s).r;\n' % texcoords[ 'ssao2'] if 'BlurSharpen' in configuration: text += ' o_color = lerp(tex2D(k_txblur1, %s), o_color, k_blurval.x);\n' % texcoords[ 'blur1'] if 'Bloom' in configuration: text += ' o_color = saturate(o_color);\n' text += ' float4 bloom = 0.5 * tex2D(k_txbloom3, %s);\n' % texcoords[ 'bloom3'] text += ' o_color = 1-((1-bloom)*(1-o_color));\n' if 'ViewGlow' in configuration: text += ' o_color.r = o_color.a;\n' if 'VolumetricLighting' in configuration: text += ' float decay = 1.0f;\n' text += ' float2 curcoord = %s;\n' % texcoords['color'] text += ' float2 lightdir = curcoord - k_casterpos.xy;\n' text += ' lightdir *= k_vlparams.x;\n' text += ' half4 sample = tex2D(k_txcolor, curcoord);\n' text += ' float3 vlcolor = sample.rgb * sample.a;\n' text += ' for (int i = 0; i < %s; i++) {\n' % int( configuration['VolumetricLighting'].numsamples) text += ' curcoord -= lightdir;\n' text += ' sample = tex2D(k_tx%s, curcoord);\n' % configuration[ 'VolumetricLighting'].source text += ' sample *= sample.a * decay;//*weight\n' text += ' vlcolor += sample.rgb;\n' text += ' decay *= k_vlparams.y;\n' text += ' }\n' text += ' o_color += float4(vlcolor * k_vlparams.z, 1);\n' if 'GammaAdjust' in configuration: gamma = configuration['GammaAdjust'] if gamma == 0.5: text += ' o_color.rgb = sqrt(o_color.rgb);\n' elif gamma == 2.0: text += ' o_color.rgb *= o_color.rgb;\n' elif gamma != 1.0: text += ' o_color.rgb = pow(o_color.rgb, %ff);\n' % gamma if 'Inverted' in configuration: text += ' o_color = float4(1, 1, 1, 1) - o_color;\n' text += '}\n' self.finalQuad.setShader(Shader.make(text, Shader.SL_Cg)) for tex in self.textures: self.finalQuad.setShaderInput('tx' + tex, self.textures[tex]) self.task = taskMgr.add(self.update, 'common-filters-update') if changed == 'CartoonInk' or fullrebuild: if 'CartoonInk' in configuration: c = configuration['CartoonInk'] self.finalQuad.setShaderInput( 'cartoonseparation', LVecBase4(c.separation, 0, c.separation, 0)) self.finalQuad.setShaderInput('cartooncolor', c.color) if changed == 'BlurSharpen' or fullrebuild: if 'BlurSharpen' in configuration: blurval = configuration['BlurSharpen'] self.finalQuad.setShaderInput( 'blurval', LVecBase4(blurval, blurval, blurval, blurval)) if changed == 'Bloom' or fullrebuild: if 'Bloom' in configuration: bloomconf = configuration['Bloom'] intensity = bloomconf.intensity * 3.0 self.bloom[0].setShaderInput('blend', bloomconf.blendx, bloomconf.blendy, bloomconf.blendz, bloomconf.blendw * 2.0) self.bloom[0].setShaderInput( 'trigger', bloomconf.mintrigger, 1.0 / (bloomconf.maxtrigger - bloomconf.mintrigger), 0.0, 0.0) self.bloom[0].setShaderInput('desat', bloomconf.desat) self.bloom[3].setShaderInput('intensity', intensity, intensity, intensity, intensity) if changed == 'VolumetricLighting' or fullrebuild: if 'VolumetricLighting' in configuration: config = configuration['VolumetricLighting'] tcparam = config.density / float(config.numsamples) self.finalQuad.setShaderInput('vlparams', tcparam, config.decay, config.exposure, 0.0) if changed == 'AmbientOcclusion' or fullrebuild: if 'AmbientOcclusion' in configuration: config = configuration['AmbientOcclusion'] self.ssao[0].setShaderInput( 'params1', config.numsamples, -float(config.amount) / config.numsamples, config.radius, 0) self.ssao[0].setShaderInput('params2', config.strength, config.falloff, 0, 0) self.update() return True
def create_default_texture(self): image = self.create_default_image() texture = Texture() texture.load(image) return (texture, 0, 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 gl-version 4 3 """) 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.gsg) base.graphicsEngine.extract_texture_data(dest_tex, base.win.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 updateTexture(self, main): dir_node = getNode('/config/directories', True) # reset base textures for i, m in enumerate(self.models): if m != main: if m.getName() in tcache: fulltex = tcache[m.getName()][1] self.models[i].setTexture(fulltex, 1) else: if self.base_textures[i] != None: self.models[i].setTexture(self.base_textures[i], 1) else: print(m.getName()) if m.getName() in tcache: fulltex = tcache[m.getName()][1] self.models[i].setTexture(fulltex, 1) continue base, ext = os.path.splitext(m.getName()) image_file = None search = [args.project, os.path.join(args.project, 'images')] for dir in search: tmp1 = os.path.join(dir, base + '.JPG') tmp2 = os.path.join(dir, base + '.jpg') if os.path.isfile(tmp1): image_file = tmp1 elif os.path.isfile(tmp2): image_file = tmp2 if not image_file: print( 'Warning: no full resolution image source file found:', base) else: if True: # example of passing an opencv image as a # panda texture print(base, image_file) #image = proj.findImageByName(base) #print(image) rgb = cv2.imread(image_file, flags=cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH | cv2.IMREAD_IGNORE_ORIENTATION) rgb = np.flipud(rgb) # vignette correction if not self.vignette_mask is None: rgb = rgb.astype('uint16') + self.vignette_mask rgb = np.clip(rgb, 0, 255).astype('uint8') h, w = rgb.shape[:2] print('shape: (%d,%d)' % (w, h)) rescale = False if h > self.max_texture_dimension: h = self.max_texture_dimension rescale = True if w > self.max_texture_dimension: w = self.max_texture_dimension rescale = True if self.needs_pow2: h2 = 2**math.floor(math.log(h, 2)) w2 = 2**math.floor(math.log(w, 2)) if h2 != h: h = h2 rescale = True if w2 != w: w = w2 rescale = True if rescale: print( "Notice: rescaling texture to (%d,%d) to honor video card capability." % (w, h)) rgb = cv2.resize(rgb, (w, h)) # filter_by = 'none' filter_by = 'equalize_value' # filter_by = 'equalize_rgb' # filter_by = 'equalize_blue' # filter_by = 'equalize_green' # filter_by = 'equalize_blue' # filter_by = 'equalize_red' # filter_by = 'red/green' if filter_by == 'none': b, g, r = cv2.split(rgb) result = cv2.merge((b, g, r)) if filter_by == 'equalize_value': # equalize val (essentially gray scale level) hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) aeq = clahe.apply(val) # recombine hsv = cv2.merge((hue, sat, aeq)) # convert back to rgb result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) elif filter_by == 'equalize_rgb': # equalize individual b, g, r channels b, g, r = cv2.split(rgb) b = clahe.apply(b) g = clahe.apply(g) r = clahe.apply(r) result = cv2.merge((b, g, r)) elif filter_by == 'equalize_blue': # equalize val (essentially gray scale level) hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) # blue hue = 120 # slide 120 -> 90 (center of 0-180 range # with mod() roll over) diff = np.mod(hue.astype('float64') - 30, 180) # move this center point to 0 (-90 to +90 # range) and take absolute value # (distance) diff = np.abs(diff - 90) # scale to 0 to 1 (1 being the closest to # our target hue) diff = 1.0 - diff / 90 print('hue:', np.amin(hue), np.amax(hue)) print('sat:', np.amin(sat), np.amax(sat)) print('diff:', np.amin(diff), np.amax(diff)) #print(diff) #g = (256 - (256.0/90.0)*diff).astype('uint8') b = (diff * sat).astype('uint8') g = np.zeros(hue.shape, dtype='uint8') r = np.zeros(hue.shape, dtype='uint8') #g = clahe.apply(g) result = cv2.merge((b, g, r)) print(result.shape, result.dtype) elif filter_by == 'equalize_green': # equalize val (essentially gray scale level) hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) # green hue = 60 # slide 60 -> 90 (center of 0-180 range # with mod() roll over) diff = np.mod(hue.astype('float64') + 30, 180) # move this center point to 0 (-90 to +90 # range) and take absolute value # (distance) diff = np.abs(diff - 90) # scale to 0 to 1 (1 being the closest to # our target hue) diff = 1.0 - diff / 90 print('hue:', np.amin(hue), np.amax(hue)) print('sat:', np.amin(sat), np.amax(sat)) print('diff:', np.amin(diff), np.amax(diff)) #print(diff) b = np.zeros(hue.shape, dtype='uint8') g = (diff * sat).astype('uint8') r = np.zeros(hue.shape, dtype='uint8') #g = clahe.apply(g) result = cv2.merge((b, g, r)) print(result.shape, result.dtype) elif filter_by == 'equalize_red': # equalize val (essentially gray scale level) hsv = cv2.cvtColor(rgb, cv2.COLOR_BGR2HSV) hue, sat, val = cv2.split(hsv) # red hue = 0 # slide 0 -> 90 (center of 0-180 range # with mod() roll over) diff = np.mod(hue.astype('float64') + 90, 180) # move this center point to 0 (-90 to +90 # range) and take absolute value # (distance) diff = np.abs(diff - 90) # scale to 0 to 1 (1 being the closest to # our target hue) diff = 1.0 - diff / 90 print('hue:', np.amin(hue), np.amax(hue)) print('sat:', np.amin(sat), np.amax(sat)) print('diff:', np.amin(diff), np.amax(diff)) b = np.zeros(hue.shape, dtype='uint8') g = np.zeros(hue.shape, dtype='uint8') r = (diff * sat).astype('uint8') result = cv2.merge((b, g, r)) print(result.shape, result.dtype) elif filter_by == 'red/green': # equalize val (essentially gray scale level) max = 4.0 b, g, r = cv2.split(rgb) ratio = r / (g.astype('float64') + 1.0) ratio = np.clip(ratio, 0, max) inv = g / (r.astype('float64') + 1.0) inv = np.clip(inv, 0, max) max_ratio = np.amax(ratio) max_inv = np.amax(inv) print(max_ratio, max_inv) b[:] = 0 g = (inv * (255 / max)).astype('uint8') r = (ratio * (255 / max)).astype('uint8') result = cv2.merge((b, g, r)) print(result.shape, result.dtype) fulltex = Texture(base) fulltex.setCompression(Texture.CMOff) fulltex.setup2dTexture(w, h, Texture.TUnsignedByte, Texture.FRgb) fulltex.setRamImage(result) # fulltex.load(rgb) # for loading a pnm image fulltex.setWrapU(Texture.WM_clamp) fulltex.setWrapV(Texture.WM_clamp) m.setTexture(fulltex, 1) tcache[m.getName()] = [m, fulltex, time.time()] else: print(image_file) fulltex = self.loader.loadTexture(image_file) fulltex.setWrapU(Texture.WM_clamp) fulltex.setWrapV(Texture.WM_clamp) #print('fulltex:', fulltex) m.setTexture(fulltex, 1) tcache[m.getName()] = [m, fulltex, time.time()] cachesize = 10 while len(tcache) > cachesize: oldest_time = time.time() oldest_name = "" for name in tcache: if tcache[name][2] < oldest_time: oldest_time = tcache[name][2] oldest_name = name del tcache[oldest_name]
class TextureHeightmapBase(Heightmap): def __init__(self, name, width, height, height_scale, u_scale, v_scale, median, interpolator): Heightmap.__init__(self, name, width, height, height_scale, u_scale, v_scale, median, interpolator) self.texture = None self.texture_offset = LVector2() self.texture_scale = LVector2(1, 1) self.tex_id = str(width) + ':' + str(height) def reset(self): self.texture = None def get_texture_offset(self, patch): return self.texture_offset def get_texture_scale(self, patch): return self.texture_scale return self.heightmap_ready def set_height(self, x, y, height): pass def get_height(self, x, y): if self.texture_peeker is None: print("No peeker") traceback.print_stack() return 0.0 new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height new_x = min(new_x, self.width - 1) new_y = min(new_y, self.height - 1) height = self.interpolator.get_value(self.texture_peeker, new_x, new_y) return height * self.height_scale # + self.offset def create_heightmap(self, shape, callback=None, cb_args=()): return self.load(shape, callback, cb_args) def load(self, shape, callback, cb_args=()): if self.texture is None: self.texture = Texture() self.texture.set_wrap_u(Texture.WMClamp) self.texture.set_wrap_v(Texture.WMClamp) self.interpolator.configure_texture(self.texture) self.do_load(shape, self.heightmap_ready_cb, (callback, cb_args)) else: if callback is not None: callback(self, *cb_args) def heightmap_ready_cb(self, texture, callback, cb_args): #print("READY", self.patch.str_id()) self.texture_peeker = self.texture.peek() # if self.texture_peeker is None: # print("NOT READY !!!") self.heightmap_ready = True data = self.texture.getRamImage() if sys.version_info[0] < 3: buf = data.getData() np_buffer = numpy.fromstring(buf, dtype=numpy.float32) else: np_buffer = numpy.frombuffer(data, numpy.float32) np_buffer.shape = (self.texture.getYSize(), self.texture.getXSize(), self.texture.getNumComponents()) self.min_height = np_buffer.min() self.max_height = np_buffer.max() self.mean_height = np_buffer.mean() if callback is not None: callback(self, *cb_args) def do_load(self, shape, callback, cb_args): pass
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.disableMouse() self.camera.setPos(0, -26, 4) self.setBackgroundColor(0, 0, 0) # Create a texture into which we can copy the main window. # We set it to RTMTriggeredCopyTexture mode, which tells it that we # want it to copy the window contents into a texture every time we # call self.win.triggerCopy(). self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) self.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Set the initial color to clear the texture to, before rendering it. # This is necessary because we don't clear the texture while rendering, # and otherwise the user might see garbled random data from GPU memory. self.tex.setClearColor((0, 0, 0, 1)) self.tex.clearImage() # Create another 2D camera. Tell it to render before the main camera. self.backcam = self.makeCamera2d(self.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) # Obtain two texture cards. One renders before the dragon, the other # after. self.bcard = self.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = self.win.getTextureCard() self.fcard.reparentTo(self.render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0, 0, 0, 1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(self.render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(self.render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if self.win.getGsg().getCopyTextureInverted(): print("Copy texture is inverted.") self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", fg=(1, 1, 1, 1), parent=base.a2dBottomCenter, pos=(0, 0.1), scale=.08) instr0 = addInstructions(0.06, "Press ESC to exit") instr1 = addInstructions(0.12, "Press 1: Ghost effect") instr2 = addInstructions(0.18, "Press 2: PaintBrush effect") instr3 = addInstructions(0.24, "Press 3: Double Vision effect") instr4 = addInstructions(0.30, "Press 4: Wings of Blue effect") instr5 = addInstructions(0.36, "Press 5: Whirlpool effect") # Enable the key events self.accept("escape", sys.exit, [0]) self.accept("1", self.chooseEffectGhost) self.accept("2", self.chooseEffectPaintBrush) self.accept("3", self.chooseEffectDoubleVision) self.accept("4", self.chooseEffectWingsOfBlue) self.accept("5", self.chooseEffectWhirlpool)
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) # Load the environment model. self.setup_environment() #self.scene = self.loader.loadModel("models/environment") # Reparent the model to render. #self.scene.reparentTo(self.render) # Apply scale and position transforms on the model. #self.scene.setScale(0.25, 0.25, 0.25) #self.scene.setPos(-8, 42, 0) # Needed for camera image self.dr = self.camNode.getDisplayRegion(0) # Needed for camera depth image winprops = WindowProperties.size(self.win.getXSize(), self.win.getYSize()) fbprops = FrameBufferProperties() fbprops.setDepthBits(1) self.depthBuffer = self.graphicsEngine.makeOutput( self.pipe, "depth buffer", -2, fbprops, winprops, GraphicsPipe.BFRefuseWindow, self.win.getGsg(), self.win) self.depthTex = Texture() self.depthTex.setFormat(Texture.FDepthComponent) self.depthBuffer.addRenderTexture(self.depthTex, GraphicsOutput.RTMCopyRam, GraphicsOutput.RTPDepth) lens = self.cam.node().getLens() lens.setFov(90.0, 90.0) # the near and far clipping distances can be changed if desired # lens.setNear(5.0) # lens.setFar(500.0) self.depthCam = self.makeCamera(self.depthBuffer, lens=lens, scene=self.render) self.depthCam.reparentTo(self.cam) # TODO: Scene is rendered twice: once for rgb and once for depth image. # How can both images be obtained in one rendering pass? self.render.setAntialias(AntialiasAttrib.MAuto) def setup_environment(self): # encapsulate some stuff # set up ambient lighting self.alight = AmbientLight('alight') self.alight.setColor(VBase4(0.1, 0.1, 0.1, 1)) self.alnp = self.render.attachNewNode(self.alight) self.render.setLight(self.alnp) # set up a point light self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1)) self.plnp = self.render.attachNewNode(self.plight) self.plnp.setPos(0, 0, 100) self.render.setLight(self.plnp) # set up terrain model self.terr_material = Material() self.terr_material.setShininess(1.0) self.terr_material.setAmbient(VBase4(0, 0, 0, 0)) self.terr_material.setDiffuse(VBase4(1, 1, 1, 1)) self.terr_material.setEmission(VBase4(0, 0, 0, 0)) self.terr_material.setSpecular(VBase4(0, 0, 0, 0)) # general scaling self.trrHorzSc = 4.0 self.trrVertSc = 4.0 # was 4.0 # Create sky #terrctr = self.trrHorzSc*65.0 #self.setup_skybox(terrctr,800.0,2.0,0.3) self.skysphere = self.loader.loadModel("sky-forest/SkySphere.bam") self.skysphere.setBin('background', 1) self.skysphere.setDepthWrite(0) self.skysphere.reparentTo(self.render) # Load some textures self.grsTxtSc = 5 self.numTreeTexts = 7 # ground texture self.txtGrass = self.loader.loadTexture('tex/ground005.png') self.txtGrass.setWrapU(Texture.WM_mirror) self.txtGrass.setWrapV(Texture.WM_mirror) self.txtGrass.setMagfilter(Texture.FTLinear) self.txtGrass.setMinfilter(Texture.FTLinearMipmapLinear) # set up terrain texture stages self.TS1 = TextureStage('terrtext') self.TS1.setSort(0) self.TS1.setMode(TextureStage.MReplace) # Set up the GeoMipTerrain self.terrain = GeoMipTerrain("myDynamicTerrain") img = PNMImage(Filename('tex/bowl_height_map.png')) self.terrain.setHeightfield(img) self.terrain.setBruteforce(0) self.terrain.setAutoFlatten(GeoMipTerrain.AFMMedium) # Set terrain properties self.terrain.setBlockSize(32) self.terrain.setNear(50) self.terrain.setFar(500) self.terrain.setFocalPoint(self.camera) # Store the root NodePath for convenience self.root = self.terrain.getRoot() self.root.clearTexture() self.root.setTwoSided(0) self.root.setCollideMask(BitMask32.bit(0)) self.root.setSz(self.trrVertSc) self.root.setSx(self.trrHorzSc) self.root.setSy(self.trrHorzSc) self.root.setMaterial(self.terr_material) self.root.setTexture(self.TS1, self.txtGrass) self.root.setTexScale(self.TS1, self.grsTxtSc, self.grsTxtSc) offset = 0.5 * img.getXSize() * self.trrHorzSc - 0.5 self.root.setPos(-offset, -offset, 0) self.terrain.generate() self.root.reparentTo(self.render) # load tree billboards self.txtTreeBillBoards = [] for a in range(self.numTreeTexts): fstr = 'trees/tree' + '%03d' % (a + 991) self.txtTreeBillBoards.append( \ self.loader.loadTexture(fstr + '-color.png', fstr + '-opacity.png')) self.txtTreeBillBoards[a].setMinfilter( Texture.FTLinearMipmapLinear) #self.placePlantOnTerrain('trees',300,0,20,20,self.trrHorzSc,self.trrVertSc, \ # self.numTreeTexts,self.txtTreeBillBoards,'scene-def/trees.txt') self.setup_house() self.setup_vehicle() self.taskMgr.add(self.skysphereTask, "SkySphere Task") def setup_house(self): # place farmhouse on terrain self.house = ModelNode('house1') self.loadModelOntoTerrain(self.render, self.terrain, self.house, 43.0, 0.275, 0.0, 0.0, self.trrHorzSc, self.trrVertSc, 'models/FarmHouse', Vec3(0, 0, 0), Point3(-12.0567, -29.1724, 0.0837742), Point3(12.2229, 21.1915, 21.3668)) def setup_vehicle(self): # place HMMWV on terrain self.hmmwv = ModelNode('hmmwv1') self.loadModelOntoTerrain(self.render, self.terrain, self.hmmwv, 33.0, 1.0, 20.0, 24.0, self.trrHorzSc, self.trrVertSc, 'models/hmmwv', Vec3(0, -90, 0), Point3(-1.21273, -2.49153, -1.10753), Point3(1.21273, 2.49153, 1.10753)) def setup_skybox(self, terrctr=645.0, boxsz=1000.0, aspect=1.0, uplift=0.0): vsz = boxsz / aspect self.bckgtx = [] self.bckgtx.append(self.loader.loadTexture('sky/Back2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Right2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Front2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Left2.png')) self.bckgtx.append(self.loader.loadTexture('sky/Up.png')) for a in range(4): self.bckg = CardMaker('bkcard') lr = Point3(0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz) ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz) ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0.5 * vsz) ll = Point3(-0.5 * boxsz, 0.5 * boxsz, -0.5 * vsz) self.bckg.setFrame(ll, lr, ur, ul) self.bckg.setHasNormals(0) self.bckg.setHasUvs(1) #self.bckg.setUvRange(self.bckgtx[a]) bkcrd = self.render.attachNewNode(self.bckg.generate()) bkcrd.setTexture(self.bckgtx[a]) self.bckgtx[a].setWrapU(Texture.WMClamp) self.bckgtx[a].setWrapV(Texture.WMClamp) bkcrd.setLightOff() bkcrd.setFogOff() bkcrd.setHpr(90.0 * a, 0, 0) cz = 0.5 * boxsz * uplift #print 'set card at:', terrctr,terrctr,cz, ' with points: ', lr,ur,ul,ll bkcrd.setPos(terrctr, terrctr, cz) self.top = CardMaker('bkcard') lr = Point3(0.5 * boxsz, -0.5 * boxsz, 0) ur = Point3(0.5 * boxsz, 0.5 * boxsz, 0) ul = Point3(-0.5 * boxsz, 0.5 * boxsz, 0) ll = Point3(-0.5 * boxsz, -0.5 * boxsz, 0) self.top.setFrame(ll, lr, ur, ul) self.top.setHasNormals(0) self.top.setHasUvs(1) #self.top.setUvRange(self.bckgtx[4]) bkcrd = self.render.attachNewNode(self.bckg.generate()) bkcrd.setTexture(self.bckgtx[4]) self.bckgtx[4].setWrapU(Texture.WMClamp) self.bckgtx[4].setWrapV(Texture.WMClamp) bkcrd.setLightOff() bkcrd.setFogOff() bkcrd.setHpr(0, 90, 90) bkcrd.setPos(terrctr, terrctr, 0.5 * vsz + 0.5 * boxsz * uplift) def placePlantOnTerrain(self, itemStr, itemCnt, Mode, typItemWidth, typItemHeight, trrHorzSc, trrVertSc, numTxtTypes, txtList, planFileName): # Billboarding plants crd = CardMaker('mycard') crd.setColor(0.5, 0.5, 0.5, 1) ll = Point3(-0.5 * typItemWidth, 0, 0) lr = Point3(0.5 * typItemWidth, 0, 0) ur = Point3(0.5 * typItemWidth, 0, typItemHeight) ul = Point3(-0.5 * typItemWidth, 0, typItemHeight) crd.setFrame(ll, lr, ur, ul) crd.setHasNormals(False) crd.setHasUvs(True) # generate/save/load locations try: plan_data_fp = open(planFileName, 'r') item_list = [] for line in plan_data_fp: toks = line.split(',') px = float(toks[0].strip(' ')) py = float(toks[1].strip(' ')) ang = float(toks[2].strip(' ')) dht = float(toks[3].strip(' ')) scl = float(toks[4].strip(' ')) idx = int(toks[5].strip(' ')) item_list.append((px, py, ang, dht, scl, idx)) plan_data_fp.close() print 'loaded ', itemStr, ' data file of size:', len(item_list) except IOError: # generate list and try to save item_list = [] for a in range(itemCnt): px = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) py = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) ang = 180 * random.random() dht = 0.0 scl = 0.75 + 0.25 * (random.random() + random.random()) idx = random.randrange(0, numTxtTypes) item_list.append([px, py, ang, dht, scl, idx]) try: plan_data_fp = open(planFileName, 'w') for c in item_list: print >> plan_data_fp, c[0], ',', c[1], ',', c[2], ',', c[ 3], ',', c[4], ',', c[5] plan_data_fp.close() print 'saved ', itemStr, ' data of size: ', len(item_list) except IOError: print 'unable to store ', itemStr, ' data of size: ', len( item_list) # define each plant for c in item_list: px = c[0] py = c[1] ang = c[2] dht = c[3] scl = c[4] idx = c[5] if idx >= numTxtTypes: idx = 0 if Mode > 0: for b in range(Mode): crdNP = self.render.attachNewNode(crd.generate()) crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) crdNP.setTwoSided(True) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc + dht) crdNP.setHpr(ang + (180 / Mode) * b, 0, 0) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() else: # set up item as defined crd.setUvRange(txtList[idx]) crdNP = self.render.attachNewNode(crd.generate()) crdNP.setBillboardAxis() crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() def loadModelOntoTerrain(self, render_node, terr_obj, model_obj, hdg, scl, xctr, yctr, terr_horz_sc, terr_vert_sc, model_path, rotA, minP, maxP): # load model onto terrain hdg_rads = hdg * math.pi / 180.0 model_obj = self.loader.loadModel(model_path) rotAll = rotA rotAll.setX(rotAll.getX() + hdg) model_obj.setHpr(rotA) model_obj.setLightOff() # if model changes, these will have to be recomputed # minP = Point3(0,0,0) # maxP = Point3(0,0,0) # model_obj.calcTightBounds(minP,maxP) print minP print maxP htl = [] maxzofs = -1000.0 for xi in [minP[0], maxP[0]]: for yi in [minP[1], maxP[1]]: tx = xctr + scl * xi * math.cos(hdg_rads) ty = yctr + scl * yi * math.sin(hdg_rads) tht = self.terrain.getElevation(tx / terr_horz_sc, ty / terr_horz_sc) print 'tx=', tx, ', ty=', ty, ', tht=', tht htl.append(tht * terr_vert_sc - minP.getZ()) for hi in htl: if hi > maxzofs: maxzofs = hi print maxzofs model_obj.setPos(xctr, yctr, maxzofs) model_obj.setHpr(rotAll) model_obj.setScale(scl) model_obj.reparentTo(render_node) return maxzofs, minP, maxP def get_camera_image(self, requested_format=None): """ Returns the camera's image, which is of type uint8 and has values between 0 and 255. The 'requested_format' argument should specify in which order the components of the image must be. For example, valid format strings are "RGBA" and "BGRA". By default, Panda's internal format "BGRA" is used, in which case no data is copied over. """ tex = self.dr.getScreenshot() if requested_format is None: data = tex.getRamImage() else: data = tex.getRamImageAs(requested_format) image = np.frombuffer( data.get_data(), np.uint8) # use data.get_data() instead of data in python 2 image.shape = (tex.getYSize(), tex.getXSize(), tex.getNumComponents()) image = np.flipud(image) return image def get_camera_depth_image(self): """ Returns the camera's depth image, which is of type float32 and has values between 0.0 and 1.0. """ data = self.depthTex.getRamImage() depth_image = np.frombuffer(data.get_data(), np.float32) depth_image.shape = (self.depthTex.getYSize(), self.depthTex.getXSize(), self.depthTex.getNumComponents()) depth_image = np.flipud(depth_image) ''' Surface position can be inferred by calculating backward from the depth buffer. Each pixel on the screen represents a ray from the camera into the scene, and the depth value in the pixel indicates a distance along the ray. Because of this, it is not actually necessary to store surface position explicitly - it is only necessary to store depth values. Of course, OpenGL does that for free. So the framebuffer now needs to store surface normal, diffuse color, and depth value (to infer surface position). In practice, most ordinary framebuffers can only store color and depth - they don't have any place to store a third value. So we need to use a special offscreen buffer with an "auxiliary" bitplane. The auxiliary bitplane stores the surface normal. So then, there's the final postprocessing pass. This involves combining the diffuse color texture, the surface normal texture, the depth texture, and the light parameters into a final rendered output. The light parameters are passed into the postprocessing shader as constants, not as textures. If there are a lot of lights, things get interesting. You use one postprocessing pass per light. Each pass only needs to scan those framebuffer pixels that are actually in range of the light in question. To traverse only the pixels that are affected by the light, just render the illuminated area's convex bounding volume. The shader to store the diffuse color and surface normal is trivial. But the final postprocessing shader is a little complicated. What makes it tricky is that it needs to regenerate the original surface position from the screen position and depth value. The math for that deserves some explanation. We need to take a clip-space coordinate and depth-buffer value (ClipX,ClipY,ClipZ,ClipW) and unproject it back to a view-space (ViewX,ViewY,ViewZ) coordinate. Lighting is then done in view-space. Okay, so here's the math. Panda uses the projection matrix to transform view-space into clip-space. But in practice, the projection matrix for a perspective camera always contains four nonzero constants, and they're always in the same place: -- here are the non-zero elements of the projection matrix -- A 0 0 0 0 0 B 1 0 C 0 0 0 0 D 0 -- precompute these from above projection matrix -- ''' proj = self.cam.node().getLens().getProjectionMat() proj_x = 0.5 * proj.getCell(3, 2) / proj.getCell(0, 0) proj_y = 0.5 * proj.getCell(3, 2) proj_z = 0.5 * proj.getCell(3, 2) / proj.getCell(2, 1) proj_w = -0.5 - 0.5 * proj.getCell(1, 2) ''' -- now for each pixel compute viewpoint coordinates -- viewx = (screenx * projx) / (depth + projw) viewy = (1 * projy) / (depth + projw) viewz = (screeny * projz) / (depth + projw) ''' grid = np.mgrid[0:depth_image.shape[0], 0:depth_image.shape[1]] ygrid = np.float32(np.squeeze( grid[0, :, :])) / float(depth_image.shape[0] - 1) ygrid -= 0.5 xgrid = np.float32(np.squeeze( grid[1, :, :])) / float(depth_image.shape[1] - 1) xgrid -= 0.5 xview = 2.0 * xgrid * proj_x zview = 2.0 * ygrid * proj_z denom = np.squeeze(depth_image) + proj_w xview = xview / denom yview = proj_y / denom zview = zview / denom sqrng = xview**2 + yview**2 + zview**2 range_image = np.sqrt(sqrng) range_image_1 = np.expand_dims(range_image, axis=2) return depth_image, range_image_1 def compute_sample_pattern(self, limg_shape, res_factor): # assume velocity is XYZ and we are looking +X up and towards -Z pattern = [] lens = self.cam.node().getLens() sx = self.win.getXSize() sy = self.win.getYSize() ifov_vert = 2.0 * math.tan( 0.5 * math.radians(lens.getVfov())) / float(sy - 1) ifov_horz = 2.0 * math.tan( 0.5 * math.radians(lens.getHfov())) / float(sx - 1) #ifov_vert = lens.getVfov() / float(sy-1) #ifov_horz = lens.getHfov() / float(sy-1) for ldr_row in range(limg_shape[0]): theta = -10.0 - 41.33 * ( float(ldr_row) / float(limg_shape[0] - 1) - 0.5) for ldr_col in range(limg_shape[1]): psi = 60.0 * (float(ldr_col) / float(limg_shape[1] - 1) - 0.5) cpsi = math.cos(math.radians(psi)) vert_ang = theta / cpsi img_row_flt = (0.5 * float(sy - 1) - (math.tan(math.radians(vert_ang)) / ifov_vert)) #img_row_flt = 0.5*(sy-1) - (vert_ang / ifov_vert) if img_row_flt < 0: print('img_row_flt=%f' % img_row_flt) img_row_flt = 0.0 if img_row_flt >= sy: print('img_row_flt=%f' % img_row_flt) img_row_flt = float(sy - 1) img_col_flt = (0.5 * float(sx - 1) + (math.tan(math.radians(psi)) / ifov_horz)) #img_col_flt = 0.5*(sx-1) + (psi / ifov_horz) if img_col_flt < 0: print('img_col_flt=%f' % img_col_flt) img_col_flt = 0.0 if img_col_flt >= sx: print('img_col_flt=%f' % img_col_flt) img_col_flt = float(sx - 1) pattern.append((ldr_row, ldr_col, img_row_flt, img_col_flt)) return pattern def find_sorted_ladar_returns(self, rangearr, intensarr, ks_m): my_range = rangearr.copy() my_inten = intensarr.copy() ''' pixels data is organized by: [0] starting range of this return [1] ending range of this return [2] peak range of this return [3] total intensity of this return ''' int_mult = len(my_inten) pixels = map( list, zip(my_range.tolist(), my_range.tolist(), my_range.tolist(), my_inten.tolist())) spix = sorted(pixels, key=lambda x: x[0]) done = False while not done: mxpi = len(spix) if mxpi > 2: mindel = 1e20 mnidx = None for pidx in range(mxpi - 1): rdel = spix[pidx + 1][0] - spix[pidx][1] # must be within ks_m meters in range to merge if (rdel < ks_m) and (rdel < mindel): mindel = rdel mnidx = pidx # merge best two returns if mnidx is not None: # new range span for testing against neighbors spix[mnidx][1] = spix[mnidx + 1][1] # new peak range is range of max contributor if spix[mnidx + 1][3] > spix[mnidx][3]: spix[mnidx][2] = spix[mnidx + 1][2] # intensity of return is sum of contributors spix[mnidx][3] += spix[mnidx + 1][3] # remove one of the two merged del spix[mnidx + 1] else: done = True else: done = True # now eliminate all but max and last returns max_idx = None max_val = 0.0 for ci, pix in enumerate(spix): if pix[3] > max_val: max_val = pix[3] / int_mult max_idx = ci # if they are the same, return only one if spix[-1][3] >= spix[max_idx][3]: return [spix[-1]] else: return [spix[max_idx], spix[-1]] def sample_range_image(self, rng_img, int_img, limg_shape, vel_cam, pps, ldr_err, pattern): # depth image is set up as 512 x 512 and is 62.5 degrees vertical FOV # the center row is vertical, but we want to sample from the # region corresponding to HDL-32 FOV: from +10 to -30 degrees detailed_sensor_model = False fwd_vel = vel_cam[1] beam_div = 0.002 lens = self.cam.node().getLens() #sx = self.win.getXSize() sy = self.win.getYSize() ifov_vert = 2.0 * math.tan( 0.5 * math.radians(lens.getVfov())) / float(sy - 1) #ifov_horz = 2.0*math.tan(0.5*math.radians(lens.getHfov()))/float(sx-1) #ifov = math.radians(self.cam.node().getLens().getVfov() / self.win.getYSize()) sigma = beam_div / ifov_vert hs = int(2.0 * sigma + 1.0) gprof = gauss_kern(sigma, hs, normalize=False) rimg = np.zeros(limg_shape, dtype=np.float32) iimg = np.zeros(limg_shape, dtype=np.float32) margin = 10.0 for pidx, relation in enumerate(pattern): # get the usual scan pattern sample ldr_row, ldr_col, img_row_flt, img_col_flt = relation if ((img_row_flt > -margin) and (img_col_flt > -margin) and (img_row_flt < rng_img.shape[0] + margin) and (img_col_flt < rng_img.shape[1] + margin)): # within reasonable distance from image limits img_row = int(round(img_row_flt)) img_col = int(round(img_col_flt)) # motion compensation trng = np.float32(rng_img[img_row, img_col]) if trng > 0.0: # TODO: change this back to False done = True ic = 0 while not done: old_trng = trng del_row = pidx * fwd_vel / (ifov_vert * trng * pps) if (abs(del_row) > 1e-1) and (ic < 10): img_row_f = img_row_flt + del_row img_row = int(round(img_row_f)) trng = np.float32(rng_img[img_row, img_col]) ic += 1 if abs(trng - old_trng) < 0.5: done = True else: done = True # simple sensor processing: just sample from large images rimg[ldr_row, ldr_col] = np.float32(rng_img[img_row, img_col]) iimg[ldr_row, ldr_col] = np.float32(int_img[img_row, img_col]) if detailed_sensor_model: # detailed model subsamples whole beam width gpatch = copy_patch_centered((img_row, img_col), hs, int_img, 0.0) gpatch = np.float32(gpatch) gpatch *= gprof rpatch = copy_patch_centered((img_row, img_col), hs, rng_img, 0.0) rpatch = np.squeeze(rpatch) valid = rpatch > 1e-3 if np.count_nonzero(valid) > 0: rpatch_ts = rpatch[valid] gpatch_ts = gpatch[valid] returns = self.find_sorted_ladar_returns( rpatch_ts, gpatch_ts, 2.5) # for now we just take first return rimg[ldr_row, ldr_col] = returns[0][2] iimg[ldr_row, ldr_col] = returns[0][3] else: rimg[ldr_row, ldr_col] = 0.0 iimg[ldr_row, ldr_col] = np.float32(int_img[img_row, img_col]) rimg += ldr_err * np.random.standard_normal(rimg.shape) return rimg, iimg def skysphereTask(self, task): if self.base is not None: self.skysphere.setPos(self.base.camera, 0, 0, 0) self.terrain.generate() return task.cont
def renderSceneInto(self, depthtex=None, colortex=None, auxtex=None, auxbits=0, textures=None, rgbabits=(1, 1, 1, 1), floatcolor=False, srgb=False, depthbits=1, floatdepth=False, multisamples=0): """ Causes the scene to be rendered into the supplied textures instead of into the original window. Puts a fullscreen quad into the original window to show the render-to-texture results. Returns the quad. Normally, the caller would then apply a shader to the quad. To elaborate on how this all works: * An offscreen buffer is created. It is set up to mimic the original display region - it is the same size, uses the same clear colors, and contains a DisplayRegion that uses the original camera. * A fullscreen quad and an orthographic camera to render that quad are both created. The original camera is removed from the original window, and in its place, the orthographic quad-camera is installed. * The fullscreen quad is textured with the data from the offscreen buffer. A shader is applied that tints the results pink. * Automatic shader generation NOT enabled. If you have a filter that depends on a render target from the auto-shader, you either need to set an auto-shader attrib on the main camera or scene, or, you need to provide these outputs in your own shader. * All clears are disabled on the original display region. If the display region fills the whole window, then clears are disabled on the original window as well. It is assumed that rendering the full-screen quad eliminates the need to do clears. Hence, the original window which used to contain the actual scene, now contains a pink-tinted quad with a texture of the scene. It is assumed that the user will replace the shader on the quad with a more interesting filter. """ if (textures): colortex = textures.get("color", None) depthtex = textures.get("depth", None) auxtex = textures.get("aux", None) auxtex0 = textures.get("aux0", auxtex) auxtex1 = textures.get("aux1", None) else: auxtex0 = auxtex auxtex1 = None if (colortex == None): colortex = Texture("filter-base-color") colortex.setWrapU(Texture.WMClamp) colortex.setWrapV(Texture.WMClamp) texgroup = (depthtex, colortex, auxtex0, auxtex1) # Choose the size of the offscreen buffer. (winx, winy) = self.getScaledSize(1, 1, 1) buffer = self.createBuffer("filter-base", winx, winy, texgroup, rgbabits=rgbabits, floatcolor=floatcolor, srgb=srgb, depthbits=depthbits, floatdepth=floatdepth, multisamples=multisamples) if (buffer == None): return None cm = CardMaker("filter-base-quad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setTexture(colortex) quad.setColor(1, 0.5, 0.5, 1) cs = NodePath("dummy") cs.setState(self.camstate) # Do we really need to turn on the Shader Generator? #cs.setShaderAuto() if (auxbits): cs.setAttrib(AuxBitplaneAttrib.make(auxbits)) self.camera.node().setInitialState(cs.getState()) quadcamnode = Camera("filter-quad-cam") lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) self.region.setCamera(quadcam) self.setStackedClears(buffer, self.rclears, self.wclears) if (auxtex0): buffer.setClearActive(GraphicsOutput.RTPAuxRgba0, 1) buffer.setClearValue(GraphicsOutput.RTPAuxRgba0, (0.5, 0.5, 1.0, 0.0)) if (auxtex1): buffer.setClearActive(GraphicsOutput.RTPAuxRgba1, 1) self.region.disableClears() if (self.isFullscreen()): self.win.disableClears() dr = buffer.makeDisplayRegion() dr.disableClears() dr.setCamera(self.camera) dr.setActive(1) self.buffers.append(buffer) self.sizes.append((1, 1, 1)) return quad
def initPostProcessing(self): manager = FilterManager(base.win, base.cam) tex = Texture() quad = manager.renderSceneInto(colortex=tex) quad.setShader(Shader.load("shaders/post_processing.sha")) quad.setShaderInput("tex", tex)
def __init__(self, texture_array, stim_angles=(0, 0), mask_angle=0, position=(0, 0), velocity=0, band_radius=3, window_size=512, texture_size=512, bgcolor=(0, 0, 0, 1)): super().__init__() self.mask_position_ndc = position self.mask_position_uv = (ndc2uv(self.mask_position_ndc[0]), ndc2uv(self.mask_position_ndc[1])) self.mask_scale = np.sqrt(8) self.texture_array = texture_array self.texture_dtype = type(self.texture_array.flat[0]) self.ndims = self.texture_array.ndim self.left_texture_angle = stim_angles[0] self.right_texture_angle = stim_angles[1] self.velocity = velocity self.mask_angle = mask_angle #this will change fairly frequently #Set window title and size self.window_properties = WindowProperties() self.window_properties.setSize(window_size, window_size) self.window_properties.setTitle("BinocularStatic") ShowBaseGlobal.base.win.requestProperties( self.window_properties) #base is a panda3d global #CREATE MASKS (right mask for left stim, and vice-versa) self.right_mask = 255 * np.ones( (texture_size, texture_size), dtype=np.uint8) self.right_mask[:, texture_size // 2 - band_radius:] = 0 #CREATE TEXTURE STAGES #Grating texture self.grating_texture = Texture("Grating") #T_unsigned_byte self.grating_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.grating_texture.setRamImage(self.texture_array) self.left_texture_stage = TextureStage('grating') #Mask self.right_mask_texture = Texture("right_mask") self.right_mask_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.right_mask_texture.setRamImage(self.right_mask) self.right_mask_stage = TextureStage('right_mask') #Multiply the texture stages together self.right_mask_stage.setCombineRgb(TextureStage.CMModulate, TextureStage.CSTexture, TextureStage.COSrcColor, TextureStage.CSPrevious, TextureStage.COSrcColor) #CREATE CARDS/SCENEGRAPH cm = CardMaker('stimcard') cm.setFrameFullscreenQuad() self.left_card = self.aspect2d.attachNewNode(cm.generate()) #SET TEXTURE STAGES self.left_card.setTexture(self.left_texture_stage, self.grating_texture) self.left_card.setTexture(self.right_mask_stage, self.right_mask_texture) #Add texture move procedure to the task manager, if needed if self.velocity != 0: self.taskMgr.add(self.update_trs, "moveTextureTask") self.title = OnscreenText("x", style=1, fg=(1, 1, 1, 1), bg=(0, 0, 0, .8), pos=self.mask_position_ndc, scale=0.05)
class ShaderHeightmap(Heightmap): tex_generators = {} def __init__(self, name, width, height, height_scale, median, noise, offset, scale, coord = TexCoord.Cylindrical): Heightmap.__init__(self, name, width, height, height_scale, 1.0, 1.0, median) self.noise = noise self.offset = offset self.scale = scale self.coord = coord self.shader = None self.texture = None self.texture_offset = LVector2() self.texture_scale = LVector2(1, 1) self.tex_id = str(width) + ':' + str(height) def reset(self): self.texture = None def set_noise(self, noise): self.noise = noise self.shader = None self.texture = None def set_offset(self, offset): self.offset = offset if self.shader is not None: self.shader.offset = offset self.texture = None def set_scale(self, scale): self.scale = scale if self.shader is not None: self.shader.scale = scale self.texture = None def get_heightmap(self, patch): return self def get_texture_offset(self, patch): return self.texture_offset def get_texture_scale(self, patch): return self.texture_scale def get_height(self, x, y): if self.texture_peeker is None: print("No peeker") traceback.print_stack() return 0.0 try: color = LColor() #pos = LVector2(x * self.texture_scale[0], ((self.height - 1) - y) * self.texture_scale[1]) + self.texture_offset new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width #new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height #new_y = ((self.height - 1) - new_y) new_y = ((self.height - 1) - y) * self.texture_scale[1] + self.texture_offset[1] * self.height #print(x, y, int(new_x), int(new_y), self.texture_scale, self.texture_offset) self.texture_peeker.fetch_pixel(color, min(int(new_x), self.width - 1), min(int(new_y), self.height - 1)) #self.texture_peeker.fetch_pixel(color, x, y) if settings.encode_float: height = color[0] + color[1] / 255.0 + color[2] / 65025.0 + color[3] / 16581375.0 else: height = color[0] except AssertionError as e: #traceback.print_stack() #print(e) print(x, y) print(int(new_x), int(new_y)) print(((self.height - 1) - y), self.texture_scale[1], ((self.height - 1) - y) * self.texture_scale[1], self.texture_offset[1] * self.height) height = 0.0 #print(height, self.parent.height_scale) return height * self.height_scale# + self.offset def heightmap_ready_cb(self, texture, callback, cb_args): self.heightmap_ready = True #print("READY") self.texture_peeker = self.texture.peek() # if self.texture_peeker is None: # print("NOT READY !!!") if callback is not None: callback(self, *cb_args) def create_heightmap(self, patch, callback=None, cb_args=()): if self.texture is None: self.texture = Texture() self.texture.set_wrap_u(Texture.WMClamp) self.texture.set_wrap_v(Texture.WMClamp) self.texture.setMinfilter(Texture.FT_linear) self.texture.setMagfilter(Texture.FT_linear) self._make_heightmap(callback, cb_args) else: if callback is not None: callback(self, *cb_args) def _make_heightmap(self, callback, cb_args): if not self.tex_id in ShaderHeightmap.tex_generators: ShaderHeightmap.tex_generators[self.tex_id] = TexGenerator() if settings.encode_float: texture_format = Texture.F_rgba else: texture_format = Texture.F_r32 ShaderHeightmap.tex_generators[self.tex_id].make_buffer(self.width, self.height, texture_format) tex_generator = ShaderHeightmap.tex_generators[self.tex_id] if self.shader is None: self.shader = NoiseShader(noise_source=self.noise, noise_target=FloatTarget(), coord = self.coord, offset = self.offset, scale = self.scale) self.shader.global_frequency = self.global_frequency self.shader.create_and_register_shader(None, None) tex_generator.generate(self.shader, 0, self.texture, self.heightmap_ready_cb, (callback, cb_args))
class BinocularDrift(ShowBase): """ Show binocular drifting textures forever. Takes in texture array and other parameters, and shows texture drifting indefinitely. Texture array can be grayscale or rgb, uint8 or uint16. Usage: BinocularDrift(texture_array, stim_angles = (0, 0), mask_angle = 0, position = (0,0), velocity = 0.1, band_radius = 3, window_size = 512, texture_size = 512, bgcolor = (0,0,0,1)) Note(s): angles are (left_texture_angle, right_texture_angle): > is cw, < 0 cc2 Velocity is in NDC, so 1.0 is the entire window width (i.e., super-fast). Make texture_size a power of 2: this makes the GPU happier. position is x,y in NDC (from [-1 1]), so (.5, .5) will be in top right quadrant of window. band_radius is just the half-width of the band in the middle. It can be 0. The texture array can be 2d (gray) or NxNx3 (rgb) """ def __init__(self, texture_array, stim_angles=(0, 0), mask_angle=0, position=(0, 0), velocity=0, band_radius=3, window_size=512, texture_size=512, bgcolor=(0, 0, 0, 1)): super().__init__() self.mask_position_ndc = position self.mask_position_uv = (ndc2uv(self.mask_position_ndc[0]), ndc2uv(self.mask_position_ndc[1])) self.mask_scale = np.sqrt(8) self.texture_array = texture_array self.texture_dtype = type(self.texture_array.flat[0]) self.ndims = self.texture_array.ndim self.left_texture_angle = stim_angles[0] self.right_texture_angle = stim_angles[1] self.velocity = velocity self.mask_angle = mask_angle #this will change fairly frequently #Set window title and size self.window_properties = WindowProperties() self.window_properties.setSize(window_size, window_size) self.window_properties.setTitle("BinocularStatic") ShowBaseGlobal.base.win.requestProperties( self.window_properties) #base is a panda3d global #CREATE MASKS (right mask for left stim, and vice-versa) self.right_mask = 255 * np.ones( (texture_size, texture_size), dtype=np.uint8) self.right_mask[:, texture_size // 2 - band_radius:] = 0 #CREATE TEXTURE STAGES #Grating texture self.grating_texture = Texture("Grating") #T_unsigned_byte self.grating_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.grating_texture.setRamImage(self.texture_array) self.left_texture_stage = TextureStage('grating') #Mask self.right_mask_texture = Texture("right_mask") self.right_mask_texture.setup2dTexture(texture_size, texture_size, Texture.T_unsigned_byte, Texture.F_luminance) self.right_mask_texture.setRamImage(self.right_mask) self.right_mask_stage = TextureStage('right_mask') #Multiply the texture stages together self.right_mask_stage.setCombineRgb(TextureStage.CMModulate, TextureStage.CSTexture, TextureStage.COSrcColor, TextureStage.CSPrevious, TextureStage.COSrcColor) #CREATE CARDS/SCENEGRAPH cm = CardMaker('stimcard') cm.setFrameFullscreenQuad() self.left_card = self.aspect2d.attachNewNode(cm.generate()) #SET TEXTURE STAGES self.left_card.setTexture(self.left_texture_stage, self.grating_texture) self.left_card.setTexture(self.right_mask_stage, self.right_mask_texture) #Add texture move procedure to the task manager, if needed if self.velocity != 0: self.taskMgr.add(self.update_trs, "moveTextureTask") self.title = OnscreenText("x", style=1, fg=(1, 1, 1, 1), bg=(0, 0, 0, .8), pos=self.mask_position_ndc, scale=0.05) #Procedure to move the camera def update_trs(self, task): #Move texture in whatever direction new_texture_position = -task.time * self.velocity #negative b/c texture stage self.left_card.setTexPos(self.left_texture_stage, new_texture_position, 0, 0) #Transform the mask so we only see some of the texture self.left_card.setTexTransform(self.right_mask_stage, self.trs_transform(task.time)) return task.cont def trs_transform(self, elapsed_time): """ trs = translate rotate scale: transform for mask stage """ pos = 0.5 + self.mask_position_uv[0], 0.5 + self.mask_position_uv[1] center_shift = TransformState.make_pos2d((-pos[0], -pos[1])) scale = TransformState.make_scale2d(1 / self.mask_scale) rotate = TransformState.make_rotate2d(np.mod(elapsed_time * 40, 360)) translate = TransformState.make_pos2d((0.5, 0.5)) return translate.compose(rotate.compose(scale.compose(center_shift)))
def generateNode(self, name, DB, parentNode): log.debug("Setting up " + name) bodyEntity = sandbox.createEntity() component = CelestialComponent() if DB['type'] == 'solid': body = Body(name) elif DB['type'] == 'moon': body = Body(name) body.kind = "moon" elif DB['type'] == 'star': body = Star(name) body.absoluteM = DB['absolute magnitude'] body.spectral = DB['spectral'] elif DB['type'] == 'barycenter': body = BaryCenter(name) component.kind = TYPES[DB['type']] if DB['type'] != "barycenter": component.mass = DB['mass'] body.radius = DB['radius'] body.rotation = DB['rotation'] if 'orbit' in DB: component.orbit = DB['orbit'] body.period = DB['period'] #body.setPos(self.get2DBodyPosition(component, universals.day)) component.truePos = self.get2DBodyPosition(component, universals.day) if name == "Earth": #universals.spawn = component.truePos + LPoint3d(0, 6671, 0) universals.spawn = component.truePos + LPoint3d(6671, 0, 0) if parentNode == universals.solarSystemRoot: universals.defaultSOIid = bodyEntity.id component.soi = 0 elif DB['type'] != 'star' or DB['type'] != 'barycenter': component.soi = self.getSOI(component.mass, self.bodies[0].mass, component.orbit['a']) body.type = DB['type'] body.reparentTo(parentNode) component.nodePath = body self.bodies.append(component) bodyEntity.addComponent(component) if universals.runClient and DB['type'] == 'star': component = graphicsComponents.RenderComponent() #component.mesh = NodePath(name) #self.sphere.copyTo(component.mesh) #component.mesh = shapeGenerator.Sphere(body.radius, 128, name) component.mesh = shapeGenerator.Sphere(body.radius, 64, name) #component.mesh.setScale(body.radius) component.mesh.reparentTo(sandbox.base.render) sandbox.send('makePickable', [component.mesh]) #texture = sandbox.base.loader.loadTexture('planets/' + DB['texture']) #texture.setMinfilter(Texture.FTLinearMipmapLinear) #ts1 = TextureStage('textures1') #ts1.setMode(TextureStage.MGlow) #component.mesh.setTexture(ts1, texture) #component.mesh.setTexture(texture, 1) component.light = component.mesh.attachNewNode(PointLight("sunPointLight")) component.light.node().setColor(Vec4(1, 1, 1, 1)) sandbox.base.render.setLight(component.light) bodyEntity.addComponent(component) #Shader test componentStar = graphicsComponents.StarRender() componentStar.noise_texture = Texture('noise') componentStar.noise_texture.setup2dTexture() img = PNMImage(1024, 1024) for y in range(1024): for x in range(1024): img.setXel(x, y, componentStar.noise.noise(x, y)) #print componentStar.noise.noise(x, y) componentStar.noise_texture.load(img) #componentStar.noise_texture.write('test.png') #component.mesh.setTexture(componentStar.noise_texture, 1) texture = sandbox.base.loader.loadTexture('planets/' + DB['texture']) ts1 = TextureStage('textures1') ts1.setMode(TextureStage.MGlow) component.mesh.setTexture(ts1, componentStar.noise_texture) #component.mesh.setTexture(ts1, texture) component.mesh.setShaderInput('time', universals.get_day_in_seconds()) shaders = Shader.load(Shader.SLGLSL, 'vortexVertex.glsl', 'starFrag.glsl') component.mesh.setShader(shaders) sandbox.send('makePickable', [component.mesh]) if universals.runClient and (DB['type'] == 'solid' or DB['type'] == 'moon'): component = graphicsComponents.RenderComponent() #component.mesh = shapeGenerator.Sphere(body.radius, 128, name) #component.mesh = shapeGenerator.Sphere(body.radius, 64, name) component.mesh = surface_mesh.make_planet(name=name, scale=body.radius) #sandbox.send('makePickable', [component.mesh]) sandbox.send('makePickable', [component.mesh.node_path]) #component.mesh.setScale(body.radius) component.mesh.reparent_to(sandbox.base.render) # Doing world text text = TextNode('node name') text.setText(name) #textNodePath = component.mesh.attachNewNode(text) textNodePath = component.mesh.node_path.attachNewNode(text) textNodePath.setScale(0.07) component.mesh.set_textures(DB['texture'], night_path=DB['night'], gloss_path=DB['spec']) component.mesh.set_ambient(1, 1, 1, 1) component.mesh.set_diffuse(1, 1, 1, 1) component.mesh.set_specular(1, 1, 1, 1) component.mesh.set_shininess(100) '''if '#' in DB['texture']: component.mesh.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition) component.mesh.setTexProjector(TextureStage.getDefault(), sandbox.base.render, component.mesh) component.mesh.setTexScale(TextureStage.getDefault(), 1, 1, -1) component.mesh.setTexHpr(TextureStage.getDefault(), 90, -18, 90) #self.mesh.setHpr(0, 90, 0) texture = loader.loadCubeMap('planets/' + DB['texture']) else: texture = sandbox.base.loader.loadTexture('planets/' + DB['texture']) #texture.setMinfilter(Texture.FTLinearMipmapLinear) component.mesh.setTexture(texture, 1)''' '''if "atmosphere" in DB: component.atmosphere = shapeGenerator.Sphere(-1, 128) component.atmosphere.reparentTo(render) component.atmosphere.setScale(body.radius * 1.025) outerRadius = component.atmosphere.getScale().getX() scale = 1 / (outerRadius - component.body.getScale().getX()) component.atmosphere.setShaderInput("fOuterRadius", outerRadius) component.atmosphere.setShaderInput("fInnerRadius", component.mesh.getScale().getX()) component.atmosphere.setShaderInput("fOuterRadius2", outerRadius * outerRadius) component.atmosphere.setShaderInput("fInnerRadius2", component.mesh.getScale().getX() * component.mesh.getScale().getX()) component.atmosphere.setShaderInput("fKr4PI", 0.000055 * 4 * 3.14159) component.atmosphere.setShaderInput("fKm4PI", 0.000015 * 4 * 3.14159) component.atmosphere.setShaderInput("fScale", scale) component.atmosphere.setShaderInput("fScaleDepth", 0.25) component.atmosphere.setShaderInput("fScaleOverScaleDepth", scale / 0.25) # Currently hard coded in shader component.atmosphere.setShaderInput("fSamples", 10.0) component.atmosphere.setShaderInput("nSamples", 10) # These do sunsets and sky colors # Brightness of sun ESun = 15 # Reyleight Scattering (Main sky colors) component.atmosphere.setShaderInput("fKrESun", 0.000055 * ESun) # Mie Scattering -- Haze and sun halos component.atmosphere.setShaderInput("fKmESun", 0.000015 * ESun) # Color of sun component.atmosphere.setShaderInput("v3InvWavelength", 1.0 / math.pow(0.650, 4), 1.0 / math.pow(0.570, 4), 1.0 / math.pow(0.465, 4)) #component.atmosphere.setShader(Shader.load("atmo.cg"))''' bodyEntity.addComponent(component) log.info(name + " set Up") if 'bodies' in DB: for bodyName, bodyDB in DB['bodies'].items(): self.generateNode(bodyName, bodyDB, body)
class HeightmapPatch: cachable = True def __init__(self, parent, x0, y0, x1, y1, width, height, scale=1.0, coord=TexCoord.Cylindrical, face=-1, border=1): self.parent = parent self.x0 = x0 self.y0 = y0 self.x1 = x1 self.y1 = y1 self.scale = scale self.width = width self.height = height self.coord = coord self.face = face self.border = border self.r_width = self.width + self.border * 2 self.r_height = self.height + self.border * 2 self.r_x0 = self.x0 - float( self.border) / self.width * (self.x1 - self.x0) self.r_x1 = self.x1 + float( self.border) / self.width * (self.x1 - self.x0) self.r_y0 = self.y0 - float( self.border) / self.height * (self.y1 - self.y0) self.r_y1 = self.y1 + float( self.border) / self.height * (self.y1 - self.y0) self.dx = self.r_x1 - self.r_x0 self.dy = self.r_y1 - self.r_y0 self.lod = None self.patch = None self.heightmap_ready = False self.texture = None self.texture_peeker = None self.callback = None self.cloned = False self.texture_offset = LVector2() self.texture_scale = LVector2(1, 1) self.min_height = None self.max_height = None self.mean_height = None @classmethod def create_from_patch(cls, noise, parent, x, y, scale, lod, density, coord=TexCoord.Cylindrical, face=-1): #TODO: Should be move to Patch/Tile if coord == TexCoord.Cylindrical: r_div = 1 << lod s_div = 2 << lod x0 = float(x) / s_div y0 = float(y) / r_div x1 = float(x + 1) / s_div y1 = float(y + 1) / r_div elif coord == TexCoord.NormalizedCube or coord == TexCoord.SqrtCube: div = 1 << lod r_div = div s_div = div x0 = float(x) / div y0 = float(y) / div x1 = float(x + 1) / div y1 = float(y + 1) / div else: div = 1 << lod r_div = div s_div = div size = 1.0 / (1 << lod) x0 = (x) * scale y0 = (y) * scale x1 = (x + size) * scale y1 = (y + size) * scale patch = cls(noise, parent, x0, y0, x1, y1, width=density, height=density, scale=scale, coord=coord, face=face, border=1) patch.patch_lod = lod patch.lod = lod patch.lod_scale_x = scale / s_div patch.lod_scale_y = scale / r_div patch.density = density patch.x = x patch.y = y return patch def copy_from(self, heightmap_patch): self.cloned = True self.lod = heightmap_patch.lod self.texture = heightmap_patch.texture self.texture_peeker = heightmap_patch.texture_peeker self.heightmap_ready = heightmap_patch.heightmap_ready self.min_height = heightmap_patch.min_height self.max_height = heightmap_patch.max_height self.mean_height = heightmap_patch.mean_height def calc_sub_patch(self): self.copy_from(self.parent_heightmap) delta = self.patch.lod - self.lod scale = 1 << delta if self.patch.coord != TexCoord.Flat: x_tex = int(self.x / scale) * scale y_tex = int(self.y / scale) * scale x_delta = float(self.x - x_tex) / scale y_delta = float(self.y - y_tex) / scale else: x_tex = int(self.x * scale) / scale y_tex = int(self.y * scale) / scale x_delta = float(self.x - x_tex) y_delta = float(self.y - y_tex) self.texture_offset = LVector2(x_delta, y_delta) self.texture_scale = LVector2(1.0 / scale, 1.0 / scale) def is_ready(self): return self.heightmap_ready def set_height(self, x, y, height): pass def get_height(self, x, y): if self.texture_peeker is None: print("No peeker", self.patch.str_id(), self.patch.instance_ready) traceback.print_stack() return 0.0 new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height new_x = min(new_x, self.width - 1) new_y = min(new_y, self.height - 1) height = self.parent.interpolator.get_value(self.texture_peeker, new_x, new_y) #TODO: This should be done in PatchedHeightmap.get_height() return height * self.parent.height_scale # + self.parent.offset def get_height_uv(self, u, v): return self.get_height(u * self.width, v * self.height) def load(self, patch, callback, cb_args=()): if self.texture is None: self.texture = Texture() self.texture.set_wrap_u(Texture.WMClamp) self.texture.set_wrap_v(Texture.WMClamp) self.parent.interpolator.configure_texture(self.texture) self.do_load(patch, callback, cb_args) else: if callback is not None: callback(self, *cb_args) def heightmap_ready_cb(self, texture, callback, cb_args): if texture is not None: self.texture = texture #print("READY", self.patch.str_id(), texture, self.texture) self.texture_peeker = texture.peek() # if self.texture_peeker is None: # print("NOT READY !!!") self.heightmap_ready = True data = self.texture.getRamImage() #TODO: should be completed and refactored signed = False component_type = texture.getComponentType() if component_type == Texture.T_float: buffer_type = numpy.float32 scale = 1.0 elif component_type == Texture.T_unsigned_byte: if signed: buffer_type = numpy.int8 scale = 128.0 else: buffer_type = numpy.uint8 scale = 255.0 elif component_type == Texture.T_unsigned_short: if signed: buffer_type = numpy.int16 scale = 32768.0 else: buffer_type = numpy.uint16 scale = 65535.0 if sys.version_info[0] < 3: buf = data.getData() np_buffer = numpy.fromstring(buf, dtype=buffer_type) else: np_buffer = numpy.frombuffer(data, buffer_type) np_buffer.shape = (self.texture.getYSize(), self.texture.getXSize(), self.texture.getNumComponents()) self.min_height = np_buffer.min() / scale self.max_height = np_buffer.max() / scale self.mean_height = np_buffer.mean() / scale else: if self.parent_heightmap is not None: self.calc_sub_patch() else: print("Make default texture for heightmap") texture = Texture() texture.setup_2d_texture(1, 1, Texture.T_float, Texture.F_r32) texture.set_clear_color(LColor(0, 0, 0, 0)) texture.make_ram_image() self.heightmap_ready_cb(texture, None, None) if callback is not None: callback(self, *cb_args) def do_load(self, patch, callback, cb_args): pass
def check_and_create_rendering_buffers(showbase): if not settings.render_scene_to_buffer: return if not settings.buffer_texture: print("Render to buffer not supported") return print("Render scene to buffer") buffer_multisamples = 0 if settings.render_scene_to_buffer and not settings.disable_multisampling and settings.use_multisampling and settings.multisamples > 0: buffer_multisamples = settings.multisamples manager = FilterManager(showbase.win, showbase.cam) color_buffer = Texture() depth_buffer = None aux_buffer = None if settings.use_inverse_z: render.set_attrib(DepthTestAttrib.make(DepthTestAttrib.M_greater)) depth_buffer = Texture() showbase.win.set_clear_depth(0) float_depth = True depth_bits = 24 else: float_depth = False depth_bits = 1 if settings.render_scene_to_float: if settings.floating_point_buffer: rgba_bits = (32, 32, 32, 32) float_colors = True else: print( "Floating point buffer not available, sRBG conversion will show artifacts" ) rgba_bits = (1, 1, 1, 1) float_colors = False else: rgba_bits = (1, 1, 1, 1) float_colors = False if settings.aux_buffer: aux_buffer = Texture() textures = { 'color': color_buffer, 'depth': depth_buffer, 'aux0': aux_buffer } fbprops = FrameBufferProperties() fbprops.setFloatColor(float_colors) fbprops.setRgbaBits(*rgba_bits) fbprops.setSrgbColor(settings.srgb_buffer) fbprops.setDepthBits(depth_bits) fbprops.setFloatDepth(float_depth) if not settings.framebuffer_multisampling: fbprops.setMultisamples(buffer_multisamples) final_quad = manager.render_scene_into(textures=textures, fbprops=fbprops) final_quad.clear_color() if aux_buffer is not None: manager.buffers[-1].setClearValue(GraphicsOutput.RTPAuxRgba0, (0.0, 0.0, 0.0, 0.0)) final_quad_shader = PostProcessShader( gamma_correction=settings.software_srgb, hdr=settings.use_hdr).create_shader() final_quad.set_shader(final_quad_shader) final_quad.set_shader_input("color_buffer", color_buffer) final_quad.set_shader_input("exposure", 2) return textures
def bld_page(self): self.skills = [drv[2] for drv in self.props.drivers] menu_gui = self.mdt.menu.gui menu_args = self.mdt.menu.gui.menu_args widgets = [ OnscreenText(text=_('Select the driver'), pos=(0, .8), **menu_gui.menu_args.text_args) ] self.track_path = self.mdt.menu.track t_a = self.mdt.menu.gui.menu_args.text_args.copy() del t_a['scale'] name = OnscreenText(_('Write your name:'), pos=(-.1, .6), scale=.06, align=TextNode.A_right, **t_a) self.ent = DirectEntry(scale=.08, pos=(0, 1, .6), entryFont=menu_args.font, width=12, frameColor=menu_args.btn_color, initialText=self.props.player_name or _('your name')) self.ent.onscreenText['fg'] = menu_args.text_fg self.drivers = [] for row, col in product(range(2), range(4)): idx = (col + 1) + row * 4 widgets += [ ImgBtn(scale=.24, pos=(-.75 + col * .5, 1, .25 - row * .5), frameColor=(0, 0, 0, 0), image=self.props.drivers_img[0] % idx, command=self.on_click, extraArgs=[idx], **self.mdt.menu.gui.menu_args.imgbtn_args) ] self.drivers += [widgets[-1]] sign = lambda x: '\1green\1+\2' if x > 0 else '' psign = lambda x: '+' if x == 0 else sign(x) def ppcol(x): return '\1green\1%s\2' % x if x > 0 else '\1red\1%s\2' % x pcol = lambda x: x if x == 0 else ppcol(x) def add_lab(txt, pos_z): return OnscreenText(txt + ':', pos=(-.95 + col * .5, pos_z - row * .5), scale=.046, align=TextNode.A_left, **t_a) def add_txt(val, pos_z): return OnscreenText('%s%s%%' % (psign(val), pcol(val)), pos=(-.55 + col * .5, pos_z - row * .5), scale=.052, align=TextNode.A_right, **t_a) lab_lst = [(_('adherence'), .04), (_('speed'), .16), (_('stability'), .1)] widgets += map(lambda lab_def: add_lab(*lab_def), lab_lst) txt_lst = [(self.skills[idx - 1][1], .04), (self.skills[idx - 1][0], .16), (self.skills[idx - 1][2], .1)] widgets += map(lambda txt_def: add_txt(*txt_def), txt_lst) self.img = OnscreenImage(self.props.cars_img % self.mdt.car, parent=base.a2dBottomRight, pos=(-.38, 1, .38), scale=.32) widgets += [self.img, name, self.ent] map(self.add_widget, widgets) fpath = eng.curr_path + 'yyagl/assets/shaders/filter.vert' with open(fpath) as ffilter: vert = ffilter.read() shader = Shader.make(Shader.SL_GLSL, vert, frag) self.img.setShader(shader) self.img.setTransparency(True) self.t_s = TextureStage('ts') self.t_s.setMode(TextureStage.MDecal) empty_img = PNMImage(1, 1) empty_img.add_alpha() empty_img.alpha_fill(0) tex = Texture() tex.load(empty_img) self.img.setTexture(self.t_s, tex) ThanksPageGui.bld_page(self) self.update_tsk = taskMgr.add(self.update_text, 'update text') self.enable_buttons(False)
class ToonFPS(DirectObject): notify = directNotify.newCategory("ToonFPS") WeaponName2DamageData = {"pistol": (30.0, 10.0, 150.0, 0.3), "shotgun": (40.0, 15.0, 155.0, 0.5), "sniper": (40.0, 15.0, 155.0, 0.5)} def __init__(self, mg, weaponName = "pistol"): self.mg = mg self.weaponName = weaponName self.v_model_root = None self.v_model = None self.weapon = None self.track = None self.draw = None self.shoot = None self.reload = None self.empty = None self.cockBack = None self.cockFwd = None self.player_node = None # blach (02Aug15) # Drastically improved the accuracy of bullets... DRASTICALLY self.shooterTrav = None self.shooterRay = None self.shooterRayNode = None self.shooterHandler = None self.gui = ToonFPSGui(self) self.fsm = ClassicFSM('ToonFPS', [State('off', self.enterOff, self.exitOff), State('alive', self.enterAlive, self.exitAlive), State('dead', self.enterDead, self.exitDead)], 'off', 'off') #self.deadFSM = ClassicFSM('dead', [State('off', self.enterOff, self.exitOff), # State(']) self.aliveFSM = ClassicFSM('alive', [State('off', self.enterOff, self.exitOff), State('draw', self.enterDraw, self.exitDraw, ['idle']), State('idle', self.enterIdle, self.exitIdle, ['shoot', 'reload']), State('shoot', self.enterShoot, self.exitShoot, ['idle']), State('reload', self.enterReload, self.exitReload, ['idle'])], 'off', 'off') self.fsm.getStateNamed('alive').addChild(self.aliveFSM) #self.fsm.getStateNamed('dead').addChild(self.deadFSM) self.fsm.enterInitialState() self.aliveFSM.enterInitialState() if self.weaponName == "pistol": self.ammo = 14 elif self.weaponName == "shotgun": self.ammo = 7 self.hp = 125 self.max_hp = 125 self.firstPerson = FirstPerson() def movementTask(self, task): if (inputState.isSet('jump') or base.localAvatar.walkControls.isAirborne): if base.localAvatar.getAnimState() != "jump": base.localAvatar.setAnimState("jump") base.localAvatar.playMovementSfx(None) self.mg.sendUpdate("jumpingAvatar", [base.localAvatar.doId]) return Task.cont def enterAlive(self): if not self.mg.fsm.getCurrentState().getName() in ['gameOver', 'announceGameOver', 'finalScores']: self.start() self.resetHp() self.resetAmmo() if self.mg.fsm.getCurrentState().getName() == "play": self.reallyStart() def exitAlive(self): self.end() self.v_model.reparentTo(hidden) if self.mg.fsm.getCurrentState().getName() != "play": self.reallyEnd() def updatePoints(self): self.points = self.kills - self.deaths def enterDead(self, killer): base.localAvatar.getGeomNode().show() self.gui.end() base.localAvatar.attachCamera() self.freezeCamSfx = base.loadSfx("phase_4/audio/sfx/freeze_cam.ogg") self.freezeCamImage = None self.freezeCamImageFile = None base.camera.setZ(base.camera.getZ() + 2.0) taskMgr.add( self.cameraLookAtKillerTask, "lookAtKiller", extraArgs = [killer], appendTask = True ) taskMgr.doMethodLater( 2.0, self.startZoomOnKiller, "startFreezeCam", extraArgs = [killer], appendTask = True ) def startZoomOnKiller(self, killer, task): taskMgr.add( self.__zoomOnKillerTask, "zoomOnKiller", extraArgs = [killer], appendTask = True ) return task.done def __zoomOnKillerTask(self, killer, task): if base.camera.getDistance(killer) <= 10.0 and self.freezeCamSfx.status() == self.freezeCamSfx.READY: base.playSfx(self.freezeCamSfx) if base.camera.getDistance(killer) < 7.0: self.doFreezeCam() return task.done base.camera.setY(base.camera, 60 * globalClock.getDt()) return task.again 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 cameraLookAtKillerTask(self, killer, task): try: base.camera.lookAt(killer, 0, 0, 3) except AssertionError: pass return task.cont def exitDead(self): taskMgr.remove("zoomOnKiller") taskMgr.remove("lookAtKiller") taskMgr.remove("startFreezeCam") del self.freezeCamSfx if self.freezeCamImage: self.freezeCamImage.destroy() del self.freezeCamImage self.frameBuffer.clear() self.freezeCamTex.clear() del self.frameBuffer del self.freezeCamTex base.localAvatar.detachCamera() base.localAvatar.getGeomNode().hide() self.gui.start() def load(self): if self.weaponName == "pistol": self.draw = base.loadSfx("phase_4/audio/sfx/draw_secondary.ogg") self.shoot = base.loadSfx("phase_4/audio/sfx/pistol_shoot.ogg") self.reload = base.loadSfx("phase_4/audio/sfx/pistol_worldreload.ogg") elif self.weaponName == "sniper": self.draw = base.loadSfx("phase_4/audio/sfx/draw_primary.ogg") self.shoot = base.loadSfx("phase_4/audio/sfx/shotgun_shoot.ogg") self.cockBack = base.loadSfx("phase_4/audio/sfx/shotgun_cock_back.ogg") self.cockFwd = base.loadSfx("phase_4/audio/sfx/shotgun_cock_forward.ogg") elif self.weaponName == "shotgun": self.draw = base.loadSfx("phase_4/audio/sfx/draw_primary.ogg") self.shoot = base.loadSfx("phase_4/audio/sfx/shotgun_shoot.ogg") self.cockBack = base.loadSfx("phase_4/audio/sfx/shotgun_cock_back.ogg") self.cockFwd = base.loadSfx("phase_4/audio/sfx/shotgun_cock_forward.ogg") self.empty = base.loadSfx("phase_4/audio/sfx/shotgun_empty.ogg") self.v_model_root = base.camera.attachNewNode('v_model_root') self.v_model = Actor('phase_4/models/minigames/v_dgm.egg', {'pidle': 'phase_4/models/minigames/v_dgm-pistol-idle.egg', 'pshoot': 'phase_4/models/minigames/v_dgm-pistol-shoot.egg', 'preload': 'phase_4/models/minigames/v_dgm-pistol-reload.egg', 'pdraw': 'phase_4/models/minigames/v_dgm-pistol-draw.egg', 'sidle': 'phase_4/models/minigames/v_dgm-shotgun-idle.egg', 'sshoot': 'phase_4/models/minigames/v_dgm-shotgun-shoot.egg'}) if self.weaponName == "pistol": self.weapon = loader.loadModel("phase_4/models/props/water-gun.bam") self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.011")) self.weapon.setX(-0.125) self.weapon.setY(0.5) self.weapon.setScale(0.65) elif self.weaponName == "sniper": self.weapon = loader.loadModel("phase_4/models/props/sniper.egg") self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.029")) self.weapon.setScale(0.75) self.weapon.setPos(0.45, -1.03, -1.17) self.weapon.setHpr(9.46, 308.19, 75.78) elif self.weaponName == "shotgun": self.weapon = loader.loadModel("phase_4/models/props/shotgun.egg") self.weapon.reparentTo(self.v_model.exposeJoint(None, "modelRoot", "Bone.029")) self.weapon.setScale(0.75) self.weapon.setPos(0.45, -1.03, -1.17) self.weapon.setHpr(9.46, 308.19, 75.78) self.gui.load() def start(self): base.camLens.setNear(0.1) self.shooterTrav = CollisionTraverser('ToonFPS.shooterTrav') ray = CollisionRay() rayNode = CollisionNode('ToonFPS.rayNode') rayNode.addSolid(ray) rayNode.setCollideMask(BitMask32(0)) rayNode.setFromCollideMask(CIGlobals.WallBitmask | CIGlobals.FloorBitmask) self.shooterRay = ray self.shooterRayNode = base.camera.attachNewNode(rayNode) self.shooterHandler = CollisionHandlerQueue() self.shooterTrav.addCollider(self.shooterRayNode, self.shooterHandler) self.firstPerson.start() self.v_model_root.reparentTo(base.camera) self.v_model.reparentTo(self.v_model_root) if self.weaponName == "pistol": self.v_model_root.setZ(-1.8) self.v_model_root.setY(0.3) self.v_model_root.setX(-0.1) self.v_model_root.setH(2) elif self.weaponName == "sniper": self.v_model_root.setPos(-0.42, -0.81, -1.7) self.v_model_root.setHpr(359, 352.87, 0.00) elif self.weaponName == "shotgun": self.v_model_root.setPos(-0.42, -0.81, -1.7) self.v_model_root.setHpr(359, 352.87, 0.00) self.gui.start() self.firstPerson.disableMouse() self.aliveFSM.request('draw') def reallyStart(self): self.firstPerson.reallyStart() base.localAvatar.startTrackAnimToSpeed() #taskMgr.add(self.movementTask, "toonBattleMovement") def end(self): if self.aliveFSM.getCurrentState().getName() != 'off': self.aliveFSM.request('off') if self.firstPerson: self.firstPerson.enableMouse() self.firstPerson.end() taskMgr.remove("toonBattleMovement") if self.mg.fsm.getCurrentState().getName() != "play": self.fsm.request('off') def reallyEnd(self): try: self.ToonFPS_reallyEnded return except: self.ToonFPS_reallyEnded = 1 if self.shooterRayNode: self.shooterRayNode.removeNode() self.shooterRayNode = None self.shooterRay = None self.shooterTrav = None self.shooterHandler = None if self.firstPerson: self.firstPerson.reallyEnd() if self.v_model_root: self.v_model_root.reparentTo(hidden) if self.v_model: self.v_model.reparentTo(hidden) self.v_model.setPosHpr(0, 0, 0, 0, 0, 0) if self.gui: self.gui.end() base.camLens.setNear(1.0) def cleanup(self): try: self.ToonFPS_cleanedUp return except: self.ToonFPS_cleanedUp = 1 taskMgr.remove("lookAtKiller") taskMgr.remove("toonBattleMovement") if self.firstPerson: self.firstPerson.cleanup() self.firstPerson = None self.draw = None self.shoot = None self.reload = None self.empty = None self.ammo = None try: self.aliveFSM.requestFinalState() self.fsm.requestFinalState() except: self.notify.warning('Redundant call to enter the final state.') self.fsm = None self.aliveFSM = None self.player_node = None self.min_camerap = None self.max_camerap = None self.hp = None self.max_hp = None if self.v_model: self.v_model.cleanup() self.v_model = None if self.weapon: self.weapon.removeNode() self.weapon = None if self.weapon: self.v_model_root.removeNode() self.v_model_root = None if self.gui: self.gui.cleanup() def damageTaken(self, amount, avId): if self.hp <= 0.0: killer = self.mg.cr.doId2do.get(avId, None) self.fsm.request('dead', [killer]) self.gui.adjustHpMeter() def enterDraw(self): self.draw.play() if self.weaponName == "pistol": self.track = ActorInterval(self.v_model, 'pdraw', playRate = 1.6, name = 'drawTrack') elif self.weaponName == "shotgun": self.v_model.pose('sidle', 15) self.track = LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0), blendType = 'easeOut', name = 'drawTrack') elif self.weaponName == "sniper": self.v_model.pose('sidle', 15) self.track = LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0), blendType = 'easeOut', name = 'drawTrack') self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle']) self.track.start() def exitDraw(self): #self.draw.stop() if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None def enterIdle(self): if self.weaponName == "pistol": self.v_model.loop('pidle') elif self.weaponName == "shotgun": self.track = Sequence(LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 1, 0), startHpr = (0, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 0, 0), startHpr = (0, 1, 0), blendType = 'easeInOut')) self.track.loop() elif self.weaponName == "sniper": self.track = Sequence(LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 1, 0), startHpr = (0, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.v_model, duration = 2.0, quat = (0, 0, 0), startHpr = (0, 1, 0), blendType = 'easeInOut')) self.track.loop() self.accept('mouse1', self.requestShoot) if self.ammo <= 0: self.gui.notifyNoAmmo() if self.ammo < 14: self.accept('r', self.aliveFSM.request, ['reload']) def requestShoot(self): if self.mg.fsm.getCurrentState().getName() != "play": return if self.ammo > 0: self.aliveFSM.request('shoot') else: self.empty.play() def exitIdle(self): self.v_model.stop() if self.track: self.track.finish() self.track = None self.ignore('mouse1') self.ignore('r') def enterShoot(self): self.shoot.play() if self.weaponName == "pistol": self.track = ActorInterval(self.v_model, 'pshoot', playRate = 2, name = 'shootTrack') elif self.weaponName == "shotgun": self.track = Parallel( Sequence( LerpQuatInterval(self.v_model, duration = 0.05, quat = (0, 3, 0), startHpr = (0, 0, 0)), LerpQuatInterval(self.v_model, duration = 0.1, quat = (0, 0, 0), startHpr = (0, 3, 0)) ), Sequence( LerpPosInterval(self.v_model, duration = 0.05, pos = (0, -0.3, 0), startPos = (0, 0, 0)), LerpPosInterval(self.v_model, duration = 0.1, pos = (0, 0, 0), startPos = (0, -0.3, 0)), Wait(0.1) ), ) elif self.weaponName == "sniper": self.track = Parallel( Sequence( LerpQuatInterval(self.v_model, duration = 0.05, quat = (0, 3, 0), startHpr = (0, 0, 0)), LerpQuatInterval(self.v_model, duration = 0.1, quat = (0, 0, 0), startHpr = (0, 3, 0)) ), Sequence( LerpPosInterval(self.v_model, duration = 0.05, pos = (0, -0.3, 0), startPos = (0, 0, 0)), LerpPosInterval(self.v_model, duration = 0.1, pos = (0, 0, 0), startPos = (0, -0.3, 0)), Wait(0.1) ), ) self.track.setDoneEvent('shootTrack') self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle']) self.track.start() self.ammo -= 1 self.gui.adjustAmmoGui() self.mg.makeSmokeEffect(self.weapon.find('**/joint_nozzle').getPos(render)) self.traverse() def traverse(self): mpos = base.mouseWatcherNode.getMouse() self.shooterRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.shooterTrav.traverse(render) def calcDamage(self, avatar): dmgData = self.WeaponName2DamageData[self.weaponName] maxDamage = dmgData[0] minDistance = dmgData[1] maxDistance = dmgData[2] factor = dmgData[3] distance = base.localAvatar.getDistance(avatar) if distance < minDistance: distance = minDistance elif distance > maxDistance: distance = maxDistance damage = maxDamage - ((distance - minDistance) * factor) return damage def exitShoot(self): #self.shoot.stop() self.ignore('shootTrack') if self.track: self.track.finish() self.track = None def enterReload(self): self.gui.deleteNoAmmoLabel() if self.weaponName == "pistol": self.track = Parallel(Sequence(Wait(0.3), Func(self.reload.play), Func(self.resetAmmo)), ActorInterval(self.v_model, 'preload', playRate = 1.5), name = 'reloadTrack') elif self.weaponName == "shotgun": self.track = Sequence(Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5, quat = (70, -50, 0), startHpr = (0, 0, 0), blendType = 'easeIn'), SoundInterval(self.cockBack), SoundInterval(self.cockFwd), Func(self.resetAmmo), Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0), blendType = 'easeOut'), name = 'reloadTrack') elif self.weaponName == "sniper": self.track = Sequence(Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5, quat = (70, -50, 0), startHpr = (0, 0, 0), blendType = 'easeIn'), SoundInterval(self.cockBack), SoundInterval(self.cockFwd), Func(self.resetAmmo), Func(self.draw.play), LerpQuatInterval(self.v_model, duration = 0.5, quat = (0, 0, 0), startHpr = (70, -50, 0), blendType = 'easeOut'), name = 'reloadTrack') self.track.setDoneEvent('reloadTrack') self.acceptOnce(self.track.getDoneEvent(), self.aliveFSM.request, ['idle']) self.track.start() def exitReload(self): #self.reload.stop() self.ignore('reloadTrack') if self.track: self.track.finish() self.track = None def resetAmmo(self): if self.weaponName == "pistol": self.ammo = 14 elif self.weaponName == "shotgun": self.ammo = 7 elif self.weaponName == "sniper": self.ammo = 7 self.gui.resetAmmo() def resetHp(self): self.hp = self.max_hp self.gui.adjustHpMeter() def enterOff(self): pass def exitOff(self): pass
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
class ShaderHeightmapPatch(HeightmapPatch): tex_generators = {} cachable = False def __init__(self, noise, parent, x0, y0, x1, y1, width, height, scale=1.0, coord=TexCoord.Cylindrical, face=0, border=1): HeightmapPatch.__init__(self, parent, x0, y0, x1, y1, width, height, scale, coord, face, border) self.shader = None self.texture = None self.texture_peeker = None self.noise = noise self.tex_generator = None self.callback = None self.cloned = False self.texture_offset = LVector2() self.texture_scale = LVector2(1, 1) def copy_from(self, heightmap_patch): self.cloned = True self.lod = heightmap_patch.lod self.texture = heightmap_patch.texture self.texture_peeker = heightmap_patch.texture_peeker self.heightmap_ready = heightmap_patch.heightmap_ready def get_height(self, x, y): if self.texture_peeker is None: print("No peeker", self.patch.str_id(), self.patch.instance_ready) traceback.print_stack() return 0.0 try: color = LColor() #pos = LVector2(x * self.texture_scale[0], ((self.height - 1) - y) * self.texture_scale[1]) + self.texture_offset new_x = x * self.texture_scale[0] + self.texture_offset[0] * self.width #new_y = y * self.texture_scale[1] + self.texture_offset[1] * self.height #new_y = ((self.height - 1) - new_y) new_y = ((self.height - 1) - y) * self.texture_scale[1] + self.texture_offset[1] * self.height #print(x, y, int(new_x), int(new_y), self.texture_scale, self.texture_offset) self.texture_peeker.fetch_pixel(color, min(int(new_x), self.width - 1), min(int(new_y), self.height - 1)) #self.texture_peeker.fetch_pixel(color, x, y) if settings.encode_float: height = color[0] + color[1] / 255.0 + color[2] / 65025.0 + color[3] / 16581375.0 else: height = color[0] except AssertionError as e: #traceback.print_stack() #print(e) print(x, y) print(int(new_x), int(new_y)) print(((self.height - 1) - y), self.texture_scale[1], ((self.height - 1) - y) * self.texture_scale[1], self.texture_offset[1] * self.height) height = 0.0 #print(height, self.parent.height_scale) #TODO: This should be done in PatchedHeightmap.get_height() return height * self.parent.height_scale# + self.parent.offset def generate(self, callback, cb_args=()): if self.texture is None: self.texture = Texture() self.texture.set_wrap_u(Texture.WMClamp) self.texture.set_wrap_v(Texture.WMClamp) self.texture.setMinfilter(Texture.FT_linear) self.texture.setMagfilter(Texture.FT_linear) self._make_heightmap(callback, cb_args) else: if callback is not None: callback(self, *cb_args) def heightmap_ready_cb(self, texture, callback, cb_args): #print("READY", self.patch.str_id()) self.texture_peeker = self.texture.peek() # if self.texture_peeker is None: # print("NOT READY !!!") self.heightmap_ready = True if callback is not None: callback(self, *cb_args) def _make_heightmap(self, callback, cb_args): if not self.width in ShaderHeightmapPatch.tex_generators: ShaderHeightmapPatch.tex_generators[self.width] = GeneratorPool(settings.patch_pool_size) if settings.encode_float: texture_format = Texture.F_rgba else: texture_format = Texture.F_r32 ShaderHeightmapPatch.tex_generators[self.width].make_buffer(self.width, self.height, texture_format) tex_generator = ShaderHeightmapPatch.tex_generators[self.width] if self.shader is None: self.shader = NoiseShader(coord=self.coord, noise_source=self.noise, noise_target=FloatTarget(), offset=(self.x0, self.y0, 0.0), scale=(self.lod_scale_x, self.lod_scale_y, 1.0)) self.shader.global_frequency = self.parent.global_frequency self.shader.create_and_register_shader(None, None) tex_generator.generate(self.shader, self.face, self.texture, self.heightmap_ready_cb, (callback, cb_args))