def __init__(self): ShowBase.__init__(self) self.loader.destroy() self.loader = CogInvasionLoader(self) builtins.loader = self.loader self.graphicsEngine.setDefaultLoader(self.loader.loader) self.makeAllPipes() from panda3d.core import RenderAttribRegistry from panda3d.core import ShaderAttrib, TransparencyAttrib from panda3d.bsp import BSPMaterialAttrib attribRegistry = RenderAttribRegistry.getGlobalPtr() attribRegistry.setSlotSort(BSPMaterialAttrib.getClassSlot(), 0) attribRegistry.setSlotSort(ShaderAttrib.getClassSlot(), 1) attribRegistry.setSlotSort(TransparencyAttrib.getClassSlot(), 2) self.bloomToggle = False self.hdrToggle = False self.fxaaToggle = CIGlobals.getSettingsMgr().getSetting("aa").getValue() == "FXAA" self.aoToggle = False # Initialized in initStuff() self.shaderGenerator = None self.initialize()
def SetupLights(self): # Create Ambient Light ambientLight = AmbientLight('ambientLight') ambientLight.setColor((0.2, 0.2, 0.2, 1)) self.ambLight = self.render.attachNewNode(ambientLight) self.render.setLight(self.ambLight) # Directional light 01 directionalLight1 = DirectionalLight('directionalLight') directionalLight1.setColor((1, 1, 1, 1)) self.dirLight1 = self.render.attachNewNode(directionalLight1) # This light is facing backwards, towards the camera. self.dirLight1.setHpr(40, -40, 0) self.render.setLight(self.dirLight1) directionalLight2 = DirectionalLight('directionalLight') directionalLight2.setColor((0.9, 0.9, 0.9, 1)) self.dirLight2 = self.render.attachNewNode(directionalLight2) # This light is facing backwards, towards the camera. self.dirLight2.setHpr(180+40, 30, 0) self.render.setLight(self.dirLight2) self.render.setAntialias(AntialiasAttrib.MLine) self.render.setAttrib(TransparencyAttrib.make(TransparencyAttrib.M_dual))
def _make_fullscreen_tri(self): """ Creates the oversized triangle used for rendering """ vformat = GeomVertexFormat.get_v3() vdata = GeomVertexData("vertices", vformat, Geom.UH_static) vdata.set_num_rows(3) vwriter = GeomVertexWriter(vdata, "vertex") vwriter.add_data3f(-1, 0, -1) vwriter.add_data3f(3, 0, -1) vwriter.add_data3f(-1, 0, 3) gtris = GeomTriangles(Geom.UH_static) gtris.add_next_vertices(3) geom = Geom(vdata) geom.add_primitive(gtris) geom_node = GeomNode("gn") geom_node.add_geom(geom) geom_node.set_final(True) geom_node.set_bounds(OmniBoundingVolume()) tri = NodePath(geom_node) tri.set_depth_test(False) tri.set_depth_write(False) tri.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 10000) tri.set_color(Vec4(1)) tri.set_bin("unsorted", 10) tri.reparent_to(self._node) self._tri = tri
def __build_Model(self, planet, model_type, rec): model_np = NodePath("model_{}".format(rec)) # Basic terrain model. ter_model, pts = self.__get_Sphere_Model(model_type, rec, planet.radius, "terrain") ter_model.NP.reparentTo(model_np) # Map planet topography. if "height_map" in planet.__dict__ and model_type in ("mid", "high"): self.__map_Topography(planet, ter_model, pts) # Map planet colours for low type models only. if model_type == "low" and "colour_map" in planet.__dict__: self.__map_Colours(planet, ter_model, rec, pts) # Atmosphere. if "atmos_ceiling" in planet.__dict__: a_radius = planet.radius + planet.atmos_ceiling am_type = model_type if model_type != "high" else "mid" atmos_model, a_pts = self.__get_Sphere_Model( am_type, min(rec, 7), a_radius, "atmos") atmos_model.NP.setAttrib( CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) atmos_model.NP.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MAlpha)) atmos_model.NP.reparentTo(model_np) model_np.attachNewNode("planet_label") return model_np
def __build_Model(self, planet, model_type, rec): model_np = NodePath("model_{}".format(rec)) # Basic terrain model. ter_model, pts = self.__get_Sphere_Model(model_type, rec, planet.radius, "terrain") ter_model.NP.reparentTo(model_np) # Map planet topography. if "height_map" in planet.__dict__ and model_type in ("mid", "high"): self.__map_Topography(planet, ter_model, pts) # Map planet colours for low type models only. if model_type == "low" and "colour_map" in planet.__dict__: self.__map_Colours(planet, ter_model, rec, pts) # Atmosphere. if "atmos_ceiling" in planet.__dict__: a_radius = planet.radius + planet.atmos_ceiling am_type = model_type if model_type != "high" else "mid" atmos_model, a_pts = self.__get_Sphere_Model(am_type, min(rec,7), a_radius, "atmos") atmos_model.NP.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) atmos_model.NP.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MAlpha)) atmos_model.NP.reparentTo(model_np) model_np.attachNewNode("planet_label") return model_np
def setMaterial(self, mat): self.material.material = mat if mat: self.state3D = self.state3D.setAttrib(BSPMaterialAttrib.make(mat.material)) if mat.material.hasKeyvalue("$translucent") and bool(int(mat.material.getKeyvalue("$translucent"))): self.state3D = self.state3D.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MDual)) if self.geom3D: self.solid.setFaceGeomState(self.geom3D, self.state3D)
def prepareSceneRender(self): self.debug("Preparing scene render for", self._name) # Init buffer object self._createBuffer() # Prepare fullscreen quad self._quad = self._makeFullscreenQuad() # Prepare initial state cs = NodePath("InitialStateDummy") cs.setState(self._sourceCam.node().getInitialState()) if self.hasTarget(RenderTargetType.Aux0): cs.setAttrib(AuxBitplaneAttrib.make(self._auxBits), 20) cs.setAttrib(StencilAttrib.makeOff(), 20) if not self._enableTransparency: cs.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 20) self._sourceCam.node().setInitialState(cs.getState()) # Set new camera bufferCam = self._makeFullscreenCam() bufferCamNode = self._quad.attachNewNode(bufferCam) self._region.setCamera(bufferCamNode) self._region.setSort(5) # Set clears bufferRegion = self._buffer.getInternalBuffer().getDisplayRegion(0) self._correctClears() bufferRegion.setClearStencilActive(False) # self._sourceWindow.setClearStencilActive(False) # Set aux clears targetCheck = [ (RenderTargetType.Aux0, GraphicsOutput.RTPAuxRgba0), (RenderTargetType.Aux1, GraphicsOutput.RTPAuxRgba1), (RenderTargetType.Aux2, GraphicsOutput.RTPAuxRgba2), (RenderTargetType.Aux3, GraphicsOutput.RTPAuxRgba3), ] for target, targetBindPos in targetCheck: if self.hasTarget(target): bufferRegion.setClearActive(targetBindPos, 1) bufferRegion.setClearValue(targetBindPos, Vec4(0.5, 0.5, 1.0, 0.0)) self._region.disableClears() bufferRegion.setCamera(self._sourceCam) bufferRegion.setActive(1) # bufferRegion.setClearDepthActive(False) bufferRegion.setSort(20) self._setSizeShaderInput()
def _setup(self): self.debug("Setting up render pipeline") # First, we need no transparency render.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Now create deferred render buffers self._makeDeferredTargets() # Setup compute shader for lighting self._createLightingPipeline() # Setup combiner self._createCombiner() self.deferredTarget.setShader( BetterShader.load("Shader/DefaultPostProcess.vertex", "Shader/TextureDisplay.fragment")) self._setupAntialiasing() self._createFinalPass() self.antialias.getFirstBuffer().setShaderInput( "lastFrame", self.lightingComputeCombinedTex) self.antialias.getFirstBuffer().setShaderInput("lastPosition", self.lastPositionBuffer) self.antialias.getFirstBuffer().setShaderInput( "currentPosition", self.deferredTarget.getColorTexture()) # self.deferredTarget.setShaderInput("sampler", self.lightingComputeCombinedTex) # self.deferredTarget.setShaderInput("sampler", self.antialias.getResultTexture()) self.deferredTarget.setShaderInput("sampler", self.finalPass.getColorTexture()) # self.deferredTarget.setShaderInput("sampler", self.combiner.getColorTexture()) # self.deferredTarget.setShaderInput("sampler", self.lightingComputeCombinedTex) # self.deferredTarget.setShaderInput("sampler", self.antialias._neighborBuffer.getColorTexture()) # self.deferredTarget.setShaderInput("sampler", self.antialias._blendBuffer.getColorTexture()) # self.deferredTarget.setShaderInput("sampler", self.lightingComputeCombinedTex) # add update task self._attachUpdateTask() # compute first mvp self._computeMVP() self.lastLastMVP = self.lastMVP # DirectFrame(frameColor=(1, 1, 1, 0.2), frameSize=(-0.28, 0.28, -0.27, 0.4), pos=(base.getAspectRatio() - 0.35, 0.0, 0.49)) self.atlasDisplayImage = OnscreenImage( image=self.lightManager.getAtlasTex(), pos=(base.getAspectRatio() - 0.35, 0, 0.5), scale=(0.25, 0, 0.25)) self.lastPosImage = OnscreenImage( image=self.lightingComputeCombinedTex, pos=(base.getAspectRatio() - 0.35, 0, -0.05), scale=(0.25, 0, 0.25))
def _makeSquare(self): c = CardMaker("square") c.setFrame(-0.5, 0.5, -0.5, 0.5) self.square = NodePath(c.generate()) self.square.setShaderInput("font", self.fontTex) self.square.setShader(self.fontShader) self.square.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MAlpha), 100) self.square.reparentTo(Globals.base.aspect2d) return self.square
def _makeSquare(self): c = CardMaker("square") c.setFrame(-0.5, 0.5, -0.5, 0.5) self.square = NodePath(c.generate()) self.square.setShaderInput("font", self.fontTex) self.square.setShader(self.fontShader, 1000) self.square.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MAlpha), 1000) self.square.reparentTo(self.parent) return self.square
def remapTextures(self): # ------------------------------------------------------------------------------------- # ANIMATED TEXTURE SETUP AND TRANSPARENCY FOR ZONE GEOMETRY (NOT PLACEABLES etc!) # trying to evaluate the scene graph structure under our root node here # since flattenStrong() totally changes the structure of our scene from how we # originally created it, we need to find a way to: # - get a the geoms that the flatten process has produced # - find their textures # - map those back to our sprites # - and finally set up the update process for texture animations based on the above # # NOTE this code will fail if there is more than one sprite useing a single texture! # Not encountered this yet though. self.world.consoleOut('setting up animated textures for zone geometry') for child in self.rootNode.getChildren(): # print child geom_node = child.node() for geom_number in range(0, geom_node.getNumGeoms()): geom_render_state = geom_node.getGeomState(geom_number) attr = geom_render_state.getAttrib(26) # attrib 26 is the texture attribute (hope this is static) if attr != None: # print attr tex = attr.getTexture() # print tex # BINGO! now we have the texture for this GEOM, lets find the sprite sprite = self.zone_wld_container.findSpriteUsing(tex) if sprite != None: # print sprite # set general texture alpha based tansparency for masked textures # if sprite.masked == 1: # child.setTransparency(TransparencyAttrib.MAlpha) if sprite.transparent == 1 or sprite.masked == 1: # EXPERIMENTAL TRANSPARENCY SUPPORT ############### # This is for semi-transparent polygons (water surfaces etc) # we implement the transparency via the alpha component of the GEOM's ColorAttrib ta = TransparencyAttrib.make(TransparencyAttrib.MAlpha) geom_render_state = geom_render_state.setAttrib(ta, 1) # potentialy needs passing "int override" (=1?) as second param if not sprite.masked == 1: ca = ColorAttrib.makeFlat(Vec4(1, 1, 1, sprite.alpha)) geom_render_state = geom_render_state.setAttrib(ca, 1) # potentialy needs passing "int override" (=1?) as second param geom_node.setGeomState(geom_number, geom_render_state) # ##################################################### if sprite.anim_delay > 0: # ANIMATED SPRITE # sprite.addAnimGeomRenderState((geom_node, geom_number, geom_render_state)) sprite.addAnimGeomRenderState((geom_node, geom_number, geom_render_state)) else: print 'could not find sprite for geom node, node texture cant be animated'
def registerEarlyZTagState(self, name, state): """ Registers a new tag state """ if not self.prepassCam: return # state.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullClockwise), 10000) state.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff), 10000) state.setAttrib(AlphaTestAttrib.make(AlphaTestAttrib.MNone, 1.0), 10000) state.setAttrib(DepthWriteAttrib.make(DepthWriteAttrib.MOn), 10000) state.setAttrib(DepthTestAttrib.make(DepthTestAttrib.MLess), 10000) state.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 10000) self.prepassCam.setTagState(name, state.getState())
def create(self): self.target = RenderTarget("ApplyLights") self.target.addColorTexture() self.target.setColorBits(16) self.target.prepareOffscreenBuffer() self.target.setClearColor(True) self.target.getQuad().removeNode() self.target.getNode().setAttrib( TransparencyAttrib.make(TransparencyAttrib.MNone), 1000) self.target.getNode().setAttrib( ColorBlendAttrib.make(ColorBlendAttrib.MAdd), 1000) self.quads = {} numInstances = self.tileCount.x * self.tileCount.y for lightType in ["DirectionalLightShadow"]: cm = CardMaker("BufferQuad-" + lightType) cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 1000) quad.setColor(Vec4(1, 0.5, 0.5, 1)) # Disable culling quad.node().setFinal(True) quad.node().setBounds(OmniBoundingVolume()) quad.setBin("unsorted", 10) quad.setInstanceCount(numInstances) quad.reparentTo(self.target.getNode()) self.quads[lightType] = quad self.target.getNode().setShaderInput("tileCount", self.tileCount)
def _makeFullscreenQuad(self): cm = CardMaker("BufferQuad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone)) quad.setColor(Vec4(1, 0.5, 0.5, 1)) # No culling check quad.node().setFinal(True) quad.node().setBounds(OmniBoundingVolume()) quad.setBin("unsorted", 10) return quad
def initSwitchSigns(self): self.switchSigns = [] for i in range(11): cm = CardMaker('card%d'%i) cm.setColor(0,0,0,0) cm.setFrame(-0.5, 0.5, -0.5, 0.5) card = self.level.attachNewNode(cm.generate()) card.setAttrib(TransparencyAttrib.make(TransparencyAttrib.M_alpha)) tex = loader.loadTexture('%d.png'%i) ts = TextureStage('ts') ts.setMode(TextureStage.MReplace) card.setTexture(ts, tex) card.setEffect(BillboardEffect.makePointEye()) card.hide() self.switchSigns.append(card)
def _makeFullscreenQuad(self): """ Create a quad which fills the full screen """ cm = CardMaker("BufferQuad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 1000) quad.setColor(Vec4(1, 0.5, 0.5, 1)) # No culling check quad.node().setFinal(True) quad.node().setBounds(OmniBoundingVolume()) quad.setBin("unsorted", 10) return quad
def _makeFullscreenQuad(self): """ Create a quad which fills the whole screen """ cm = CardMaker("BufferQuad") cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(False) quad.setDepthWrite(False) quad.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 1000) quad.setColor(Vec4(1, 0.5, 0.5, 1)) # Disable culling quad.node().setFinal(True) quad.node().setBounds(OmniBoundingVolume()) quad.setBin("unsorted", 10) return quad
def loadup(self, task): # get in front self.base.camera.setPos(0, 0, 0) # trusty typewriter self.typewriterNP = self.base.loader.loadModel('typewriter') # the desk self.deskNP = self.base.loader.loadModel('desk') # skybox skyb = skybox.NetmapSkybox(self.base, 'iceRiver', '', '.jpg') self.sky = skyb.create(self.base.cam) # sounds self.sounds['bell'] = self.base.loader.loadSfx('bell.wav') self.sounds['advance'] = self.base.loader.loadSfx('advance.wav') self.sounds['pullback'] = self.base.loader.loadSfx('pullback.wav') self.sounds['scroll'] = self.base.loader.loadSfx('scroll.wav') self.sounds['type1'] = self.base.loader.loadSfx('type1.wav') self.sounds['type2'] = self.base.loader.loadSfx('type2.wav') self.sounds['type3'] = self.base.loader.loadSfx('type3.wav') self.base.sfxManagerList[0].setVolume(0.5) if not self.skipIntro: self.sky.setAttrib( TransparencyAttrib.make(TransparencyAttrib.M_alpha)) self.sky.setAlphaScale(0, 1) alphaInterval = LerpFunc(lambda a: self.sky.setAlphaScale(a, 1), duration=1, fromData=0, toData=1, blendType='easeIn') seq = Sequence(alphaInterval) seq.setDoneEvent('createWorld') seq.start() else: self.base.messenger.send('createWorld')
def loadup(self, task): # get in front self.base.camera.setPos(0, 0, 0) # trusty typewriter self.typewriterNP = self.base.loader.loadModel('typewriter') # the desk self.deskNP = self.base.loader.loadModel('desk') # skybox skyb = skybox.NetmapSkybox(self.base, 'iceRiver', '', '.jpg') self.sky = skyb.create(self.base.cam) # sounds self.sounds['bell'] = self.base.loader.loadSfx('bell.wav') self.sounds['advance'] = self.base.loader.loadSfx('advance.wav') self.sounds['pullback'] = self.base.loader.loadSfx('pullback.wav') self.sounds['scroll'] = self.base.loader.loadSfx('scroll.wav') self.sounds['type1'] = self.base.loader.loadSfx('type1.wav') self.sounds['type2'] = self.base.loader.loadSfx('type2.wav') self.sounds['type3'] = self.base.loader.loadSfx('type3.wav') self.base.sfxManagerList[0].setVolume(0.5) if not self.skipIntro: self.sky.setAttrib(TransparencyAttrib.make(TransparencyAttrib.M_alpha)) self.sky.setAlphaScale(0, 1) alphaInterval = LerpFunc(lambda a: self.sky.setAlphaScale(a, 1), duration=1, fromData=0, toData=1, blendType='easeIn') seq = Sequence(alphaInterval) seq.setDoneEvent('createWorld') seq.start() else: self.base.messenger.send('createWorld')
def __build_Atmos_Sphere(self): sphere_path = "{}/sphere_simp_6.bam".format(_path.MODELS) atmos_model_np = loader.loadModel(sphere_path).getChild(0) atmos_model_np.setName("atmos") atmos_model = Model(atmos_model_np) pts = atmos_model.read("vertex") pts = list(map(lambda pt: pt*_env.ATMOS_RADIUS, pts)) atmos_model.modify("vertex", pts) atmos_model.NP.setAttrib(CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) atmos_model.NP.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MAlpha)) atmos_vert_path = "{}/env_atmos_VERT.glsl".format(_path.SHADERS) atmos_frag_path = "{}/env_atmos_FRAG.glsl".format(_path.SHADERS) atmos_shader = Shader.load(Shader.SL_GLSL, atmos_vert_path, atmos_frag_path) atmos_model.NP.setShader(atmos_shader) atmos_model.NP.setShaderInput("atmos_colour", LVector4f(0,0,0,0)) atmos_model.NP.setBin("fixed", 10) atmos_model.NP.reparentTo(self.NP) return atmos_model.NP
def prepare_render(self, camera_np): """ Prepares to render a scene """ self.create_default_region = False self._create_buffer() self._source_region = self._internal_buffer.get_display_region(0) if camera_np: initial_state = NodePath("rtis") initial_state.set_state(camera_np.node().get_initial_state()) if self._aux_count: initial_state.set_attrib( AuxBitplaneAttrib.make(self._aux_bits), 20) initial_state.set_attrib( TransparencyAttrib.make(TransparencyAttrib.M_none), 20) if max(self._color_bits) == 0: initial_state.set_attrib( ColorWriteAttrib.make(ColorWriteAttrib.C_off), 20) # Disable existing regions of the camera for region in camera_np.node().get_display_regions(): region.set_active(False) # Remove the existing display region of the camera for region in self._source_window.get_display_regions(): if region.get_camera() == camera_np: self._source_window.remove_display_region(region) camera_np.node().set_initial_state(initial_state.get_state()) self._source_region.set_camera(camera_np) self._internal_buffer.disable_clears() self._source_region.disable_clears() self._source_region.set_active(True) self._source_region.set_sort(20) # Reenable depth-clear, usually desireable self._source_region.set_clear_depth_active(True) self._source_region.set_clear_depth(1.0) self._active = True
def prepare_render(self, camera_np): """ Prepares to render a scene """ self.create_default_region = False self._create_buffer() self._source_region = self._internal_buffer.get_display_region(0) if camera_np: initial_state = NodePath("rtis") initial_state.set_state(camera_np.node().get_initial_state()) if self._aux_count: initial_state.set_attrib(AuxBitplaneAttrib.make(self._aux_bits), 20) initial_state.set_attrib(TransparencyAttrib.make(TransparencyAttrib.M_none), 20) if max(self._color_bits) == 0: initial_state.set_attrib(ColorWriteAttrib.make(ColorWriteAttrib.C_off), 20) # Disable existing regions of the camera for region in camera_np.node().get_display_regions(): region.set_active(False) # Remove the existing display region of the camera for region in self._source_window.get_display_regions(): if region.get_camera() == camera_np: self._source_window.remove_display_region(region) camera_np.node().set_initial_state(initial_state.get_state()) self._source_region.set_camera(camera_np) self._internal_buffer.disable_clears() self._source_region.disable_clears() self._source_region.set_active(True) self._source_region.set_sort(20) # Reenable depth-clear, usually desireable self._source_region.set_clear_depth_active(True) self._source_region.set_clear_depth(1.0) self._active = True
def __build_Atmos_Sphere(self): sphere_path = "{}/sphere_simp_6.bam".format(_path.MODELS) atmos_model_np = loader.loadModel(sphere_path).getChild(0) atmos_model_np.setName("atmos") atmos_model = Model(atmos_model_np) pts = atmos_model.read("vertex") pts = list(map(lambda pt: pt * _env.ATMOS_RADIUS, pts)) atmos_model.modify("vertex", pts) atmos_model.NP.setAttrib( CullFaceAttrib.make(CullFaceAttrib.MCullCounterClockwise)) atmos_model.NP.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MAlpha)) atmos_vert_path = "{}/env_atmos_VERT.glsl".format(_path.SHADERS) atmos_frag_path = "{}/env_atmos_FRAG.glsl".format(_path.SHADERS) atmos_shader = Shader.load(Shader.SL_GLSL, atmos_vert_path, atmos_frag_path) atmos_model.NP.setShader(atmos_shader) atmos_model.NP.setShaderInput("atmos_colour", LVector4f(0, 0, 0, 0)) atmos_model.NP.setBin("fixed", 10) atmos_model.NP.reparentTo(self.NP) return atmos_model.NP
def create(self): """ Creates this pipeline """ self.debug("Setting up render pipeline") if self.settings is None: self.error("You have to call loadSettings first!") return # Mount everything first self.mountManager.mount() # Store globals, as cython can't handle them self.debug("Setting up globals") Globals.load(self.showbase) # Setting up shader loading BetterShader._DumpShaders = self.settings.dumpGeneratedShaders # We use PTA's for shader inputs, because that's faster than # using setShaderInput self.temporalProjXOffs = PTAInt.emptyArray(1) self.cameraPosition = PTAVecBase3f.emptyArray(1) self.motionBlurFactor = PTAFloat.emptyArray(1) self.lastMVP = PTALMatrix4f.emptyArray(1) self.currentMVP = PTALMatrix4f.emptyArray(1) # Create onscreen gui # For the temporal reprojection it is important that the window width # is a multiple of 2 if self.showbase.win.getXSize() % 2 == 1: self.error( "The window has to have a width which is a multiple of 2 " "(Current: ", self.showbase.win.getXSize(), ")") self.error( "I'll correct that for you, but next time pass the correct " "window size!") wp = WindowProperties() wp.setSize( self.showbase.win.getXSize() + 1, self.showbase.win.getYSize()) self.showbase.win.requestProperties(wp) self.showbase.graphicsEngine.openWindows() self.camera = self.showbase.cam self.size = self._getSize() self.cullBounds = None # Debug variables to disable specific features self.haveLightingPass = True # haveCombiner can only be true when haveLightingPass is enabled self.haveCombiner = True self.haveMRT = True # Not as good as I want it, so disabled. I'll work on it. self.blurEnabled = False self.debug("Window size is", self.size.x, "x", self.size.y) self.showbase.camLens.setNearFar(0.1, 50000) self.showbase.camLens.setFov(90) self.showbase.win.setClearColor(Vec4(1.0,0.0,1.0,1.0)) # Create occlusion handler self._setupOcclusion() if self.settings.displayOnscreenDebugger: self.guiManager = PipelineGuiManager(self) self.guiManager.setup() # Generate auto-configuration for shaders self._generateShaderConfiguration() # Create light manager, which handles lighting + shadows if self.haveLightingPass: self.lightManager = LightManager(self) self.patchSize = LVecBase2i( self.settings.computePatchSizeX, self.settings.computePatchSizeY) # Create separate scene graphs. The deferred graph is render self.forwardScene = NodePath("Forward-Rendering") self.transparencyScene = NodePath("Transparency-Rendering") # We need no transparency (we store other information in the alpha # channel) self.showbase.render.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Now create deferred render buffers self._makeDeferredTargets() # Create the target which constructs the view-space normals and # position from world-space position if self.occlusion.requiresViewSpacePosNrm(): self._createNormalPrecomputeBuffer() # Setup the buffers for lighting self._createLightingPipeline() # Setup combiner for temporal reprojetion if self.haveCombiner: self._createCombiner() if self.occlusion.requiresBlurring(): self._createOcclusionBlurBuffer() self._setupAntialiasing() if self.blurEnabled: self._createDofStorage() self._createBlurBuffer() self._setupFinalPass() self._setShaderInputs() # add update task self._attachUpdateTask()
def __init__(self, *args, **kwargs): ShowBase.__init__(self, *args, **kwargs) from panda3d.core import RenderAttribRegistry from panda3d.core import ShaderAttrib, TransparencyAttrib from panda3d.bsp import BSPMaterialAttrib attribRegistry = RenderAttribRegistry.getGlobalPtr() attribRegistry.setSlotSort(BSPMaterialAttrib.getClassSlot(), 0) attribRegistry.setSlotSort(ShaderAttrib.getClassSlot(), 1) attribRegistry.setSlotSort(TransparencyAttrib.getClassSlot(), 2) gsg = self.win.getGsg() # Let's print out the Graphics information. self.notify.info( 'Graphics Information:\n\tVendor: {0}\n\tRenderer: {1}\n' '\tVersion: {2}\n\tSupports Cube Maps: {3}\n' '\tSupports 3D Textures: {4}\n\tSupports Compute Shaders: {5}'. format(gsg.getDriverVendor(), gsg.getDriverRenderer(), gsg.getDriverVersion(), str(gsg.getSupportsCubeMap()), str(gsg.getSupports3dTexture()), str(gsg.getSupportsComputeShaders()))) # Enable shader generation on all of the main scenes if gsg.getSupportsBasicShaders() and gsg.getSupportsGlsl(): self.render.setShaderAuto() self.render2d.setShaderAuto() self.render2dp.setShaderAuto() self.aspect2d.setShaderAuto() self.pixel2d.setShaderAuto() else: # I don't know how this could be possible self.notify.error("GLSL shaders unsupported by graphics driver.") return self.camNode.setCameraMask(CAMERA_MAIN) # Any ComputeNodes should be parented to this node, not render. # We isolate ComputeNodes to avoid traversing the same ComputeNodes # when doing multi-pass rendering. self.computeRoot = NodePath('computeRoot') self.computeCam = self.makeCamera(self.win) self.computeCam.node().setCameraMask(CAMERA_COMPUTE) self.computeCam.node().setCullBounds(OmniBoundingVolume()) self.computeCam.node().setFinal(True) self.computeCam.reparentTo(self.computeRoot) self.bspLoader = None self.bspLevel = None self.brushCollisionMaterialData = {} self.createBSPLoader() self.audio3d = None self.create3DAudio() # Initialized in createShaderGenerator() self.shaderGenerator = None # Initialized in createPostProcess() self.filters = None self.render.show(CAMERA_SHADOW) self.render.setAttrib(LightRampAttrib.makeIdentity())
def create(self): """ Creates the pipeline """ self.debug("Setting up render pipeline") self.guiVisible = True # Handy shortcuts self.showbase.accept("1", PStatClient.connect) self.showbase.accept("r", self.reloadShaders) self.showbase.accept("t", self.reloadEffects) self.showbase.accept("f7", self._createBugReport) self.showbase.accept("f8", self.toggleGui) if self.settings is None: self.error("You have to call loadSettings first!") return self.debug("Checking required Panda3D version ..") SystemAnalyzer.checkPandaVersionOutOfDate(12,8,2015) # SystemAnalyzer.analyze() # Mount everything first self.mountManager.mount() # Check if there is already another instance running, but only if specified # in the settings if self.settings.preventMultipleInstances and not self.mountManager.getLock(): self.fatal("Another instance of the rendering pipeline is already running") return # Store globals, as cython can't handle them self.debug("Setting up globals") Globals.load(self.showbase) Globals.resolution = LVecBase2i( \ int(self.showbase.win.getXSize() * self.settings.resolution3D), int(self.showbase.win.getYSize() * self.settings.resolution3D)) Globals.font = loader.loadFont("Data/Font/SourceSansPro-Semibold.otf") Globals.font.setPixelsPerUnit(25) # Check size if Globals.resolution.x % 2 == 1: self.fatal( "The window width has to be a multiple of 2 " "(Current: ", Globals.resolution.x, ")") return if self.settings.displayOnscreenDebugger: self.guiManager = PipelineGuiManager(self) else: self.guiManager = None # Some basic scene settings self.showbase.camLens.setNearFar(0.1, 70000) self.showbase.camLens.setFov(110) self.showbase.win.setClearColor(Vec4(1.0, 0.0, 1.0, 1.0)) self.showbase.camNode.setCameraMask(self.getMainPassBitmask()) self.showbase.render.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Create render pass matcher self.renderPassManager = RenderPassManager() # Create last frame buffers self._createLastFrameBuffers() self._precomputeScattering() # Add initial pass self.initialRenderPass = InitialRenderPass() self.renderPassManager.registerPass(self.initialRenderPass) # Add deferred pass self.deferredScenePass = DeferredScenePass(self) self.renderPassManager.registerPass(self.deferredScenePass) # Add lighting pass self.lightingPass = LightingPass() self.renderPassManager.registerPass(self.lightingPass) # Add dynamic exposure pass if self.settings.useAdaptiveBrightness: self.dynamicExposurePass = DynamicExposurePass(self) self.renderPassManager.registerPass(self.dynamicExposurePass) # Add motion blur pass if self.settings.enableMotionBlur: self.motionBlurPass = MotionBlurPass() self.renderPassManager.registerPass(self.motionBlurPass) # Add volumetric lighting # self.volumetricLightingPass = VolumetricLightingPass() # self.renderPassManager.registerPass(self.volumetricLightingPass) # Add bloom pass if self.settings.enableBloom: self.bloomPass = BloomPass() self.renderPassManager.registerPass(self.bloomPass) # Add dof pass if self.settings.enableDOF: self.dofPass = DOFPass() self.renderPassManager.registerPass(self.dofPass) # Add final pass self.finalPostprocessPass = FinalPostprocessPass() self.renderPassManager.registerPass(self.finalPostprocessPass) # Add scene finish pass self.sceneFinishPass = SceneFinishPass(self) self.renderPassManager.registerPass(self.sceneFinishPass) # Create managers self.occlusionManager = AmbientOcclusionManager(self) self.lightManager = LightManager(self) self.antialiasingManager = AntialiasingManager(self) self.dynamicObjectsManager = DynamicObjectsManager(self) self.sslrManager = SSLRManager(self) if self.settings.useTransparency: self.transparencyManager = TransparencyManager(self) if self.settings.enableClouds: self.cloudManager = CloudManager(self) self._createGlobalIllum() # Make variables available self._createGenericDefines() self._createInputHandles() self._createDefaultTextureInputs() self._createViewSpacePass() self._createSkyboxMaskPass() # Create an empty node at render space to store all dummmy cameras on camDummyNode = render.attachNewNode("RPCameraDummys") camDummyNode.hide() # Create an empty node at render space to store the light debug nodes lightDebugNode = render.attachNewNode("RPLightDebugNodes") # Finally matchup all the render passes and set the shaders self.renderPassManager.createPasses() self.renderPassManager.writeAutoconfig() self.renderPassManager.setShaders() # Create the update tasks self._createTasks() # Create the effect loader self.effectLoader = EffectLoader(self) # Apply the default effect to the scene self.setEffect(Globals.render, "Effects/Default/Default.effect", { "transparent": False, "normalMapping": True, "alphaTest": True, }, -10) render.setAttrib(AlphaTestAttrib.make(AlphaTestAttrib.MNone, 1), 999999) # Apply the debug effect to the light debug nodes self.setEffect(lightDebugNode, "Effects/LightDebug.effect", { "transparent": False, "normalMapping": False, "alphaTest": True, "castShadows": False, "castGI": False }, 100) self._setGuiShaders() if self.settings.enableGlobalIllumination: self.globalIllum.reloadShader() # Give the gui a hint when the pipeline is done loading if self.guiManager: self.guiManager.onPipelineLoaded()
def prepareSceneRender(self, earlyZ=False, earlyZCam=None): """ Renders the scene of the source camera to the buffer. See the documentation of this class for further information """ self.debug("Preparing scene render") # Init buffer object self._createBuffer() # Prepare initial state cs = NodePath("InitialStateDummy") cs.setState(self._sourceCam.node().getInitialState()) if self.hasTarget(RenderTargetType.Aux0): cs.setAttrib(AuxBitplaneAttrib.make(self._auxBits), 20) cs.setAttrib(StencilAttrib.makeOff(), 20) if not self._enableTransparency: cs.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 100) if not self._writeColor: cs.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff), 100) self._sourceCam.node().setInitialState(cs.getState()) if earlyZ: self._earlyZRegion = self._internalBuffer.makeDisplayRegion() self._earlyZRegion.setSort(-10) self._earlyZRegion.setCamera(earlyZCam) self._node = NodePath("RTRoot") # Prepare fullscreen quad if self._createOverlayQuad: self._quad = self._makeFullscreenQuad() self._quad.reparentTo(self._node) bufferCam = self._makeFullscreenCam() self._camera = self._node.attachNewNode(bufferCam) self._region.setCamera(self._camera) self._region.setSort(5) # Set clears bufferRegion = self._internalBuffer.getDisplayRegion(0) self._correctClears() bufferRegion.setClearStencilActive(False) # self._sourceWindow.setClearStencilActive(False) # Set aux clears targetCheck = [ (RenderTargetType.Aux0, GraphicsOutput.RTPAuxRgba0), (RenderTargetType.Aux1, GraphicsOutput.RTPAuxRgba1), (RenderTargetType.Aux2, GraphicsOutput.RTPAuxRgba2), (RenderTargetType.Aux3, GraphicsOutput.RTPAuxRgba3), ] for target, targetBindPos in targetCheck: if self.hasTarget(target): bufferRegion.setClearActive(targetBindPos, 1) bufferRegion.setClearValue(targetBindPos, Vec4(0.5, 0.5, 1.0, 0.0)) self._region.disableClears() bufferRegion.setCamera(self._sourceCam) bufferRegion.setActive(1) bufferRegion.setClearDepthActive(False) bufferRegion.setSort(20) if earlyZ: self._earlyZRegion.disableClears() self._earlyZRegion.setClearDepthActive(True) self._earlyZRegion.setActive(1) self._setSizeShaderInput() self._active = True self._registerBuffer()
def create(self): """ Creates the pipeline """ self.debug("Setting up render pipeline") # Handy shortcuts self.showbase.accept("r", self.reloadShaders) self.showbase.accept("f7", self.createBugReport) if self.settings is None: self.error("You have to call loadSettings first!") return self.debug("Checking required Panda3D version ..") SystemAnalyzer.checkPandaVersionOutOfDate(29,04,2015) # Mount everything first self.mountManager.mount() # Check if there is already another instance running, but only if specified # in the settings if self.settings.preventMultipleInstances and not self.mountManager.getLock(): self.fatal("Another instance of the rendering pipeline is already running") return # Store globals, as cython can't handle them self.debug("Setting up globals") Globals.load(self.showbase) Globals.font = loader.loadFont("Data/Font/SourceSansPro-Semibold.otf") Globals.font.setPixelsPerUnit(25) self._size = LVecBase2i(self.showbase.win.getXSize(), self.showbase.win.getYSize()) # Check size if self._size.x % 2 == 1: self.fatal( "The window width has to be a multiple of 2 " "(Current: ", self._size.x, ")") return if self.settings.displayOnscreenDebugger: self.guiManager = PipelineGuiManager(self) else: self.guiManager = None # Some basic scene settings self.showbase.camLens.setNearFar(0.1, 500000) self.showbase.camLens.setFov(110) self.showbase.win.setClearColor(Vec4(1.0, 0.0, 1.0, 1.0)) self.showbase.camNode.setCameraMask(self.getMainPassBitmask()) self.showbase.render.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Create render pass matcher self.renderPassManager = RenderPassManager() self._precomputeScattering() # Add initial pass self.initialRenderPass = InitialRenderPass() self.renderPassManager.registerPass(self.initialRenderPass) # Add deferred pass self.deferredScenePass = DeferredScenePass() self.renderPassManager.registerPass(self.deferredScenePass) # Add lighting pass self.lightingPass = LightingPass() self.renderPassManager.registerPass(self.lightingPass) # Add dynamic exposure pass if self.settings.useAdaptiveBrightness: self.dynamicExposurePass = DynamicExposurePass(self) self.renderPassManager.registerPass(self.dynamicExposurePass) # Add SSLR pass if self.settings.enableSSLR: self.sslrPass = SSLRPass() self.renderPassManager.registerPass(self.sslrPass) # Add volumetric lighting # self.volumetricLightingPass = VolumetricLightingPass() # self.renderPassManager.registerPass(self.volumetricLightingPass) # Add final pass self.finalPostprocessPass = FinalPostprocessPass() self.renderPassManager.registerPass(self.finalPostprocessPass) # Create managers self.occlusionManager = AmbientOcclusionManager(self) self.lightManager = LightManager(self) self.antialiasingManager = AntialiasingManager(self) self.dynamicObjectsManager = DynamicObjectsManager(self) if self.settings.useTransparency: self.transparencyManager = TransparencyManager(self) else: self.transparencyManager = None self._createGlobalIllum() # Make variables available self._createGenericDefines() self._createInputHandles() self._createDefaultTextureInputs() self._createViewSpacePass() # Finally matchup all the render passes and set the shaders self.renderPassManager.createPasses() self.renderPassManager.writeAutoconfig() self.renderPassManager.setShaders() # Create the update tasks self._createTasks() # Create the effect loader self.effectLoader = EffectLoader(self) # Apply the default effect to the scene self.setEffect(Globals.render, "Effects/Default/Default.effect", { "transparent": False, "normalMapping": False, "alphaTest": True, }, -10) if self.settings.enableGlobalIllumination: self.globalIllum.reloadShader() # Give the gui a hint when the pipeline is done loading if self.guiManager: self.guiManager.onPipelineLoaded() self.reloadShaders()
def prepareSceneRender(self): """ Renders the scene of the source camera to the buffer. See the documentation of this class for further information """ self.debug("Preparing scene render") # Init buffer object self._createBuffer() # Prepare fullscreen quad self._quad = self._makeFullscreenQuad() # Prepare initial state cs = NodePath("InitialStateDummy") cs.setState(self._sourceCam.node().getInitialState()) if self.hasTarget(RenderTargetType.Aux0): cs.setAttrib(AuxBitplaneAttrib.make(self._auxBits), 20) cs.setAttrib(StencilAttrib.makeOff(), 20) if not self._enableTransparency: cs.setAttrib(TransparencyAttrib.make(TransparencyAttrib.MNone), 100) if not self._writeColor: cs.setAttrib(ColorWriteAttrib.make(ColorWriteAttrib.COff), 100) self._sourceCam.node().setInitialState(cs.getState()) # Set new camera bufferCam = self._makeFullscreenCam() bufferCamNode = self._quad.attachNewNode(bufferCam) self._region.setCamera(bufferCamNode) self._region.setSort(5) # Set clears bufferRegion = self._buffer.getInternalBuffer().getDisplayRegion(0) self._correctClears() bufferRegion.setClearStencilActive(False) # self._sourceWindow.setClearStencilActive(False) # Set aux clears targetCheck = [ (RenderTargetType.Aux0, GraphicsOutput.RTPAuxRgba0), (RenderTargetType.Aux1, GraphicsOutput.RTPAuxRgba1), (RenderTargetType.Aux2, GraphicsOutput.RTPAuxRgba2), (RenderTargetType.Aux3, GraphicsOutput.RTPAuxRgba3), ] for target, targetBindPos in targetCheck: if self.hasTarget(target): bufferRegion.setClearActive(targetBindPos, 1) bufferRegion.setClearValue( targetBindPos, Vec4(0.5, 0.5, 1.0, 0.0)) self._region.disableClears() bufferRegion.setCamera(self._sourceCam) bufferRegion.setActive(1) # bufferRegion.setClearDepthActive(False) bufferRegion.setSort(20) self._setSizeShaderInput()
def create(self): """ Creates this pipeline """ self.debug("Setting up render pipeline") if self.settings is None: self.error("You have to call loadSettings first!") return self.debug("Analyzing system ..") SystemAnalyzer.analyze() self.debug("Checking required Panda3D version ..") SystemAnalyzer.checkPandaVersionOutOfDate(7,8,2014) # Mount everything first self.mountManager.mount() # Store globals, as cython can't handle them self.debug("Setting up globals") Globals.load(self.showbase) Globals.font = loader.loadFont("Data/Font/SourceSansPro-Semibold.otf") Globals.font.setPixelsPerUnit(25) # Setting up shader loading BetterShader._DumpShaders = self.settings.dumpGeneratedShaders # We use PTA's for shader inputs, because that's faster than # using setShaderInput self.temporalProjXOffs = PTAInt.emptyArray(1) self.cameraPosition = PTAVecBase3f.emptyArray(1) self.motionBlurFactor = PTAFloat.emptyArray(1) self.lastMVP = PTALMatrix4f.emptyArray(1) self.currentMVP = PTALMatrix4f.emptyArray(1) self.currentShiftIndex = PTAInt.emptyArray(1) # Initialize variables self.camera = self.showbase.cam self.size = self._getSize() self.cullBounds = None # For the temporal reprojection it is important that the window width # is a multiple of 2 if self.settings.enableTemporalReprojection and self.size.x % 2 == 1: self.error( "The window has to have a width which is a multiple of 2 " "(Current: ", self.showbase.win.getXSize(), ")") self.error( "I'll correct that for you, but next time pass the correct " "window size!") wp = WindowProperties() wp.setSize( self.showbase.win.getXSize() + 1, self.showbase.win.getYSize()) self.showbase.win.requestProperties(wp) self.showbase.graphicsEngine.openWindows() # Get new size self.size = self._getSize() # Debug variables to disable specific features self.haveLightingPass = True # haveCombiner can only be true when haveLightingPass is enabled self.haveCombiner = True self.haveMRT = True # Not as good as I want it, so disabled. I'll work on it. self.blurEnabled = False self.debug("Window size is", self.size.x, "x", self.size.y) self.showbase.camLens.setNearFar(0.1, 50000) self.showbase.camLens.setFov(115) self.showbase.win.setClearColor(Vec4(1.0, 0.0, 1.0, 1.0)) # Create GI handleer if self.settings.enableGlobalIllumination: self._setupGlobalIllumination() # Create occlusion handler self._setupOcclusion() if self.settings.displayOnscreenDebugger: self.guiManager = PipelineGuiManager(self) self.guiManager.setup() # Generate auto-configuration for shaders self._generateShaderConfiguration() # Create light manager, which handles lighting + shadows if self.haveLightingPass: self.lightManager = LightManager(self) self.patchSize = LVecBase2i( self.settings.computePatchSizeX, self.settings.computePatchSizeY) # Create separate scene graphs. The deferred graph is render self.forwardScene = NodePath("Forward-Rendering") self.transparencyScene = NodePath("Transparency-Rendering") self.transparencyScene.setBin("transparent", 30) # We need no transparency (we store other information in the alpha # channel) self.showbase.render.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Now create deferred render buffers self._makeDeferredTargets() # Create the target which constructs the view-space normals and # position from world-space position if self.occlusion.requiresViewSpacePosNrm(): self._createNormalPrecomputeBuffer() # Setup the buffers for lighting self._createLightingPipeline() # Setup combiner for temporal reprojetion if self.haveCombiner and self.settings.enableTemporalReprojection: self._createCombiner() if self.occlusion.requiresBlurring(): self._createOcclusionBlurBuffer() self._setupAntialiasing() if self.blurEnabled: self._createDofStorage() self._createBlurBuffer() # Not sure why it has to be 0.25. But that leads to the best result aspect = float(self.size.y) / self.size.x self.onePixelShift = Vec2( 0.125 / self.size.x, 0.125 / self.size.y / aspect) * self.settings.jitterAmount # Annoying that Vec2 has no multliply-operator for non-floats multiplyVec2 = lambda a, b: Vec2(a.x*b.x, a.y*b.y) if self.antialias.requiresJittering(): self.pixelShifts = [ multiplyVec2(self.onePixelShift, Vec2(-0.25, 0.25)), multiplyVec2(self.onePixelShift, Vec2(0.25, -0.25)) ] else: self.pixelShifts = [Vec2(0), Vec2(0)] self.currentPixelShift = PTAVecBase2f.emptyArray(1) self.lastPixelShift = PTAVecBase2f.emptyArray(1) self._setupFinalPass() self._setShaderInputs() # add update task self._attachUpdateTask()
def __init__(self, image_path, name=None,\ rows=1, cols=1, scale=1.0,\ twoSided=True, alpha=TRANS_ALPHA,\ repeatX=1, repeatY=1,\ anchorX=ALIGN_LEFT, anchorY=ALIGN_BOTTOM): """ Create a card textured with an image. The card is sized so that the ratio between the card and image is the same. """ scale *= self.PIXEL_SCALE self.animations = {} self.scale = scale self.repeatX = repeatX self.repeatY = repeatY self.flip = {'x':False,'y':False} self.rows = rows self.cols = cols self.currentFrame = 0 self.currentAnim = None self.loopAnim = False self.frameInterrupt = True # Create the NodePath if name: self.node = NodePath("Sprite2d:%s" % name) else: self.node = NodePath("Sprite2d:%s" % image_path) # Set the attribute for transparency/twosided self.node.node().setAttrib(TransparencyAttrib.make(alpha)) if twoSided: self.node.setTwoSided(True) # Make a filepath self.imgFile = Filename(image_path) if self.imgFile.empty(): raise IOError("File not found") # Instead of loading it outright, check with the PNMImageHeader if we can open # the file. imgHead = PNMImageHeader() if not imgHead.readHeader(self.imgFile): raise IOError("PNMImageHeader could not read file. Try using absolute filepaths") # Load the image with a PNMImage image = PNMImage() image.read(self.imgFile) self.sizeX = image.getXSize() self.sizeY = image.getYSize() self.frames = [] for rowIdx in range(self.rows): for colIdx in range(self.cols): self.frames.append(Sprite2d.Cell(colIdx, rowIdx)) # We need to find the power of two size for the another PNMImage # so that the texture thats loaded on the geometry won't have artifacts textureSizeX = self.nextsize(self.sizeX) textureSizeY = self.nextsize(self.sizeY) # The actual size of the texture in memory self.realSizeX = textureSizeX self.realSizeY = textureSizeY self.paddedImg = PNMImage(textureSizeX, textureSizeY) if image.hasAlpha(): self.paddedImg.alphaFill(0) # Copy the source image to the image we're actually using self.paddedImg.blendSubImage(image, 0, 0) # We're done with source image, clear it image.clear() # The pixel sizes for each cell self.colSize = self.sizeX/self.cols self.rowSize = self.sizeY/self.rows # How much padding the texture has self.paddingX = textureSizeX - self.sizeX self.paddingY = textureSizeY - self.sizeY # Set UV padding self.uPad = float(self.paddingX)/textureSizeX self.vPad = float(self.paddingY)/textureSizeY # The UV dimensions for each cell self.uSize = (1.0 - self.uPad) / self.cols self.vSize = (1.0 - self.vPad) / self.rows card = CardMaker("Sprite2d-Geom") # The positions to create the card at if anchorX == self.ALIGN_LEFT: posLeft = 0 posRight = (self.colSize/scale)*repeatX elif anchorX == self.ALIGN_CENTER: posLeft = -(self.colSize/2.0/scale)*repeatX posRight = (self.colSize/2.0/scale)*repeatX elif anchorX == self.ALIGN_RIGHT: posLeft = -(self.colSize/scale)*repeatX posRight = 0 if anchorY == self.ALIGN_BOTTOM: posTop = 0 posBottom = (self.rowSize/scale)*repeatY elif anchorY == self.ALIGN_CENTER: posTop = -(self.rowSize/2.0/scale)*repeatY posBottom = (self.rowSize/2.0/scale)*repeatY elif anchorY == self.ALIGN_TOP: posTop = -(self.rowSize/scale)*repeatY posBottom = 0 card.setFrame(posLeft, posRight, posTop, posBottom) card.setHasUvs(True) self.card = self.node.attachNewNode(card.generate()) # Since the texture is padded, we need to set up offsets and scales to make # the texture fit the whole card self.offsetX = (float(self.colSize)/textureSizeX) self.offsetY = (float(self.rowSize)/textureSizeY) self.node.setTexScale(TextureStage.getDefault(), self.offsetX * repeatX, self.offsetY * repeatY) self.node.setTexOffset(TextureStage.getDefault(), 0, 1-self.offsetY) self.texture = Texture() self.texture.setXSize(textureSizeX) self.texture.setYSize(textureSizeY) self.texture.setZSize(1) # Load the padded PNMImage to the texture self.texture.load(self.paddedImg) self.texture.setMagfilter(Texture.FTNearest) self.texture.setMinfilter(Texture.FTNearest) #Set up texture clamps according to repeats if repeatX > 1: self.texture.setWrapU(Texture.WMRepeat) else: self.texture.setWrapU(Texture.WMClamp) if repeatY > 1: self.texture.setWrapV(Texture.WMRepeat) else: self.texture.setWrapV(Texture.WMClamp) self.node.setTexture(self.texture)
def __init__(self): self.bspLoader = Py_CL_BSPLoader() self.bspLoader.setGlobalPtr(self.bspLoader) if metadata.USE_RENDER_PIPELINE: from rpcore import RenderPipeline self.pipeline = RenderPipeline() self.pipeline.create(self) else: ShowBase.__init__(self) self.loader.destroy() self.loader = CogInvasionLoader(self) __builtin__.loader = self.loader self.graphicsEngine.setDefaultLoader(self.loader.loader) self.cam.node().getDisplayRegion(0).setClearDepthActive(1) from panda3d.core import RenderAttribRegistry from panda3d.core import ShaderAttrib, TransparencyAttrib from libpandabsp import BSPMaterialAttrib attribRegistry = RenderAttribRegistry.getGlobalPtr() attribRegistry.setSlotSort(BSPMaterialAttrib.getClassSlot(), 0) attribRegistry.setSlotSort(ShaderAttrib.getClassSlot(), 1) attribRegistry.setSlotSort(TransparencyAttrib.getClassSlot(), 2) gsg = self.win.getGsg() # Let's print out the Graphics information. self.notify.info( 'Graphics Information:\n\tVendor: {0}\n\tRenderer: {1}\n\tVersion: {2}\n\tSupports Cube Maps: {3}\n\tSupports 3D Textures: {4}\n\tSupports Compute Shaders: {5}' .format(gsg.getDriverVendor(), gsg.getDriverRenderer(), gsg.getDriverVersion(), str(gsg.getSupportsCubeMap()), str(gsg.getSupports3dTexture()), str(gsg.getSupportsComputeShaders()))) # Enable shader generation on all of the main scenes if gsg.getSupportsBasicShaders() and gsg.getSupportsGlsl(): render.setShaderAuto() render2d.setShaderAuto() render2dp.setShaderAuto() else: # I don't know how this could be possible self.notify.error("GLSL shaders unsupported by graphics driver.") return # Let's disable fog on Intel graphics if gsg.getDriverVendor() == "Intel": metadata.NO_FOG = 1 self.notify.info('Applied Intel-specific graphical fix.') self.win.disableClears() self.camNode.setCameraMask(CIGlobals.MainCameraBitmask) from direct.distributed.ClockDelta import globalClockDelta __builtin__.globalClockDelta = globalClockDelta # Any ComputeNodes should be parented to this node, not render. # We isolate ComputeNodes to avoid traversing the same ComputeNodes # when doing multi-pass rendering. self.computeRoot = NodePath('computeRoot') self.computeCam = self.makeCamera(base.win) self.computeCam.node().setCullBounds(OmniBoundingVolume()) self.computeCam.node().setFinal(True) self.computeCam.reparentTo(self.computeRoot) # Initialized in initStuff() self.shaderGenerator = None render.hide() self.camLens.setNearFar(0.5, 10000) self.physicsWorld = BulletWorld() # Panda units are in feet, so the gravity is 32 feet per second, # not 9.8 meters per second. self.physicsWorld.setGravity(Vec3(0, 0, -32.1740)) self.physicsWorld.setGroupCollisionFlag(7, 1, True) self.physicsWorld.setGroupCollisionFlag(7, 2, True) self.physicsWorld.setGroupCollisionFlag(7, 3, False) self.physicsWorld.setGroupCollisionFlag(7, 4, False) self.physicsWorld.setGroupCollisionFlag(7, 8, True) self.taskMgr.add(self.__physicsUpdate, "physicsUpdate", sort=30) debugNode = BulletDebugNode('Debug') self.debugNP = render.attachNewNode(debugNode) self.physicsWorld.setDebugNode(self.debugNP.node()) self.physicsDbgFlag = False self.setPhysicsDebug(self.config.GetBool('physics-debug', False)) #self.shadowCaster = ShadowCaster(Vec3(163, -67, 0)) #self.shadowCaster.enable() self.bspLoader.setGamma(2.2) self.bspLoader.setWin(self.win) self.bspLoader.setCamera(self.camera) self.bspLoader.setRender(self.render) self.bspLoader.setMaterialsFile("phase_14/etc/materials.txt") #self.bspLoader.setTextureContentsFile("phase_14/etc/texturecontents.txt") self.bspLoader.setWantVisibility(True) self.bspLoader.setVisualizeLeafs(False) self.bspLoader.setWantLightmaps(True) #self.bspLoader.setShadowCamPos(Point3(-15, 5, 40)) #self.bspLoader.setShadowResolution(60 * 2, 1024 * 1) self.bspLoader.setPhysicsWorld(self.physicsWorld) self.bspLevel = None self.materialData = {} self.skyBox = None self.skyBoxUtil = None #self.nmMgr = RNNavMeshManager.get_global_ptr() #self.nmMgr.set_root_node_path(self.render) #self.nmMgr.get_reference_node_path().reparentTo(self.render) #self.nmMgr.start_default_update() #self.nmMgr.get_reference_node_path_debug().reparentTo(self.render) self.navMeshNp = None # Setup 3d audio run before igLoop so 3d positioning doesn't lag behind base.audio3d = Audio3DManager(base.sfxManagerList[0], camera, render) base.audio3d.setDropOffFactor(0.15) base.audio3d.setDopplerFactor(0.15) # Setup collision handlers base.cTrav = CollisionTraverser() base.lifter = CollisionHandlerFloor() base.pusher = CollisionHandlerPusher() base.queue = CollisionHandlerQueue() base.lightingCfg = None self.cl_attackMgr = None #self.accept('/', self.projectShadows) # Let's setup the user input storage system uis = UserInputStorage() self.inputStore = uis self.userInputStorage = uis __builtin__.inputStore = uis __builtin__.userInputStorage = uis self.credits2d = self.render2d.attachNewNode(PGTop("credits2d")) self.credits2d.setScale(1.0 / self.getAspectRatio(), 1.0, 1.0) self.wakeWaterHeight = -30.0 self.bloomToggle = False self.hdrToggle = False self.fxaaToggle = CIGlobals.getSettingsMgr().getSetting( "aa").getValue() == "FXAA" self.aoToggle = False self.music = None self.currSongName = None render.show(CIGlobals.ShadowCameraBitmask) self.avatars = [] wrm = WaterReflectionManager() self.waterReflectionMgr = wrm __builtin__.waterReflectionMgr = wrm # Let's setup our margins base.marginManager = MarginManager() base.margins = aspect2d.attachNewNode( base.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) base.leftCells = [ base.marginManager.addCell(0.1, -0.6, base.a2dTopLeft), base.marginManager.addCell(0.1, -1.0, base.a2dTopLeft), base.marginManager.addCell(0.1, -1.4, base.a2dTopLeft) ] base.bottomCells = [ base.marginManager.addCell(0.4, 0.1, base.a2dBottomCenter), base.marginManager.addCell(-0.4, 0.1, base.a2dBottomCenter), base.marginManager.addCell(-1.0, 0.1, base.a2dBottomCenter), base.marginManager.addCell(1.0, 0.1, base.a2dBottomCenter) ] base.rightCells = [ base.marginManager.addCell(-0.1, -0.6, base.a2dTopRight), base.marginManager.addCell(-0.1, -1.0, base.a2dTopRight), base.marginManager.addCell(-0.1, -1.4, base.a2dTopRight) ] base.mouseWatcherNode.setEnterPattern('mouse-enter-%r') base.mouseWatcherNode.setLeavePattern('mouse-leave-%r') base.mouseWatcherNode.setButtonDownPattern('button-down-%r') base.mouseWatcherNode.setButtonUpPattern('button-up-%r') cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) # The portal uses the shadow bin by default, # but we still want to see it with real shadows. cbm.addBin('portal', CullBinManager.BTBackToFront, 19) if not metadata.USE_REAL_SHADOWS: cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) else: cbm.addBin('shadow', CullBinManager.BTFixed, -100) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) cbm.addBin('gsg-popup', CullBinManager.BTFixed, 70) self.setBackgroundColor(CIGlobals.DefaultBackgroundColor) self.disableMouse() self.enableParticles() base.camLens.setNearFar(CIGlobals.DefaultCameraNear, CIGlobals.DefaultCameraFar) base.transitions = CITransitions(loader) base.transitions.IrisModelName = "phase_3/models/misc/iris.bam" base.transitions.FadeModelName = "phase_3/models/misc/fade.bam" self.accept(self.inputStore.TakeScreenshot, ScreenshotHandler.takeScreenshot) #self.accept('u', render.setShaderOff) #self.accept('i', render.setShaderOff, [1]) #self.accept('o', render.setShaderOff, [2]) # Disabled oobe culling #self.accept('o', self.oobeCull) #self.accept('c', self.reportCam) self.taskMgr.add(self.__updateShadersAndPostProcess, 'CIBase.updateShadersAndPostProcess', 47) self.taskMgr.add(self.__update3DAudio, 'CIBase.update3DAudio', 59)
def create(self): """ Creates this pipeline """ self.debug("Setting up render pipeline") if self.settings is None: self.error("You have to call loadSettings first!") return self.debug("Analyzing system ..") SystemAnalyzer.analyze() self.debug("Checking required Panda3D version ..") SystemAnalyzer.checkPandaVersionOutOfDate(01, 12, 2014) # Mount everything first self.mountManager.mount() # Store globals, as cython can't handle them self.debug("Setting up globals") Globals.load(self.showbase) Globals.font = loader.loadFont("Data/Font/SourceSansPro-Semibold.otf") Globals.font.setPixelsPerUnit(25) # Setting up shader loading BetterShader._DumpShaders = self.settings.dumpGeneratedShaders # We use PTA's for shader inputs, because that's faster than # using setShaderInput self.temporalProjXOffs = PTAInt.emptyArray(1) self.cameraPosition = PTAVecBase3f.emptyArray(1) self.motionBlurFactor = PTAFloat.emptyArray(1) self.lastMVP = PTALMatrix4f.emptyArray(1) self.currentMVP = PTALMatrix4f.emptyArray(1) self.currentShiftIndex = PTAInt.emptyArray(1) # Initialize variables self.camera = self.showbase.cam self.size = self._getSize() self.cullBounds = None # For the temporal reprojection it is important that the window width # is a multiple of 2 if self.settings.enableTemporalReprojection and self.size.x % 2 == 1: self.error( "The window has to have a width which is a multiple of 2 " "(Current: ", self.showbase.win.getXSize(), ")") self.error( "I'll correct that for you, but next time pass the correct " "window size!") wp = WindowProperties() wp.setSize(self.showbase.win.getXSize() + 1, self.showbase.win.getYSize()) self.showbase.win.requestProperties(wp) self.showbase.graphicsEngine.openWindows() # Get new size self.size = self._getSize() # Debug variables to disable specific features self.haveLightingPass = True # haveCombiner can only be true when haveLightingPass is enabled self.haveCombiner = True self.haveMRT = True # Not as good as I want it, so disabled. I'll work on it. self.blurEnabled = False self.debug("Window size is", self.size.x, "x", self.size.y) self.showbase.camLens.setNearFar(0.1, 50000) self.showbase.camLens.setFov(90) self.showbase.win.setClearColor(Vec4(1.0, 0.0, 1.0, 1.0)) # Create GI handler if self.settings.enableGlobalIllumination: self._setupGlobalIllumination() # Create occlusion handler self._setupOcclusion() if self.settings.displayOnscreenDebugger: self.guiManager = PipelineGuiManager(self) self.guiManager.setup() # Generate auto-configuration for shaders self._generateShaderConfiguration() # Create light manager, which handles lighting + shadows if self.haveLightingPass: self.lightManager = LightManager(self) self.patchSize = LVecBase2i(self.settings.computePatchSizeX, self.settings.computePatchSizeY) # Create separate scene graphs. The deferred graph is render self.forwardScene = NodePath("Forward-Rendering") self.transparencyScene = NodePath("Transparency-Rendering") self.transparencyScene.setBin("transparent", 30) # We need no transparency (we store other information in the alpha # channel) self.showbase.render.setAttrib( TransparencyAttrib.make(TransparencyAttrib.MNone), 100) # Now create deferred render buffers self._makeDeferredTargets() # Create the target which constructs the view-space normals and # position from world-space position if self.occlusion.requiresViewSpacePosNrm(): self._createNormalPrecomputeBuffer() if self.settings.enableGlobalIllumination: self._creatGIPrecomputeBuffer() # Setup the buffers for lighting self._createLightingPipeline() # Setup combiner for temporal reprojetion if self.haveCombiner and self.settings.enableTemporalReprojection: self._createCombiner() if self.occlusion.requiresBlurring(): self._createOcclusionBlurBuffer() self._setupAntialiasing() if self.blurEnabled: self._createDofStorage() self._createBlurBuffer() # Not sure why it has to be 0.25. But that leads to the best result aspect = float(self.size.y) / self.size.x self.onePixelShift = Vec2(0.125 / self.size.x, 0.125 / self.size.y / aspect) * self.settings.jitterAmount # Annoying that Vec2 has no multliply-operator for non-floats multiplyVec2 = lambda a, b: Vec2(a.x * b.x, a.y * b.y) if self.antialias.requiresJittering(): self.pixelShifts = [ multiplyVec2(self.onePixelShift, Vec2(-0.25, 0.25)), multiplyVec2(self.onePixelShift, Vec2(0.25, -0.25)) ] else: self.pixelShifts = [Vec2(0), Vec2(0)] self.currentPixelShift = PTAVecBase2f.emptyArray(1) self.lastPixelShift = PTAVecBase2f.emptyArray(1) self._setupFinalPass() self._setShaderInputs() # Give the gui a hint when the pipeline is done loading if self.settings.displayOnscreenDebugger: self.guiManager.onPipelineLoaded() # add update task self._attachUpdateTask()
def apply(self, nodePath): attrib = TransparencyAttrib.make(self.get_panda_transparency()) nodePath.setAttrib(attrib)
class ClipState(IntEnum): Off = 0 Drawing = 1 Drawn = 2 MovingPoint1 = 3 MovingPoint2 = 4 MovingPoint3 = 5 class ClipSide(IntEnum): Both = 0 Front = 1 Back = 2 PlaneVis3DState = RenderState.make( ColorAttrib.makeFlat(Vec4(0, 1, 1, 0.5)), TransparencyAttrib.make(TransparencyAttrib.MAlpha), CullFaceAttrib.make(CullFaceAttrib.MCullNone) ) PlaneVis2DState = RenderState.make( ColorAttrib.makeFlat(Vec4(0, 1, 1, 1)), CullBinAttrib.make("fixed", LEGlobals.BoxSort), CullFaceAttrib.make(CullFaceAttrib.MCullNone) ) # Draws the clip plane lines and move handles in each 2D viewport class ClipToolViewport2D: def __init__(self, tool, vp): self.tool = tool self.vp = vp
def getColorAttributesFromModel(model): # Calculate the net transformation transform = model.getNetTransform() transformMat = transform.getMat() areas = [] rgbColors = [] textures = [] transparencies = [] for nodePath in model.findAllMatches('**/+GeomNode'): geomNode = nodePath.node() for n in range(geomNode.getNumGeoms()): state = geomNode.getGeomState(n) geom = geomNode.getGeom(n) area = getSurfaceAreaFromGeom(geom, transformMat) if state.hasAttrib(TextureAttrib.getClassType()): # Get color from texture texAttr = state.getAttrib(TextureAttrib.getClassType()) tex = texAttr.getTexture() # Load texture image from file and compute average color texFilename = str(tex.getFullpath()) img = scipy.ndimage.imread(texFilename) texture = os.path.splitext(os.path.basename(texFilename))[0] #TODO: handle black-and-white and RGBA texture assert img.dtype == np.uint8 assert img.ndim == 3 and img.shape[-1] == 3 rgbColor = (np.mean(img, axis=(0,1)) / 255.0).tolist() rgbColors.append(rgbColor) transparencies.append(False) areas.append(area) textures.append(texture) elif state.hasAttrib(ColorAttrib.getClassType()): colorAttr = state.getAttrib(ColorAttrib.getClassType()) if (colorAttr.getColorType() == ColorAttrib.TFlat or colorAttr.getColorType() == ColorAttrib.TOff): # Get flat color color = colorAttr.getColor() isTransparent = False if isinstance(color, LVecBase4f): rgbColor= [color[0], color[1], color[2]] alpha = color[3] if state.hasAttrib(TransparencyAttrib.getClassType()): transAttr = state.getAttrib(TransparencyAttrib.getClassType()) if transAttr.getMode() != TransparencyAttrib.MNone and alpha < 1.0: isTransparent = True elif alpha < 1.0: isTransparent = True elif isinstance(color, LVecBase3f): rgbColor= [color[0], color[1], color[2]] else: raise Exception('Unsupported color class type: %s' % (color.__class__.__name__)) rgbColors.append(rgbColor) transparencies.append(isTransparent) areas.append(area) textures.append(None) else: # Get colors from vertex data verAreas, verRgbColors, vertransparencies = getColorAttributesFromVertexData(geom, transformMat) areas.extend(verAreas) rgbColors.extend(verRgbColors) transparencies.extend(vertransparencies) textures.extend([None,]*len(vertransparencies)) areas = np.array(areas) areas /= np.sum(areas) return areas, rgbColors, transparencies, textures
def setPreviewState(self): self.state3D = self.state3D.setAttrib(TransparencyAttrib.make(True)) self.state3D = self.state3D.setAttrib(ColorScaleAttrib.make(Vec4(1, 1, 1, PreviewAlpha))) self.state2D = self.state2D.setAttrib(ColorAttrib.makeFlat(LEGlobals.PreviewBrush2DColor))