Panda3D 1.9 runtime distribution - please test!

OK, I tested the correction regarding the xml.etree.ElementTree import problem and it perfectly works.

Thanks rdb!

Actually, I’ve subsequently encountered what appears to be the same issue in a Flash game–it may well be that the problem is on my side. My apologies, if so!

Ah, oops, sorry for not doing so in the first place! ^^;

The shaders are in Cg. My SDK is the 1.10 version, I believe; I’m not sure when last I tried the 1.9 version. Either way, I don’t think that I’ve encountered this issue in the SDK, that I recall.

It might be worth mentioning that these are the same shaders with which I had trouble referencing one shader from another via a “#include” statement; I do believe that I have them set to extract themselves, and a quick check indicates that they are doing so.

I ran a quick test using the .p3d file under Ubuntu, first copying the shaders to an appropriate directory, and they seemed to work correctly.

Looking at the output, it looks as though it’s somehow ending up with either zero or negative values for when calculating the lighting of a pixel. Unfortunately, the shader has a few places in which something like that might be creeping in. I might try a few experimental shaders in an attempt to determine which element is introducing this issue.

[edit]
All right, a quick test seems to indicate that the problem lies in the calculation of light-level based on surface normal and light-direction. As before, the problem seems to occur in an installed distributable build under Windows 10; I haven’t yet tested with Windows 7, I’m afraid. This is my test-shader:

//Cg

void vshader(
    in float4 vtx_position: POSITION,
    in float3 vtx_normal: NORMAL,
    in uniform float4x4 mat_modelproj,
    out float4 l_position: POSITION,
    out float3 l_normal: TEXCOORD1
)
{
    l_position = mul(mat_modelproj, vtx_position);
    l_normal = vtx_normal.xyz;
}

void fshader(
    in float3 l_normal: TEXCOORD1,
    out float4 o_color: COLOR0
)
{
    float3 lightDir = float3(-0.704, -0.704, 0.704);
    float light = max(0, dot(l_normal, lightDir));
    o_color = float4(light, light, light, 1);
}

(I realise that–if I’m not much mistaken–simply using the value in “vtx_normal” results in the object’s transformation not being taken into account; that shouldn’t be a problem here however, I wouldn’t imagine.)

flavio: are you using the Panda3D Runtime 1.0.4 or newer? Are you on 32-bit or 64-bit Windows? When running the .p3d from the console, try:

path\to\panda3d.exe -p win_i386 something.p3d

Thaumaturge: in the SDK, please try with “basic-shaders-only” set to true and false; it makes a significant difference in how Cg shaders are compiled and used.

It does matter whether you grab the 1.10 (git: master) or 1.9 (git: release/1.9.x) branch, though, since 1.10 has some significant changes to Cg support under OpenGL.

Could you maybe do a bit more testing to see if the input vertex attributes are correct? Just write out (l_normal*0.5+0.5) to o_color both SDK and and see if you’re getting the same results.

Another thing to try is switching the vertex inputs (not outputs!) to use ATTR0 and ATTR1 semantics instead of POSITION and NORMAL, respectively. This should be tried both with basic-shaders-only true and false.

Please also mention whether you are using NVIDIA/AMD/Intel.

Before I attend to the shader issue, I seem to have found another problem: Bullet appears to be broken in 1.9, whether using the SDK or the distributable.

From what I’ve seen, it appears that rigid-bodies don’t work, while ray-tests do: When testing my game, the player’s movement (which uses ray-tests, as I recall) seems to work properly. On the other hand, collisions between rigid bodies (such as between the player and a wall) seem to no longer be detected. A basic Bullet test-program failed to so much as get a rigid body to fall under gravity.

[edit]
Thinking about it, could it be that it’s the “doPhysics” method, or something that it calls, that’s broken? That might explain rigid bodies not updating responding to collisions, while ray-tests–which I imagine don’t rely on the “doPhysics” method–continue to function.
[/edit]

All seems well when using the 1.10 SDK, however, both in my game and in the test-program.

Ah, right: The development machine (on which I’m running through the SDK) has an ATI Mobility Radeon HD 3650, while the test machine (on which I’m installing the distributable builds) has an NVIDIA GeForce GT 525M.

In the SDK, this appears to make no real difference.

In the installed, distributable build, however, the version running with “basic-shaders-only” enabled works!

(Well, the simple test-program works; I haven’t yet tested my game’s shaders this way.)

Ah, fair enough–I’ve now uninstalled the 1.10 SDK and installed the 1.9 SDK (as taken from the download page), I believe.

