Archive for August, 2009

The Browser plugin and its side-benefits

Sunday, August 23rd, 2009 by drwr

Most people know that there’s a project underway to build a browser plugin for Panda3D. I’ve been working hard on that project for the past several weeks, and now it’s nearing completion, though there’s still more work to go. We’ll be targeting 1.7.0, or at least 1.7.1, with the first release of this effort.

I thought this would be a good time to clarify what, precisely, Panda will be getting as a result of all this.

Browser plugin

First, there’s the obvious: you’ll be able to run your Panda3D application as an embedded window in a browser. Simply embedding a Panda3D window in a browser is technically very easy; we had this working within a couple of days of starting the project. We can run on any major browser on any supported Panda3D platform: IE on Windows, or Firefox on Windows, Mac, and Linux, not to mention Safari, Chrome, Opera, and probably some of the more fiddly browsers that I haven’t tested yet. On every browser, and on every platform, it uses the full hardware capabilities of your graphics card, and runs at full frame rate; there’s no need to be limited to software rendering. (There may be some small performance impact on certain platforms; but still, it’s way faster than software rendering.)

But then there’s the bigger question of how do you get your code onto a web page in the first place?

P3D files

To solve that, we need a tool to package up your application into a convenient downloadable file. We’ve had the rudiments of such a tool for a while now, but now it’s much more fleshed out. It works sort of like packpanda does, but instead of building an exe file, it packs your application into a p3d file. Think of this like Flash’s compiled swf file. Now, you can embed your p3d file in a web page with a few lines of HTML syntax, very similar to the way you embed a Flash swf file, and there’s your Panda3D application playing on a web page!

The p3d file contains everything you need to run your application. So why should we limit ourselves to running the p3d file only on a web browser? Let’s not. We will also distribute a standalone executable called panda3d.exe (or just panda3d on Mac and Linux), which can be used to run any p3d file on your desktop, no browser required.

Panda3D runtime

Look what’s happened! Suddenly, packpanda is no longer needed. Even if you never plan to embed your application on a web page, you can pack it into a p3d file, and distribute that file instead of the executable that packpanda would have produced. The p3d file is better than the exe file, because (a) it’s a lot smaller, containing your application only, and not another copy of Panda, and (b) it’s platform-independent (provided your application is written in pure Python).

Anyone who receives your p3d file can just double-click on the icon, and if they have installed the Panda3D runtime, no matter what OS they are running, it will launch and run with their local copy of panda3d.exe. If you want to distribute it to people who might not already have the Panda3D runtime, you can either direct them a link on to install it, or (if you are distributing a CD-Rom title, for instance) you can ship a copy of the Panda3D runtime along with the game and install it automatically. This is similar to the way games distribute the DirectX runtime from Microsoft. Users who receive your game on CD never need to know they are running Panda3D, even though they’re still running your game from a p3d file.

iPhone integration

It’s worth mentioning in passing, too, that when this browser plugin effort is done and I get a chance to revisit the iPhone support, then I’ll be able to write this Panda3D runtime for iPhone too, which will play the very same p3d files that play on your desktop. (Realistically, you’ll still need to tune the game to make it work well on the iPhone. Rendering performance and interface requirements are very different on the iPhone than they are on your PC. But the underlying technology will be the same, and some simple games may work unchanged on both platforms.) Unfortunately, Apple has funny rules about apps that run other apps, so this Panda3D runtime application won’t be permitted on a non-jailbroken iPhone. To stay within the legitimate channels, we’ll also provide a way to compile a p3d file into a true, completely standalone iPhone app that can be distributed via the App Store and installed onto any iPhone. (This will also require you to pay Apple’s $100 developer fee, of course.)

Web security

Now, back to the browser plugin, and the p3d files. I haven’t yet talked about security: one of the things that Flash and Java are particularly good at (and ActiveX is particularly bad at) is securely running untrusted code on a web page. All three of these technologies allow a program on a web page to immediately start running as soon as you visit the page. This has obvious implications for hackers installing malware onto your computer: while Flash and Java both go through hoops to make it impossible to do this, ActiveX basically opens up your whole computer to whatever program the web page wants to run. To deal with the fallout from this, Microsoft has had to gradually close down the automatic running of ActiveX applications, and now by default prompts you before running any ActiveX program for the first time.

Clearly, we’d rather be like Flash and Java in this regard than like ActiveX. Unfortunately, it turns out that Python doesn’t really lend itself to running untrusted code securely. Unlike Flash’s ActionScript, or Java, Python was never designed from the beginning to be a secure language, and it’s ridiculously full of holes. It’s nearly impossible to prevent Python code from doing pretty much whatever it likes with the computer’s hardware. Really. There are people on the internet who think Python can be made secure (I was once one of them), and a few people who think they’ve done it, but for the most part they’re mistaken.

There are a couple of possible solutions to this. For instance, we could run the Python interpreter entirely on a virtual machine. That’s hard, for a number of reasons, but it may get easier in the future, as the technology matures. Zope has a secure python that I think may actually achieve security, but it’s also hard to use, and I’m not sure what effect it has on runtime performance. Also, maybe IronPython holds promise, since that’s basically Python running within an already-secure environment; but again this is a major change from the CPython we’ve all come to know and love.

