mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 07:48:37 -04:00
Merge branch 'release/1.10.x'
This commit is contained in:
commit
b78b7be326
@ -185,16 +185,19 @@ from the Play Store. Many of the dependencies can be installed by running the
|
||||
following command in the Termux shell:
|
||||
|
||||
```bash
|
||||
pkg install python-dev termux-tools ndk-stl ndk-sysroot clang libvorbis-dev libopus-dev opusfile-dev openal-soft-dev freetype-dev harfbuzz-dev libpng-dev ecj4.6 dx patchelf aapt apksigner libcrypt-dev
|
||||
pkg install python ndk-sysroot clang bison freetype harfbuzz libpng eigen openal-soft opusfile libvorbis assimp libopus ecj dx patchelf aapt apksigner libcrypt openssl pkg-config
|
||||
```
|
||||
|
||||
Then, you can build and install the .apk right away using these commands:
|
||||
Then, you can build the .apk using this command:
|
||||
|
||||
```bash
|
||||
python makepanda/makepanda.py --everything --target android-21 --no-tiff --installer
|
||||
xdg-open panda3d.apk
|
||||
```
|
||||
|
||||
You can install the generated panda3d.apk by browsing to the panda3d folder
|
||||
using a file manager. You may need to copy it to `/sdcard` to be able to
|
||||
access it from other apps.
|
||||
|
||||
To launch a Python program from Termux, you can use the `run_python.sh` script
|
||||
inside the `panda/src/android` directory. It will launch Python in a separate
|
||||
activity, load it with the Python script you passed as argument, and use a
|
||||
|
@ -5,6 +5,7 @@ __all__ = ['Actor']
|
||||
from panda3d.core import *
|
||||
from panda3d.core import Loader as PandaLoader
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
from direct.showbase.Loader import Loader
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
|
||||
|
||||
@ -1886,6 +1887,9 @@ class Actor(DirectObject, NodePath):
|
||||
else:
|
||||
loaderOptions.setFlags(loaderOptions.getFlags() | LoaderOptions.LFReportErrors)
|
||||
|
||||
# Ensure that custom Python loader hooks are initialized.
|
||||
Loader._loadPythonFileTypes()
|
||||
|
||||
# Pass loaderOptions to specify that we want to
|
||||
# get the skeleton model. This only matters to model
|
||||
# files (like .mb) for which we can choose to extract
|
||||
|
@ -253,8 +253,9 @@ do_unpack_int64(const char *buffer) {
|
||||
((uint64_t)(unsigned char)buffer[4] << 32) |
|
||||
((uint64_t)(unsigned char)buffer[5] << 40) |
|
||||
((uint64_t)(unsigned char)buffer[6] << 48) |
|
||||
((int64_t)(signed char)buffer[7] << 54));
|
||||
((int64_t)(signed char)buffer[7] << 56));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -295,10 +296,9 @@ do_unpack_uint64(const char *buffer) {
|
||||
((uint64_t)(unsigned char)buffer[4] << 32) |
|
||||
((uint64_t)(unsigned char)buffer[5] << 40) |
|
||||
((uint64_t)(unsigned char)buffer[6] << 48) |
|
||||
((int64_t)(signed char)buffer[7] << 54));
|
||||
((uint64_t)(unsigned char)buffer[7] << 56));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCField;
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "dcSubatomicType.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
class DCFile;
|
||||
class DCClass;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
#else // WITHIN_PANDA
|
||||
|
||||
@ -81,6 +82,7 @@
|
||||
#define nassertr_always(condition, return_value) assert(condition)
|
||||
#define nassertv(condition) assert(condition)
|
||||
#define nassertv_always(condition) assert(condition)
|
||||
#define nassert_raise(message) {std::cerr << message << std::endl; abort();}
|
||||
|
||||
// Panda defines a special Filename class. We'll use an ordinary string
|
||||
// instead.
|
||||
@ -97,8 +99,10 @@ typedef std::string Filename;
|
||||
#define pvector std::vector
|
||||
#define pmap std::map
|
||||
#define pset std::set
|
||||
#define vector_uchar std::vector<unsigned char>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef std::ifstream pifstream;
|
||||
typedef std::ofstream pofstream;
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "dcbase.h"
|
||||
#include "primeNumberGenerator.h"
|
||||
#include "vector_uchar.h"
|
||||
|
||||
/**
|
||||
* This class generates an arbitrary hash number from a sequence of ints.
|
||||
|
@ -22,6 +22,8 @@ class Loader(DirectObject):
|
||||
notify = directNotify.newCategory("Loader")
|
||||
loaderIndex = 0
|
||||
|
||||
_loadedPythonFileTypes = False
|
||||
|
||||
class Callback:
|
||||
"""Returned by loadModel when used asynchronously. This class is
|
||||
modelled after Future, and can be awaited."""
|
||||
@ -149,8 +151,7 @@ class Loader(DirectObject):
|
||||
Loader.loaderIndex += 1
|
||||
self.accept(self.hook, self.__gotAsyncObject)
|
||||
|
||||
if ConfigVariableBool('loader-support-entry-points', True):
|
||||
self._loadPythonFileTypes()
|
||||
self._loadPythonFileTypes()
|
||||
|
||||
def destroy(self):
|
||||
self.ignore(self.hook)
|
||||
@ -158,7 +159,14 @@ class Loader(DirectObject):
|
||||
del self.base
|
||||
del self.loader
|
||||
|
||||
def _loadPythonFileTypes(self):
|
||||
@classmethod
|
||||
def _loadPythonFileTypes(cls):
|
||||
if cls._loadedPythonFileTypes:
|
||||
return
|
||||
|
||||
if not ConfigVariableBool('loader-support-entry-points', True):
|
||||
return
|
||||
|
||||
import importlib
|
||||
try:
|
||||
pkg_resources = importlib.import_module('pkg_resources')
|
||||
@ -171,6 +179,8 @@ class Loader(DirectObject):
|
||||
for entry_point in pkg_resources.iter_entry_points('panda3d.loaders'):
|
||||
registry.register_deferred_type(entry_point)
|
||||
|
||||
cls._loadedPythonFileTypes = True
|
||||
|
||||
# model loading funcs
|
||||
def loadModel(self, modelPath, loaderOptions = None, noCache = None,
|
||||
allowInstance = False, okMissing = None,
|
||||
|
@ -87,7 +87,7 @@ class Thread(ThreadBase):
|
||||
object. The wrapper is designed to emulate Python's own
|
||||
threading.Thread object. """
|
||||
|
||||
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
|
||||
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, daemon=None):
|
||||
ThreadBase.__init__(self)
|
||||
|
||||
assert group is None
|
||||
@ -99,7 +99,10 @@ class Thread(ThreadBase):
|
||||
name = _newname()
|
||||
|
||||
current = current_thread()
|
||||
self.__dict__['daemon'] = current.daemon
|
||||
if daemon is not None:
|
||||
self.__dict__['daemon'] = daemon
|
||||
else:
|
||||
self.__dict__['daemon'] = current.daemon
|
||||
self.__dict__['name'] = name
|
||||
|
||||
def call_run():
|
||||
|
@ -14,6 +14,7 @@ module, and so it is therefore layered on top of Panda's thread
|
||||
implementation. """
|
||||
|
||||
import sys as _sys
|
||||
import atexit as _atexit
|
||||
|
||||
from direct.stdpy import thread as _thread
|
||||
from direct.stdpy.thread import stack_size, _newname, _local as local
|
||||
@ -395,8 +396,12 @@ class Thread(_Verbose):
|
||||
# operation on/with a NoneType
|
||||
__exc_info = _sys.exc_info
|
||||
|
||||
# Set to True when the _shutdown handler is registered as atexit function.
|
||||
# Protected by _active_limbo_lock.
|
||||
__registered_atexit = False
|
||||
|
||||
def __init__(self, group=None, target=None, name=None,
|
||||
args=(), kwargs=None, verbose=None):
|
||||
args=(), kwargs=None, verbose=None, daemon=None):
|
||||
assert group is None, "group argument must be None for now"
|
||||
_Verbose.__init__(self, verbose)
|
||||
if kwargs is None:
|
||||
@ -405,7 +410,10 @@ class Thread(_Verbose):
|
||||
self.__name = str(name or _newname())
|
||||
self.__args = args
|
||||
self.__kwargs = kwargs
|
||||
self.__daemonic = self._set_daemon()
|
||||
if daemon is not None:
|
||||
self.__daemonic = daemon
|
||||
else:
|
||||
self.__daemonic = self._set_daemon()
|
||||
self.__started = False
|
||||
self.__stopped = False
|
||||
self.__block = Condition(Lock())
|
||||
@ -436,6 +444,14 @@ class Thread(_Verbose):
|
||||
self._note("%s.start(): starting thread", self)
|
||||
_active_limbo_lock.acquire()
|
||||
_limbo[self] = self
|
||||
|
||||
# If we are starting a non-daemon thread, we need to call join() on it
|
||||
# when the interpreter exits. Python will call _shutdown() on the
|
||||
# built-in threading module automatically, but not on our module.
|
||||
if not self.__daemonic and not Thread.__registered_atexit:
|
||||
_atexit.register(_shutdown)
|
||||
Thread.__registered_atexit = True
|
||||
|
||||
_active_limbo_lock.release()
|
||||
_start_new_thread(self.__bootstrap, ())
|
||||
self.__started = True
|
||||
@ -599,6 +615,9 @@ class Thread(_Verbose):
|
||||
assert not self.__started, "cannot set daemon status of active thread"
|
||||
self.__daemonic = daemonic
|
||||
|
||||
name = property(getName, setName)
|
||||
daemon = property(isDaemon, setDaemon)
|
||||
|
||||
# The timer class was contributed by Itamar Shtull-Trauring
|
||||
|
||||
def Timer(*args, **kwargs):
|
||||
@ -670,7 +689,7 @@ class _MainThread(Thread):
|
||||
class _DummyThread(Thread):
|
||||
|
||||
def __init__(self):
|
||||
Thread.__init__(self, name=_newname("Dummy-%d"))
|
||||
Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True)
|
||||
|
||||
# Thread.__block consumes an OS-level locking primitive, which
|
||||
# can never be used by a _DummyThread. Since a _DummyThread
|
||||
|
@ -141,16 +141,13 @@ typedef long Py_hash_t;
|
||||
|
||||
#if PY_VERSION_HEX < 0x03080000 && !defined(_PyObject_CallNoArg)
|
||||
INLINE PyObject *_PyObject_CallNoArg(PyObject *func) {
|
||||
static PyTupleObject empty_tuple = {PyVarObject_HEAD_INIT(nullptr, 0)};
|
||||
#ifdef Py_TRACE_REFS
|
||||
_Py_AddToAllObjects((PyObject *)&empty_tuple, 0);
|
||||
#endif
|
||||
return PyObject_Call(func, (PyObject *)&empty_tuple, nullptr);
|
||||
static PyObject *empty_tuple = PyTuple_New(0);
|
||||
return PyObject_Call(func, empty_tuple, nullptr);
|
||||
}
|
||||
# define _PyObject_CallNoArg _PyObject_CallNoArg
|
||||
#endif
|
||||
|
||||
#ifndef _PyObject_FastCall
|
||||
#if PY_VERSION_HEX < 0x03080000 && !defined(_PyObject_FastCall)
|
||||
INLINE PyObject *_PyObject_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs) {
|
||||
PyObject *tuple = PyTuple_New(nargs);
|
||||
for (Py_ssize_t i = 0; i < nargs; ++i) {
|
||||
|
@ -944,11 +944,12 @@ if (COMPILER=="GCC"):
|
||||
for pkg in MAYAVERSIONS:
|
||||
if (PkgSkip(pkg)==0 and (pkg in SDK)):
|
||||
if GetTarget() == 'darwin':
|
||||
LibName(pkg, "-Wl,-rpath," + SDK[pkg] + "/Maya.app/Contents/MacOS")
|
||||
LibName(pkg, "-Wl,-rpath,/Applications/Autodesk/" + pkg.lower() + "/Maya.app/Contents/MacOS")
|
||||
else:
|
||||
LibName(pkg, "-Wl,-rpath," + SDK[pkg] + "/lib")
|
||||
LibName(pkg, "-lOpenMaya")
|
||||
LibName(pkg, "-lOpenMayaAnim")
|
||||
LibName(pkg, "-lOpenMayaUI")
|
||||
LibName(pkg, "-lAnimSlice")
|
||||
LibName(pkg, "-lDeformSlice")
|
||||
LibName(pkg, "-lModifiers")
|
||||
@ -967,7 +968,8 @@ if (COMPILER=="GCC"):
|
||||
LibName(pkg, "-lDependEngine")
|
||||
LibName(pkg, "-lCommandEngine")
|
||||
LibName(pkg, "-lFoundation")
|
||||
LibName(pkg, "-lIMFbase")
|
||||
if pkg != "MAYA2020":
|
||||
LibName(pkg, "-lIMFbase")
|
||||
if GetTarget() != 'darwin':
|
||||
LibName(pkg, "-lOpenMayalib")
|
||||
else:
|
||||
@ -2612,7 +2614,13 @@ if not PkgSkip("PYTHON"):
|
||||
ConditionalWriteFile(GetOutputDir() + '/panda3d/__init__.py', p3d_init)
|
||||
|
||||
# Also add this file, for backward compatibility.
|
||||
ConditionalWriteFile(GetOutputDir() + '/panda3d/dtoolconfig.py', """
|
||||
ConditionalWriteFile(GetOutputDir() + '/panda3d/dtoolconfig.py', """\
|
||||
'''Alias of :mod:`panda3d.interrogatedb`.
|
||||
|
||||
.. deprecated:: 1.10.0
|
||||
This module has been renamed to :mod:`panda3d.interrogatedb`.
|
||||
'''
|
||||
|
||||
if __debug__:
|
||||
print("Warning: panda3d.dtoolconfig is deprecated, use panda3d.interrogatedb instead.")
|
||||
from .interrogatedb import *
|
||||
|
@ -106,6 +106,7 @@ MAYAVERSIONINFO = [("MAYA6", "6.0"),
|
||||
("MAYA2017","2017"),
|
||||
("MAYA2018","2018"),
|
||||
("MAYA2019","2019"),
|
||||
("MAYA2020","2020"),
|
||||
]
|
||||
|
||||
MAXVERSIONINFO = [("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0", "installdir", "maxsdk\\cssdk\\include"),
|
||||
@ -2803,7 +2804,7 @@ def SetupVisualStudioEnviron():
|
||||
elif not win_kit.endswith('\\'):
|
||||
win_kit += '\\'
|
||||
|
||||
for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763:
|
||||
for vnum in 10150, 10240, 10586, 14393, 15063, 16299, 17134, 17763, 18362:
|
||||
version = "10.0.{0}.0".format(vnum)
|
||||
if os.path.isfile(win_kit + "Include\\" + version + "\\ucrt\\assert.h"):
|
||||
print("Using Universal CRT %s" % (version))
|
||||
|
@ -701,10 +701,15 @@ if __debug__:
|
||||
# Put the .exe files inside the panda3d-tools directory.
|
||||
whl.write_file('panda3d_tools/' + file, source_path)
|
||||
|
||||
if basename.endswith('_bin'):
|
||||
# These tools won't be invoked by the user directly.
|
||||
continue
|
||||
|
||||
# Tell pip to create a wrapper script.
|
||||
funcname = basename.replace('-', '_')
|
||||
entry_points += '{0} = panda3d_tools:{1}\n'.format(basename, funcname)
|
||||
tools_init += '{0} = lambda: _exec_tool({1!r})\n'.format(funcname, file)
|
||||
|
||||
entry_points += '[distutils.commands]\n'
|
||||
entry_points += 'build_apps = direct.dist.commands:build_apps\n'
|
||||
entry_points += 'bdist_apps = direct.dist.commands:bdist_apps\n'
|
||||
|
@ -45,6 +45,10 @@
|
||||
|
||||
TypeHandle CocoaGraphicsWindow::_type_handle;
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#define NSAppKitVersionNumber10_14 1671
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -1095,7 +1099,28 @@ set_properties_now(WindowProperties &properties) {
|
||||
*/
|
||||
CGDisplayModeRef CocoaGraphicsWindow::
|
||||
find_display_mode(int width, int height) {
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, NULL);
|
||||
CFDictionaryRef options = NULL;
|
||||
// On macOS 10.15+ (Catalina), we want to select the display mode with the
|
||||
// samescaling factor as the current view to avoid cropping or scaling issues.
|
||||
// This is a workaround until HiDPI display or scaling factor is properly
|
||||
// handled. CGDisplayCopyAllDisplayModes() does not return upscaled display
|
||||
// mode unless explicitly asked with kCGDisplayShowDuplicateLowResolutionModes
|
||||
// (which is undocumented...).
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_14) {
|
||||
const CFStringRef dictkeys[] = {kCGDisplayShowDuplicateLowResolutionModes};
|
||||
const CFBooleanRef dictvalues[] = {kCFBooleanTrue};
|
||||
options = CFDictionaryCreate(NULL,
|
||||
(const void **)dictkeys,
|
||||
(const void **)dictvalues,
|
||||
1,
|
||||
&kCFCopyStringDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
}
|
||||
#endif
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, options);
|
||||
CFRelease(options);
|
||||
|
||||
size_t num_modes = CFArrayGetCount(modes);
|
||||
CGDisplayModeRef mode;
|
||||
|
||||
@ -1104,14 +1129,22 @@ find_display_mode(int width, int height) {
|
||||
int refresh_rate;
|
||||
mode = CGDisplayCopyDisplayMode(_display);
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 1080
|
||||
// First check if the current mode is adequate.
|
||||
if (CGDisplayModeGetWidth(mode) == width &&
|
||||
CGDisplayModeGetHeight(mode) == height) {
|
||||
return mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
current_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode);
|
||||
refresh_rate = CGDisplayModeGetRefreshRate(mode);
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
// Calculate the pixel width and height of the fullscreen mode we want using
|
||||
// the currentdisplay mode dimensions and pixel dimensions.
|
||||
size_t expected_pixel_width = (size_t(width) * CGDisplayModeGetPixelWidth(mode)) / CGDisplayModeGetWidth(mode);
|
||||
size_t expected_pixel_height = (size_t(height) * CGDisplayModeGetPixelHeight(mode)) / CGDisplayModeGetHeight(mode);
|
||||
#endif
|
||||
CGDisplayModeRelease(mode);
|
||||
|
||||
for (size_t i = 0; i < num_modes; ++i) {
|
||||
@ -1119,9 +1152,17 @@ find_display_mode(int width, int height) {
|
||||
|
||||
CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(mode);
|
||||
|
||||
// As explained above, we want to select the fullscreen display mode using
|
||||
// the same scaling factor, but only for MacOS 10.15+ To do this we check
|
||||
// the mode width and heightbut also actual pixel widh and height.
|
||||
if (CGDisplayModeGetWidth(mode) == width &&
|
||||
CGDisplayModeGetHeight(mode) == height &&
|
||||
CGDisplayModeGetRefreshRate(mode) == refresh_rate &&
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_14 ||
|
||||
(CGDisplayModeGetPixelWidth(mode) == expected_pixel_width &&
|
||||
CGDisplayModeGetPixelHeight(mode) == expected_pixel_height)) &&
|
||||
#endif
|
||||
CFStringCompare(pixel_encoding, current_pixel_encoding, 0) == kCFCompareEqualTo) {
|
||||
|
||||
CFRetain(mode);
|
||||
|
@ -496,6 +496,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
|
||||
}
|
||||
#endif
|
||||
|
||||
dvbc->update_data_size_bytes(num_bytes);
|
||||
return dvbc;
|
||||
} else {
|
||||
dxgsg9_cat.error()
|
||||
@ -533,14 +534,42 @@ apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
return false;
|
||||
}
|
||||
|
||||
PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
|
||||
|
||||
#if 0
|
||||
if (dvbc->changed_size(reader)) {
|
||||
// We have to destroy the old vertex buffer and create a new one.
|
||||
dvbc->create_vbuffer(*_screen, reader);
|
||||
// Destroy and recreate the buffer.
|
||||
if (dvbc->_vbuffer != nullptr) {
|
||||
dvbc->_vbuffer->Release();
|
||||
dvbc->_vbuffer = nullptr;
|
||||
}
|
||||
|
||||
DWORD usage;
|
||||
D3DPOOL pool;
|
||||
if (_screen->_managed_vertex_buffers) {
|
||||
pool = D3DPOOL_MANAGED;
|
||||
usage = D3DUSAGE_WRITEONLY;
|
||||
} else {
|
||||
pool = D3DPOOL_DEFAULT;
|
||||
usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC;
|
||||
}
|
||||
|
||||
PStatTimer timer(_create_vertex_buffer_pcollector, Thread::get_current_thread());
|
||||
|
||||
HRESULT hr;
|
||||
int attempts = 0;
|
||||
do {
|
||||
hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer, nullptr);
|
||||
attempts++;
|
||||
} while (check_dx_allocation(hr, num_bytes, attempts));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dvbc->_vbuffer = nullptr;
|
||||
dxgsg9_cat.error()
|
||||
<< "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
|
||||
|
||||
HRESULT hr;
|
||||
BYTE *local_pointer;
|
||||
@ -5240,6 +5269,7 @@ calc_fb_properties(DWORD cformat, DWORD dformat,
|
||||
#define GAMMA_1 (255.0 * 256.0)
|
||||
|
||||
static bool _gamma_table_initialized = false;
|
||||
static bool _gamma_changed = false;
|
||||
static unsigned short _original_gamma_table [256 * 3];
|
||||
|
||||
void _create_gamma_table_dx9 (PN_stdfloat gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) {
|
||||
@ -5337,6 +5367,7 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
|
||||
|
||||
if (SetDeviceGammaRamp (hdc, ramp)) {
|
||||
set = true;
|
||||
_gamma_changed = !restore;
|
||||
}
|
||||
|
||||
ReleaseDC (nullptr, hdc);
|
||||
@ -5374,7 +5405,9 @@ restore_gamma() {
|
||||
void DXGraphicsStateGuardian9::
|
||||
atexit_function(void) {
|
||||
set_cg_device(nullptr);
|
||||
static_set_gamma(true, 1.0f);
|
||||
if (_gamma_changed) {
|
||||
static_set_gamma(true, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2523,6 +2523,20 @@ reset() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OPENGLES) && !defined(OPENGLES_1)
|
||||
if (is_at_least_gles_version(3, 0)) {
|
||||
_glReadBuffer = (PFNGLREADBUFFERPROC)
|
||||
get_extension_func("glReadBuffer");
|
||||
|
||||
} else if (has_extension("GL_NV_read_buffer")) {
|
||||
_glReadBuffer = (PFNGLREADBUFFERPROC)
|
||||
get_extension_func("glReadBufferNV");
|
||||
|
||||
} else {
|
||||
_glReadBuffer = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
_max_color_targets = 1;
|
||||
if (_glDrawBuffers != nullptr) {
|
||||
@ -9060,7 +9074,7 @@ set_draw_buffer(int rbtype) {
|
||||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
set_read_buffer(int rbtype) {
|
||||
#ifndef OPENGLES // Draw buffers not supported by OpenGL ES. (TODO!)
|
||||
#ifndef OPENGLES_1 // Draw buffers not supported by OpenGL ES 1.
|
||||
if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
|
||||
// Special case: don't have to call ReadBuffer for these.
|
||||
return;
|
||||
@ -9093,10 +9107,14 @@ set_read_buffer(int rbtype) {
|
||||
}
|
||||
++index;
|
||||
}
|
||||
#ifdef OPENGLES
|
||||
_glReadBuffer(buffer);
|
||||
#else
|
||||
glReadBuffer(buffer);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
#ifndef OPENGLES
|
||||
switch (rbtype & RenderBuffer::T_color) {
|
||||
case RenderBuffer::T_front:
|
||||
glReadBuffer(GL_FRONT);
|
||||
@ -9133,10 +9151,11 @@ set_read_buffer(int rbtype) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif // OPENGLES
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
#endif // OPENGLES
|
||||
#endif // OPENGLES_1
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,6 +92,7 @@ typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
|
||||
typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
|
||||
typedef void (APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);
|
||||
typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
|
||||
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
@ -939,6 +940,10 @@ public:
|
||||
PFNGLBLITFRAMEBUFFEREXTPROC _glBlitFramebuffer;
|
||||
PFNGLDRAWBUFFERSPROC _glDrawBuffers;
|
||||
|
||||
#if defined(OPENGLES) && !defined(OPENGLES_1)
|
||||
PFNGLREADBUFFERPROC _glReadBuffer;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
PFNGLCLEARBUFFERFVPROC _glClearBufferfv;
|
||||
PFNGLCLEARBUFFERIVPROC _glClearBufferiv;
|
||||
|
@ -371,13 +371,13 @@ find_fullscreen_crtc(const LPoint2i &point,
|
||||
for (int i = 0; i < res->ncrtc; ++i) {
|
||||
RRCrtc crtc = res->crtcs[i];
|
||||
if (auto info = get_crtc_info(res.get(), crtc)) {
|
||||
if (point[0] >= info->x && point[0] < info->x + info->width &&
|
||||
point[1] >= info->y && point[1] < info->y + info->height) {
|
||||
if (point[0] >= info->x && point[0] < info->x + (int)info->width &&
|
||||
point[1] >= info->y && point[1] < info->y + (int)info->height) {
|
||||
|
||||
x = info->x;
|
||||
y = info->y;
|
||||
width = info->width;
|
||||
height = info->height;
|
||||
width = (int)info->width;
|
||||
height = (int)info->height;
|
||||
return crtc;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ struct MayaVerInfo maya_versions[] = {
|
||||
{ "MAYA2017", "2017"},
|
||||
{ "MAYA2018", "2018"},
|
||||
{ "MAYA2019", "2019"},
|
||||
{ "MAYA2020", "2020"},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
@ -194,26 +195,22 @@ int
|
||||
main(int argc, char *argv[]) {
|
||||
// First, get the command line and append _bin, so we will actually run
|
||||
// maya2egg_bin.exe, egg2maya_bin.exe, etc.
|
||||
Filename command = Filename::from_os_specific(argv[0]);
|
||||
if (!command.is_fully_qualified()) {
|
||||
DSearchPath path;
|
||||
path.append_path(ExecutionEnvironment::get_environment_variable("PATH"));
|
||||
#ifdef _WIN32
|
||||
command.set_extension("exe");
|
||||
#endif
|
||||
command.resolve_filename(path);
|
||||
Filename command = ExecutionEnvironment::get_binary_name();
|
||||
|
||||
if (command.empty() || command == "unknown" || !command.exists()) {
|
||||
command = Filename::from_os_specific(argv[0]);
|
||||
|
||||
if (!command.is_fully_qualified()) {
|
||||
DSearchPath path;
|
||||
path.append_path(ExecutionEnvironment::get_environment_variable("PATH"));
|
||||
#ifdef _WIN32
|
||||
command.set_extension("exe");
|
||||
#endif
|
||||
command.resolve_filename(path);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (command.get_extension() == "exe") {
|
||||
command.set_extension("");
|
||||
}
|
||||
#endif
|
||||
|
||||
command = command.get_fullpath() + string("_bin");
|
||||
#ifdef _WIN32
|
||||
command.set_extension("exe");
|
||||
#endif
|
||||
command.set_basename_wo_extension(command.get_basename_wo_extension() + "_bin");
|
||||
string os_command = command.to_os_specific();
|
||||
|
||||
// First start with $PANDA_MAYA_LOCATION. If it is set, it overrides
|
||||
|
36
tests/dcparser/test_dcpacker.py
Normal file
36
tests/dcparser/test_dcpacker.py
Normal file
@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
|
||||
direct = pytest.importorskip("panda3d.direct")
|
||||
|
||||
|
||||
def test_pack_int8():
|
||||
for num in range(-128, 128):
|
||||
packer = direct.DCPacker()
|
||||
packer.raw_pack_int8(num)
|
||||
packer.set_unpack_data(packer.get_bytes())
|
||||
assert packer.raw_unpack_int8() == num
|
||||
|
||||
|
||||
def test_pack_uint8():
|
||||
for num in range(256):
|
||||
packer = direct.DCPacker()
|
||||
packer.raw_pack_uint8(num)
|
||||
packer.set_unpack_data(packer.get_bytes())
|
||||
assert packer.raw_unpack_uint8() == num
|
||||
|
||||
|
||||
def test_pack_int64():
|
||||
for num in (0, -1, 0x7fffffff, -0x80000000, 0x7fffffffffffffff, 0x7ffffffffffffffe, -0x8000000000000000, -0x7fffffffffffffff):
|
||||
packer = direct.DCPacker()
|
||||
packer.raw_pack_int64(num)
|
||||
packer.set_unpack_data(packer.get_bytes())
|
||||
assert packer.raw_unpack_int64() == num
|
||||
|
||||
|
||||
def test_pack_uint64():
|
||||
for num in (0, 1, 0x7fffffff, 0xffffffff, 0x7fffffffffffffff, 0xfffffffffffffffe, 0xffffffffffffffff):
|
||||
packer = direct.DCPacker()
|
||||
packer.raw_pack_uint64(num)
|
||||
packer.set_unpack_data(packer.get_bytes())
|
||||
assert packer.raw_unpack_uint64() == num
|
||||
|
Loading…
x
Reference in New Issue
Block a user