I presume that you mean “the same results whether using ‘basic-shaders-only’ or not”? If so, I see no difference, both when running via the SDK and in an installed distributable build.

Panda really doesn’t seem to like that, even in the SDK! 0_0

In case I misunderstood you, let me specify that my change was as follows: in the vertex shader, I changed the following:

void vshader(
    in float4 vtx_position: POSITION,
    in float3 vtx_normal: NORMAL,
// More shader code here...

to this:

void vshader(
    in float4 vtx_position: ATTR0,
    in float3 vtx_normal: ATTR1,
// More shader code here...

Doing so with “basic-shaders-only” disabled resulted in a black window, and the following message:

:shader(error): Varying parameter vtx_position : ATTR0 (bound to resource ATTR0) is invalid!
:shader(error): Varying parameter vtx_normal : ATTR1 (bound to resource ATTR1) is invalid!

When “basic-shaders-only” is enabled, the window is still black, but the following is repeatedly printed into the console:

:display:gsg:glgsg(error): Unable to bind normal to ATTR1

Since this didn’t work in the SDK, I didn’t attempt a distributable build.

Very possible, although I thought I had fixed that for the runtime distribution build. Does applying the known workaround for this issue (specifying the parameters explicitly rather than relying on the default parameters) work?

OK, so this must be one of the things I had fixed in 1.10. I suggest leaving basic-shaders-only on as a workaround.

I presume you mean the 1.9 SDK? If so, then OK, not too surprising - I think the Cg shader support in 1.10 handles ATTR# correctly.

Thanks for testing! I presume you have a workaround now with basic-shaders-only until 1.10 comes around (or until I backport the 1.10 fixes back to 1.9).

Of course, I’ll continue to point out that Cg is no longer supported by NVIDIA and GLSL is the recommended path forward for Panda3D. Includes (via the “#pragma include” syntax) will also work correctly in GLSL without needing explicit extraction.

Hi rdb, sorry for the lack of information. It works with the runtime (it is a 1.0.4 runtime on a 32-bit Windows installation), but it gives that error when I launch the game that I’ve built with pdeploy.

Ah, further testing seems to indicate that it does work in the distributable build, but not in the SDK. It looks as though I have a separate problem (quite likely on my end, rather than Panda’s) that I think that I had taken as confirmation that Bullet wasn’t working in the distributable build, having run the minimal tests only in the SDK.

The workaround does indeed seem to fix the problem! Thank you for mentioning the workaround–I think that I’d previously seen mention of it, but had subsequently forgotten.

Aah, fair enough–indeed, I don’t think that I tried it under 1.10.

I’m glad to help–and of course getting 1.9 working well aids me anyway. Conversely, thank you for all of your work in fixing these issues! :slight_smile:

Indeed, that would seem to be the case. :slight_smile:

Heh, indeed. Honestly, this set of shaders isn’t intended to go beyond a test-scenario that I’ve put together for my game, and as such I’m somewhat disinclined to port all of them to GLSL. (I don’t recall a reason for having written them in CG beyond my happening to have picked that language up first (for whatever reason).) I very much intend to use GLSL for the main game, and indeed even have a few initial passes at those shaders already written.

@flavio: In 1.9, the platform string for 32-bit Windows has been changed from “win32” to “win_i386”. It seems that pdeploy is still spitting out an installer for “win32”. If you let it generate an installer for “win_i386” instead (using “-P win_i386” argument to pdeploy), does it work then?

On a sidenote, I’ve just updated the authorization dialog that shows up the first time you are running a Panda app in the browser to have localized text strings. Let me know if you see it in the wrong language, or something of the sort.

Thank you very much, it works now! :slight_smile:

Hi rdb

It seems that the ‘uuid’ module causes problem when executing a .p3d file.

Indeed, these simple lines:

from uuid import uuid4
print uuid4()

systematically cause an exception (R6034) when I execute the p3d that was previously generated. Surprisingly, the code is actually working but a nasty pop up window opens up and shows this exception (Win7 / x64).

I even purged the cache once or twice to make sure it was not a problem relating to the previous one. The result was the same.

Many thanks!

Yikes! Seems to be some issue with the way Python’s uuid module calls into Windows’ system functions.

Hmm, you can probably use this instead:

from uuid import UUID

def uuid4():
    try:
        import os
        return UUID(bytes=os.urandom(16), version=4)
    except:
        import random
        bytes = [chr(random.randrange(256)) for i in range(16)]
        return UUID(bytes=bytes, version=4)

The hardware skinning works now in p3d files (the ast module also)… at least in glsl shaders, don’t know about other options.

I strongly encourage everyone to try it, because I’m really amazed by the performance boost it gives on my test machine.

I have a actor that has over 40k verts (in the egg file, half of that in the modeling package, never tested what pstats reports) in the highest lod - with the skinning done on the CPU I get a framerate just above 30fps, with the same done on the GPU I get over 200fps.

I seem to have found another issue, although it’s possible that I’m doing something wrong, and it’s possible that the issue is not new to 1.9.

Simply put, I don’t seem to be able to open Multifiles in an installed build under Windows 10; no errors are apparent to me in the log file.

When running via the SDK under Ubuntu all seems to work as expected.

The following test-program displays the behaviour in question:

from direct.interval.IntervalGlobal import *
from direct.task import Task
from direct.showbase.ShowBase import ShowBase
from panda3d.core import Vec4, Filename, Multifile, VirtualFileSystem, TextNode

from direct.gui.OnscreenText import OnscreenText
from direct.gui.DirectGui import *

import os
from direct.stdpy.file import *

from ThirdParty.appdirs import *

PATH_SAVE = user_data_dir("Mew", "Thaumaturge") + "/"
MF_NAME = "mew.mf"

class GameFramework(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        base.disableMouse()
        
        base.win.setClearColor(Vec4(0, 0, 0, 1))
        
        base.exitFunc = self.quit
        
        quitBtn = DirectButton(text = "Quit", command = base.userExit,
                                scale = 0.07, parent = aspect2d)
        quitBtn.setPos(render2d, 0, 0, -0.9)
        
        self.text = TextNode("text")
        self.text.setWordwrap(25.0)
        self.text.setAlign(TextNode.ACenter)
        self.text.setTextColor(0, 1, 0.7, 1)
        self.textNP = aspect2d.attachNewNode(self.text)
        self.textNP.setScale(0.07)
        self.textNP.setZ(0.2)
        
        self.accept("s", self.save)
        self.accept("l", self.load)
        
        if not os.path.exists(PATH_SAVE):
            os.makedirs(PATH_SAVE)
            self.text.setText("Save directory " + PATH_SAVE + " not found; creating it.")
        else:
            self.text.setText("Save directory " + PATH_SAVE + " found.")
    
    def save(self):
        itemFile = "mew.dat"
        
        file = PATH_SAVE + itemFile
        
        try:
            fileObj = open(file, "w")
            fileObj.write("Kittens!\n")
        except IOError, e:
            self.text.setText(str(e))
        else:
            if fileObj is not None:
                fileObj.close()
        
        fName = Filename(file)
        fName.setText()
        
        mf = Multifile()
        if mf.openReadWrite(PATH_SAVE + MF_NAME):
            result = mf.addSubfile(itemFile, fName, 1)
            mf.close()
        
        os.remove(file)
        
        self.text.setText("Saved the file " + (PATH_SAVE + MF_NAME))
    
    def load(self):
        itemFile = "mew.dat"
        
        file = PATH_SAVE + itemFile
        
        savePrefix = "MountedSave/"
        
        fName = Filename(file)
        fName.setText()
        
        mf = Multifile()
        
        result = "Failed to load file! D:"
        if mf.openRead(PATH_SAVE + MF_NAME):
            vfs = VirtualFileSystem.getGlobalPtr()
            
            if vfs.mount(mf, PATH_SAVE + savePrefix, VirtualFileSystem.MFReadOnly):
                try:
                    result = None
                    fileObj = None
                    try:
                        fileObj = open(PATH_SAVE + savePrefix + itemFile, "r")
                        result = fileObj.readline()
                        result = "Loaded: " + result
                        self.text.setText(result)
                    except IOError, e:
                        self.text.setText(str(e))
                        raise
                    else:
                        if fileObj is not None:
                            fileObj.close()
                except IOError, e:
                    self.text.setText(str(e))
                vfs.unmount(mf)
            else:
                self.text.setText("Failed to mount save file: " + (PATH_SAVE + savePrefix))
                
            mf.close()
        else:
            self.text.setText("Failed to open Multifile: " + (PATH_SAVE + MF_NAME))
    
    def quit(self):
        print "Quitting"
        

    
gameFramework = GameFramework()
gameFramework.run()
    

To perform the test, run the program and press “s”, then “l”. The former should create a simple text file and save it in a Multifile, while the latter should open the Multifile, mount it into the Virtual File System, and read the text. The results of the operations should be presented via a TextNode: if the save succeeds, it should display "Saved the file " (where “” is the name of the Multifile being saved), while a successful load should display “Loaded: Kittens!” (“Kittens!” being the text saved into the file).

Based on my tests, the process of loading appears to be failing at “mf.openRead …”.

Note that the program uses “AppDirs” (for which I think that this is the appropriate link) to find an appropriate “user data directory” into which to save; if you want to test without this, just replace the value of “PATH_SAVE”, defined near the top of the file.

Hi rdb -

Sorry for my late reply to your suggestion and thanks.

Unfortunately, even these lines give me an exception (Runtime error R6034) when using packp3d:

import sys

try:
    from uuid import UUID
except:
    print "First exception"
sys.exit()

To be honest, this is now not critical for my code but just wanted to let you know about it.

Sorry, I must have overlooked this post somehow. I’m afraid I cannot reproduce this issue. The multifile loads just fine for me in the runtime environment.

Note that you can use this to get a location you might write your application data to:

Filename(Filename.getUserAppdataDirectory(), "Mew")

Hi rdb -

Just another question on the packaging system: I generated a .pyd file through Interrogate which perfectly works in a non packaged application.

In a p3d file, the packaging is working (need to start from the VS tools command line in order for the packer to use MS tools for the dependencies analysis) but at the execution, the application crashes. The message is that the generated pyd telling that it is not a valid Win32 dll.

I suspect that it should come from a mismatch between win32 and win64 binaries in the package (the pyd I generated is x64). So I tried to force the packer to be in x64 mode (“panda3d -P” tells me I am ‘win32’) by doing:

panda3d -p win_amd64 packp3d1.9.p3d -d Packing -o ZZZZ.p3d -r morepy -n pyd

The answer is:

Couldn't load C:\Users\YYYY\AppData\Local/Panda3D/coreapi/win_amd64/p3d_plugi
n.dll, error = 193
Unable to launch core API in C:\Users\YYYY\AppData\Local/Panda3D/coreapi/win_amd64/p3d_plugin.dll
Unable to load Panda3D plugin.

I checked that the file ‘p3d_plugin.dll’ is present in:
C:\Users\YYYY\AppData\Local\Panda3D\coreapi\win_amd64

One thing I note is that the displayed path is odd (Windows mode for the beginning and Filename mode at the path’s end) but I don’t know if it is relevant.

Is there anything I am not doing right or missing?

Thanks again for your help!

I think it’s erroring because you can’t load a 64-bit DLL into a 32-bit runtime process. Arguably this makes the -p option pretty useless, and we should instead ignore the -p setting when it’s loading the coreapi DLL.

Hmm, it’s really supposed to auto-detect whether you are on a 64-bit system, and select the win_amd64 build of Panda appropriately. A bit disturbing that that isn’t working. I’d like to see the log file of this attempt to see if it gives any clues why this isn’t working.
Perhaps you could try installing a 64-bit build of the runtime from here:
panda3d.org/download.php?pl … el&runtime

Since the plugin uses an optimized NDEBUG version of Panda3D, you may also have to recompile your module against the runtime libraries of Panda. I’m not 100% sure.

Many thanks rdb.

I installed the x64 runtime and the error has changed:

  File "VFSImporter", line 148, in load_module
  File "Packing\CrashTests.py", line 15, in <module>
  File "VFSImporter", line 122, in load_module
  File "VFSImporter", line 223, in _import_extension_module
ImportError: DLL load failed: specified procedure can not be found.
Failure on startup.

I include 4 versions of p3dcore.log:
0 & 1 (previous runtime version): (packaging (#0) and execution of the package(#1))
2 & 3(x64 runtime): (packaging (#2) and execution of the package(#3))
Logs_P3Dcore_log.zip (9.34 KB)

Could you try putting this in a config.prc file in your game directory, or a loadPrcFileData line before anything else?

show-dll-error-dialog 1

You may have to call this after setting it before it takes effect:

ConfigPageManager.getGlobalPtr().reloadImplicitPages()

Many thanks rdb.

Unfortunately, I added at the top of the file:

from panda3d.core import ConfigPageManager
from pandac.PandaModules import loadPrcFileData
loadPrcFileData('','show-dll-error-dialog 1')
ConfigPageManager.getGlobalPtr().reloadImplicitPages()

But no result (I understand a pop up window should open in case of issue when loading a DLL, but no window showed up).

I made several tests but the result is still the same.