In lieu of any of those, I’ll be implementing something like the ActiveX security model, as lame as it is. What this means to you is that you will have to sign your p3d files when you put them on a website. (“Signing” a file means marking it with a unique key that identifies you as the developer. It’s OK if it’s anonymous; the only point is that it’s unique.) You can sign all of your p3d files with the same key. When the Panda3D web plugin comes across a p3d file signed with a new key it doesn’t recognize, it will offer the user a choice of whether to approve that key before it runs the application. If the user approves the key–meaning he gives you permission to run your code on his machine–then it will run the p3d file, and it will remember the user’s approval for future p3d files signed with the same key. This is basically the same kind of approval the user has to give for downloading an exe, so it doesn’t really interfere with distribution of applications, though it does make it a little clumsy if you want to have your p3d file play automatically the first time someone comes to your website.

There are other possibilities for different security models down the road, but I think this will address the issue adequately for the short term.

JavaScript integration

Back to the good stuff. Running an app in a little box on a web page is fun for a while, but it doesn’t really buy you much unless it can interact with the web page around it.

To put this in context: Python and JavaScript are very similar languages; both support late binding, dynamic object creation, and duck typing. Panda is already pretty good at wrapping C++ objects for Python’s benefit; compared to that monstrosity, wrapping JavaScript’s objects is a warm summer breeze. So why not do it properly, and fully expose the entire JavaScript object space to direct manipulation by Python?

So, we do. The Panda3D plugin allows you to write Python code that looks like “document.getElementById(‘form’).greeting.value = ‘hello'”, which is of course changing a form value on the web page, using the JavaScript DOM model. But you’re writing it in Python. In fact, anything that JavaScript can do, your Python program can do too. And the reverse is true as well: we allow you to expose the Python objects of your choice to JavaScript, to allow the web page to directly poke values into your application, or even call your Python methods!

This means you can easily integrate your Panda3D web program with any other web programs, written in JavaScript or any other web-supported language. For instance, I’ve provided a demo page that illustrates Panda3D interacting with Flash on the same page together, sending objects back and forth between Panda and Flash. When the plugin is more finished, I’ll provide this demo page and others for general inspection.

Package tool

There’s still more involved here. Packaging up your application into a single p3d file is all well and good for small applications, but what about really big apps like MMO’s, to which Panda3D owes its original raison d’être? Your users aren’t going to want to download a 200 MB p3d file every time they want to play. So, we need a system for packaging up smaller pieces of code, and downloading them individually, and/or sharing these pieces among different applications.

Enter the general package system. The same tool that can create p3d files can also build general packages: collections of Python code, compiled extension modules, and models, that aren’t an application per se, but can be requested by an application at runtime and downloaded on demand. Now when your app gets big, you have two choices: you can bundle it into one monolithic p3d file, and let the user download it all up front; or you can create one small p3d file that the user downloads first to get into the game–which might be no more than the title screen–and then you can strategically download the rest of the code in its various packages while the user continues to play the part(s) you’ve downloaded.

The package system will also automatically integrate with Panda’s built-in patchfile mechanism, allowing you to provide updates without forcing your users to completely re-download the entire application.

Also, we can use this same package system to provide several extension libraries, like pygame or wx, things which aren’t strictly part of Panda but which many applications will want to take advantage of.

You can also, of course, load models and such directly from an arbitrary URL. But you can do that today, using the vfs-mount-url Config.prc setting; that’s not a new feature of Panda (though it does take on new relevance in a web-based setting).

Panda3D versions

We haven’t talked about different versions of Panda yet. Here’s where it gets good: each p3d file knows the version of Panda3D that was used to produce it, and will only attempt to run with that same version of Panda. But the Panda3D runtime is itself version-independent. When you run a particular p3d file, the Panda3D runtime will figure out what version of Panda is required. If that version isn’t already installed on the user’s machine, it will go and download it first. It’s the job of the Panda3D runtime to manage these different versions of Panda, and to keep them all separate from each other; and it does this automatically, without the user even needing to know that it’s happening. In fact, you can even run two different versions of Panda at the same time on the same web page.

This means that once you, or any user, has installed the Panda3D runtime, you don’t need to worry about updating it when a new version of Panda comes along. It automatically updates itself as needed. This is true for the standalone panda3d.exe as well as for the browser plugin. (Every once in a while there may be an update to the runtime itself, which will require an explicit update by the user. But basic upgrades of Panda3D or any of its packages won’t require this.)

Note that the Panda3D runtime will cache all of these downloaded packages on the user’s hard disk. There has to be a limit to the amount of space Panda consumes, so the runtime will have to manage this space and automatically remove old, unused packages and versions. But the space used can be quite large by web browser standards (disks today are large enough to store hundreds of megabytes tucked away in a corner), and there’s no reason to cram all of this in the web browser’s relatively tiny cache directory. Even still, if you need more space for your app than Panda normally provides, you can take it–remember, the user has given your app permission. :)

We’ll also provide a webpage that the user can visit to manage his/her Panda3D installation, monitoring cache files and such, and tweaking global config files to his/her liking.

New Shader System

Tuesday, August 11th, 2009 by rdb

Hi all,

You’ll be pleased to know that I’ve made some big changes to the shader system for the upcoming 1.7.0 release. The new features include:

  • GLSL support (OpenGL only,  of course) and also GLSL ES (OpenGL ES only)
  • Support for separate vertex/fragment/etc programs
  • Support for structs in Cg shaders
  • Geometry shaders for Cg and GLSL (for Cg, this was provided by Schell Games)

And some more stuff. In the future, we hope to have support for CgFX as well. Maybe for 1.8 or so. Oh well, in the meantime you can watch this cute panda explode using a geometry shader.