1- # Panda3D off-screen rendering example
1+ # CEF off-screen rendering using the Panda3D game engine:
22# http://www.panda3d.org/
33
4- # You need panda3D runtime compatible with python 2.7, the stable version (1.7.2)
5- # comes with python 2.6, so you will have to compile it yourself
6- # or download 1.8.0 sdk (unstable) which comes with python 2.7.
4+ # You need panda3D runtime that is compatible with python 2.7,
5+ # version 1.8.0 comes by default with python 2.7.
76
8- # In panda3D version 1.8.0 api has changed, this code works with version 1.8.0,
9- # to make it work with 1.7.2 slight changes will be required.
10-
11- # To use custom python (not the one provided with the SDK) create a "panda.pth"
12- # file inside your copy of python, containing the path of the panda directory
13- # and the bin directory within it on separate lines, for example:
7+ # To use custom python (not the one provided with the SDK)
8+ # create a "panda.pth" file inside your copy of python, in
9+ # this file put paths to panda & bin directory on separate,
10+ # for example:
11+ #
1412# c:\Panda3D-1.8.0
1513# c:\Panda3D-1.8.0\bin
14+ #
1615# This will enable your copy of python to find the panda libraries.
1716
1817import platform
1918if platform .architecture ()[0 ] != "32bit" :
20- raise Exception ("Architecture not supported: %s" % platform .architecture ()[0 ])
19+ raise Exception ("Unsupported architecture: %s" % (
20+ platform .architecture ()[0 ]))
2121
2222import sys
2323if sys .hexversion >= 0x02070000 and sys .hexversion < 0x03000000 :
3232from direct .showbase .DirectObject import DirectObject
3333from direct .task import Task
3434from math import pi , sin , cos
35- from direct .gui .OnscreenImage import OnscreenImage
3635
3736class World (DirectObject ):
3837
3938 browser = None
39+ texture = None
4040
4141 def __init__ (self ):
4242
@@ -48,98 +48,69 @@ def __init__(self):
4848
4949 windowHandle = base .win .getWindowHandle ().getIntHandle ()
5050
51- # image = OnscreenImage("wxpython.png", pos = Vec3(0,0,0))
52- # image.setImage("panda3d_.jpg")
53-
54- # from panda3d.core import PTAUchar
55-
56- # tex = Texture()
57- # tex.setup2dTexture(512, 512, Texture.CMOff, Texture.FRgba)
58- # tex.setRamImage(tex2.getRamImage())
59-
60- # or:
61-
62- # tex = Texture()
63- # tex.setup2dTexture()
64- # tex.load()...?
65- # tex.read("wxpython.png")
66-
67- self .tex = Texture ()
68- self .tex .setup2dTexture (400 , 300 , Texture .CMOff ,
51+ self .texture = Texture ()
52+ self .texture .setup2dTexture (400 , 300 , Texture .CMOff ,
6953 Texture .FLuminanceAlpha )
7054
71- cm = CardMaker ("browser2d" )
72- cm .setFrame (- 0.75 ,.75 ,- 0.75 ,0.75 )
73- card = render2d .attachNewNode (cm .generate ())
74- card .setTexture (self .tex )
55+ cardMaker = CardMaker ("browser2d" )
56+ cardMaker .setFrame (- 0.75 ,.75 ,- 0.75 ,0.75 )
57+ card = render2d .attachNewNode (cardMaker .generate ())
58+ card .setTexture (self .texture )
7559 card .setHpr (0 , 0 , 5 )
7660
7761 windowInfo = cefpython .WindowInfo ()
7862 windowInfo .SetAsOffscreen (windowHandle )
7963 self .browser = cefpython .CreateBrowserSync (
8064 windowInfo , browserSettings = {}, navigateURL = "cefsimple.html" )
81- self .browser .SetClientHandler (ClientHandler (self .browser , self .tex ))
65+ self .browser .SetClientHandler (
66+ ClientHandler (self .browser , self .texture ))
8267 self .browser .SetSize (cefpython .PET_VIEW , 400 , 300 );
8368
8469 taskMgr .add (self .messageLoop , "CefMessageLoop" )
8570
86- # python: bytearray(), memoryview() (buffer in python < 3)
87- # mode = "L", "RGBX", "RGBA", and "CMYK"
88- # image = Image.frombuffer(mode="RGBA", size=(w,h), buffer, "raw", "RGBA", 0, 1)
89- # image.save("panda3D_buffer.png", "PNG")
90-
9171 def messageLoop (self , task ):
92- # print("messageLoop()")
9372 cefpython .SingleMessageLoop ()
94- # Force more calls to OnPaint():
95- # self.browser.GetMainFrame().ExecuteJavascript("document.body.innerHTML += '<b>asd</b>'")
9673 return Task .cont
9774
9875 def spinCameraTask (self , task ):
99-
10076 angleDegrees = task .time * 6.0
10177 angleRadians = angleDegrees * (pi / 180.0 )
10278 camera .setPos (20 * sin (angleRadians ), - 20.0 * cos (angleRadians ), 3 )
10379 camera .setHpr (angleDegrees , 0 , 0 )
10480 return Task .cont
10581
10682class ClientHandler :
107-
10883 browser = None
109- tex = None
84+ texture = None
11085
111- def __init__ (self , browser , tex ):
86+ def __init__ (self , browser , texture ):
11287 self .browser = browser
113- self .tex = tex
88+ self .texture = texture
11489
11590 def OnPaint (self , browser , paintElementType , dirtyRects , buffer ):
116- print ("OnPaint()" )
117- print ("paintElementType: %s" % paintElementType )
118- print ("dirtyRects: %s" % dirtyRects )
119-
12091 (width , height ) = self .browser .GetSize (paintElementType )
121-
122- print ("buffer.GetIntPointer(): %s" % buffer .GetIntPointer ())
123- print ("width, height = %d, %d" % (width , height ))
124-
125- print ("len(buffer.GetString()): %s" % len (buffer .GetString ()))
126- print ("type: %s" % type (buffer .GetString ()))
127-
128- img = self .tex .modifyRamImage ()
129- img .setData (buffer .GetString (origin = "bottom-left" , mode = "bgra" ))
130-
131- #arrayBuffer = PTAUchar.emptyArray(0)
132- #arrayBuffer.setData(buffer.GetString())
133- #self.tex.setRamImage(CPTAUchar(arrayBuffer), Texture.CMOff)
134-
135- #image = Image.fromstring("BGRA", (width, height),
136- # buffer.GetString(), "raw", "BGRA")
137-
138- #self.tex.setRamMipmapPointerFromInt(
139- # buffer.GetIntPointer(), 0, width*height*4)
92+ img = self .texture .modifyRamImage ()
93+ img .setData (buffer .GetString (mode = "bgra" , origin = "bottom-left" ))
94+
95+ def OnLoadEnd (self , browser , frame , httpStatusCode ):
96+ return
97+ self ._saveImage ()
98+
99+ def _saveImage (self ):
100+ try :
101+ from PIL import Image
102+ except :
103+ print ("PIL library not available, can't save image" )
104+ return
105+ (width , height ) = self .browser .GetSize (cefpython .PET_VIEW )
106+ buffer = self .browser .GetImage (cefpython .PET_VIEW , width , height )
107+ image = Image .fromstring (
108+ "RGBA" , (width ,height ),
109+ buffer .GetString (mode = "rgba" , origin = "top-left" ),
110+ "raw" , "RGBA" , 0 , 1 )
111+ image .save ("panda3d_image.png" , "PNG" )
140112
141113if __name__ == "__main__" :
142-
143114 sys .excepthook = cefpython .ExceptHook
144115 settings = {
145116 "log_file" : cefpython .GetRealPath ("debug.log" ),
0 commit comments