Merge branch 'master' into input-overhaul

This commit is contained in:
rdb 2018-10-29 23:40:46 +01:00
commit 357b6d3093
136 changed files with 1397 additions and 11547 deletions

View File

@ -77,7 +77,10 @@ class FunctionInterval(Interval.Interval):
@staticmethod
def makeUniqueName(func, suffix = ''):
name = 'Func-%s-%d' % (getattr(func, '__name__', str(func)), FunctionInterval.functionIntervalNum)
func_name = getattr(func, '__name__', None)
if func_name is None:
func_name = str(func)
name = 'Func-%s-%d' % (func_name, FunctionInterval.functionIntervalNum)
FunctionInterval.functionIntervalNum += 1
if suffix:
name = '%s-%s' % (name, str(suffix))

View File

@ -1,20 +0,0 @@
HOW TO INSTALL MAX PANDA PLUGINS.
Step 1. Install the visual studio 2008 runtime by
running "vcredist_x86-sp1.exe" as administrator.
As a convenience, this installer is included with panda.
Step 2. Make sure that there is only one copy of panda
in your system PATH. If you only have one copy of panda
installed, you can skip this step.
Step 3. Copy the relevant DLLs for your version
of max from the panda plugins directory to the
max plugins directory. For instance, if you are
using Max 9, copy maxegg9.dlo and maxeggimport9.dlo
HOW TO INSTALL MAYA PANDA PLUGINS.
(To be written)

View File

@ -1,183 +0,0 @@
------------------------ RELEASE 1.0.0 ---------------------------------
* We now have working exporters for Max5, Max6, Max7, Maya5, Maya6
* The Max exporter is dramatically improved:
- it now includes support for character studio.
- the polygon winding bug has been fixed.
* Panda no longer requires any registry keys or environment
variables. This means it is now possible to:
- run panda directly from a compact disc
- install multiple copies of panda on a single machine
- install panda by copying the tree from another computer
Note that the installer does add the panda 'bin' directory to
your PATH, and it does store an uninstall key in the registry,
but neither of these is needed for panda to function.
* The 'makepanda' build system is now capable of building
prepackaged games for Windows. These prepackaged games are simply
copies of panda with the game code included, some of the
unnecessary stuff stripped out, and some changes to the start
menu. See "Airblade - Installer" on the panda downloads page
for an example.
* All of the sample programs have been tested. The ones that didn't
work have been removed, the ones that do work have been (lightly)
documented.
* This is the first release to include not just a binary installer
for windows, but:
- a binary installer (RPM) for Fedora 2
- a binary installer (RPM) for Fedora 3
- a binary installer (RPM) for Redhat 9
- a binary installer for windows, as always
- a source tar-ball for linux
- a source zip-file for windows
------------------------ RELEASE 2004-12-13 ---------------------------------
* Basic server-client networking support is back in Panda3D. There is a
networking sample in the samples directory. This uses the Panda3d
distributed object system.The README file will explain how to run this.
Documentation of this if forthcoming.
* Panda3d now reduces the number of environment variables such that only 2
are needed now - PRC_PATH and PLAYER.
* GraphicsChannel and GraphicsLayer class have been removed from the
panda/src/display directory. Most Panda applications won't need to be
changed, since most applications simply use ShowBase.py (which has been
adjustedappropriately) to open a window and do the initial setup. For
those rare applications where you need to create your own DisplayRegions,
the makeDisplayRegion() interface has been moved from GraphicsLayer to
GraphicsWindow (actually, to GraphicsOutput, which is the base class of
GraphicsWindow). You can modify your application to call
base.win.makeDisplayRegion() accordingly. If you have something like
displayRegion.getLayer(), replace it with displayRegion.getWindow()
instead.
* Effective with the current version of Panda, the way that HPR angles are
calculated will be changing. The change will make a difference to existing
code or databases that store a hard-coded rotation as a HPR, but only when
R is involved, or both H and P are involved together. That is to say more
precisely, HPR angles with (R != 0 || (H != 0 && P != 0)) now represent a
different rotation than they used to. If you find some legacy code that no
longer works correctly (e.g. it introduces crazy rotations), try putting
the following in your Config.prc file:
temp-hpr-fix 0
To turn off the correct behavior and return to the old, broken behavior.
Note that a longer-term solution will be to represent the HPR angles
correctly in all legacy code. The function oldToNewHpr() is provided to
aid this transition.
* PandaNode definition has been changed to support setting an
into_collide_mask for any arbitrary node, in particular for any GeomNode.
It used to be that only CollisionNodes had an into_collide_mask. This
change obviates the need for CollisionNode::set_collide_geom(), which is
now a deprecated interface and will be removed at some point in the future.
Details:
There's now a NodePath::set_collide_mask() and
NodePath::get_collide_mask(), which operate on all CollisionNodes and
GeomNodes at and below the current node. By default, set_collide_mask()
will replace the entire collide mask, but you may also specify (via a
second parameter) the subset of bits that are to be changed; other bits
will be left alone. You can also specify a particular type of node to
modify via a third parameter, e.g. you can adjust the masks for GeomNodes
or CollisionNodes only.
The NodePath set_collide_mask() interface changes the into_collide_mask.
Those familiar with the collision system will recall that a CollisionNode
(but only a CollisionNode) also has a from_collide_mask. The
from_collide_mask of the active mover is compared with the into_collide_mask
of each object in the world; a collision is only possible if there are some
bits in common.
It used to be that only other CollisionNodes had an into_collide_mask. A
mover would only test for collisions with CollisionNodes that matched its
collide_mask. If you wanted to make your mover detect collisions with
visible geometry which had no into_collide_mask, you had to call
set_collide_geom(1). This allowed the mover to detect collisions with *all*
visible geometry; it was either an all-or-none thing.
Now that GeomNodes also have an into_collide_mask, there's no longer a need
for set_collide_geom(). A mover will detect collisions with any
CollisionNodes or GeomNodes that match its collide_mask. This means, for
the purposes of collision detection, you can use CollisionNodes and
GeomNodes pretty much interchangeably; simply set the appropriate bits on
the objects you want to collide with, regardless of whether they are
invisible collision solids or visible geometry.
(This should not be taken as a license to avoid using CollisionNodes
altogether. The intersection computation with visible geometry is still
less efficient than the same computation with collision solids. And visible
geometry tends to be many times more complex than is strictly necessary for
collisions.)
There's one more detail: every GeomNode, by default, has one bit set on in
its collide_mask, unless it is explicitly turned off. This bit is
GeomNode::get_default_collide_mask(). This bit is provided for the
convenience of programmers who still want the old behavior of
set_collide_geom(): it allows you to easily create a CollisionNode that
will collide with all visible geometry in the world.
Along the same lines, there's also CollisionNode::get_default_collide_mask(),
which is 0x000fffff. This is the default mask that is created for a new
CollisionNode (and it does not include the bit reserved for GeomNodes,
above). Previously, a new CollisionNode would have all bits on by default.
------------------------ RELEASE 2004-11-11 -----------------------------------
* Multiple mice can now be used with Panda3D. showbase has a list called
pointerWatcherNodes. The first mouse on this list is the system mouse. The
getMouseX() and getMouseY() will return coordinates relative to the
application window. The rest of the mice on the list will give raw mouse
positions and will change when they are moved on the screen.
In addition there are new events for mouse buttons. Each mouse will be have
a corresponding event. mouse1 will send mousedev1-mouse1, mousedev1-mouse2
and mousedev1-mouse3 events. mouse2 and any other mouse attached
will send similar events mousedev2-mouse1 etc.
The old mouse buttons work too. mouse1, mouse2, mouse3 events will be
triggered if that button is pressed on any mouse
------------------------ RELEASE 2004-10-13 -----------------------------------
General
* Release notes: Each release will now have an entry associated with
it in this document. This will be updated in reverse-chronological order.
Panda3D
* Distributed with this release is a working version of the SceneEditor
created in Spring 2004 at the ETC. Documentation will be forthcoming on the
website. This can be found in <InstallPath>/SceneEditor
* The latest version of FMOD is distributed with this release. The latest
version is 3.73.
* AudioSound object now allows more types of sound. These include wma and
ogg vorbis formats. This is valid when using the fmod sound system. Midi,
Mod, s3m, it, xm and such sequencer type file formats are not supported.
Exception - Midi files can be played. This is not fully implemented.
* A bug in SoundInterval is fixed. SoundInterval looping would incorrectly
add a minimum of 1.5 seconds to the sound. This has been fixed. Sound
looping problems in general should be fixed. Midi's still don't support
looping through the AudioSound object. They should loop through
SoundIntervals though.
* Cg support has been added to Panda3D. Documentation for this is
forthcoming.

View File

@ -306,7 +306,6 @@ is_trivial() const {
}
// Now look for functions that are virtual or con/destructors.
bool is_default_constructible = true;
CPPScope::Functions::const_iterator fi;
for (fi = _scope->_functions.begin(); fi != _scope->_functions.end(); ++fi) {
CPPFunctionGroup *fgroup = (*fi).second;
@ -343,9 +342,6 @@ is_trivial() const {
// Same for the default constructor.
return false;
}
// The presence of a non-default constructor makes the class not
// default-constructible.
is_default_constructible = false;
}
if (fgroup->_name == "operator =") {
@ -356,7 +352,7 @@ is_trivial() const {
}
// Finally, the class must be default-constructible.
return is_default_constructible;
return is_default_constructible(V_public);
}
/**

View File

@ -62,4 +62,12 @@ default_thread_consider_yield() {
void (*global_thread_yield)() = default_thread_yield;
void (*global_thread_consider_yield)() = default_thread_consider_yield;
#ifdef HAVE_PYTHON
static PyThreadState *
default_thread_state_swap(PyThreadState *state) {
return nullptr;
}
PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate) = default_thread_state_swap;
#endif // HAVE_PYTHON
#endif // HAVE_THREADS && SIMPLE_THREADS

View File

@ -63,8 +63,10 @@
/* Windows likes to define min() and max() macros, which will conflict with
std::min() and std::max() respectively, unless we do this: */
#ifdef WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0

View File

@ -233,6 +233,15 @@ INLINE void thread_consider_yield() {
(*global_thread_consider_yield)();
}
#ifdef HAVE_PYTHON
typedef struct _ts PyThreadState;
extern EXPCL_DTOOL_DTOOLBASE PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate);
INLINE PyThreadState *thread_state_swap(PyThreadState *tstate) {
return (*global_thread_state_swap)(tstate);
}
#endif // HAVE_PYTHON
#else
INLINE void thread_yield() {

View File

@ -1,2 +1,3 @@
#include "filename_ext.cxx"
#include "globPattern_ext.cxx"
#include "textEncoder_ext.cxx"

View File

@ -53,5 +53,5 @@ StringUtf8Decoder(const std::string &input) : StringDecoder(input) {
*
*/
INLINE StringUnicodeDecoder::
StringUnicodeDecoder(const std::string &input) : StringDecoder(input) {
StringUtf16Decoder(const std::string &input) : StringDecoder(input) {
}

View File

@ -26,7 +26,7 @@ StringDecoder::
/**
* Returns the next character in sequence.
*/
int StringDecoder::
char32_t StringDecoder::
get_next_character() {
if (test_eof()) {
return -1;
@ -57,19 +57,20 @@ get_notify_ptr() {
/*
In UTF-8, each 16-bit Unicode character is encoded as a sequence of
one, two, or three 8-bit bytes, depending on the value of the
one, two, three or four 8-bit bytes, depending on the value of the
character. The following table shows the format of such UTF-8 byte
sequences (where the "free bits" shown by x's in the table are
combined in the order shown, and interpreted from most significant to
least significant):
Binary format of bytes in sequence:
Number of Maximum expressible
1st byte 2nd byte 3rd byte free bits: Unicode value:
Number of Maximum expressible
1st byte 2nd byte 3rd byte 4th byte free bits: Unicode value:
0xxxxxxx 7 007F hex (127)
110xxxxx 10xxxxxx (5+6)=11 07FF hex (2047)
1110xxxx 10xxxxxx 10xxxxxx (4+6+6)=16 FFFF hex (65535)
0xxxxxxx 7 007F hex (127)
110xxxxx 10xxxxxx (5+6)=11 07FF hex (2047)
1110xxxx 10xxxxxx 10xxxxxx (4+6+6)=16 FFFF hex (65535)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (4+6*3)=21 10FFFF hex (1114111)
The value of each individual byte indicates its UTF-8 function, as follows:
@ -77,12 +78,13 @@ The value of each individual byte indicates its UTF-8 function, as follows:
80 to BF hex (128 to 191): continuing byte in a multi-byte sequence.
C2 to DF hex (194 to 223): first byte of a two-byte sequence.
E0 to EF hex (224 to 239): first byte of a three-byte sequence.
F0 to F7 hex (240 to 247): first byte of a four-byte sequence.
*/
/**
* Returns the next character in sequence.
*/
int StringUtf8Decoder::
char32_t StringUtf8Decoder::
get_next_character() {
unsigned int result;
while (!test_eof()) {
@ -125,6 +127,35 @@ get_next_character() {
unsigned int three = (unsigned char)_input[_p++];
result = ((result & 0x0f) << 12) | ((two & 0x3f) << 6) | (three & 0x3f);
return result;
} else if ((result & 0xf8) == 0xf0) {
// First byte of four.
if (test_eof()) {
if (_notify_ptr != nullptr) {
(*_notify_ptr)
<< "utf-8 encoded string '" << _input << "' ends abruptly.\n";
}
return -1;
}
unsigned int two = (unsigned char)_input[_p++];
if (test_eof()) {
if (_notify_ptr != nullptr) {
(*_notify_ptr)
<< "utf-8 encoded string '" << _input << "' ends abruptly.\n";
}
return -1;
}
unsigned int three = (unsigned char)_input[_p++];
if (test_eof()) {
if (_notify_ptr != nullptr) {
(*_notify_ptr)
<< "utf-8 encoded string '" << _input << "' ends abruptly.\n";
}
return -1;
}
unsigned int four = (unsigned char)_input[_p++];
result = ((result & 0x07) << 18) | ((two & 0x3f) << 12) | ((three & 0x3f) << 6) | (four & 0x3f);
return result;
}
// Otherwise--the high bit is set but it is not one of the introductory
@ -144,7 +175,7 @@ get_next_character() {
/**
* Returns the next character in sequence.
*/
int StringUnicodeDecoder::
char32_t StringUtf16Decoder::
get_next_character() {
if (test_eof()) {
return -1;
@ -159,5 +190,33 @@ get_next_character() {
return -1;
}
unsigned int low = (unsigned char)_input[_p++];
return ((high << 8) | low);
int ch = ((high << 8) | low);
/*
using std::swap;
if (ch == 0xfffe) {
// This is a byte-swapped byte-order-marker. That means we need to swap
// the endianness of the rest of the stream.
char *data = (char *)_input.data();
for (size_t p = _p; p < _input.size() - 1; p += 2) {
std::swap(data[p], data[p + 1]);
}
ch = 0xfeff;
}
*/
if (ch >= 0xd800 && ch < 0xdc00 && (_p + 1) < _input.size()) {
// This is a high surrogate. Look for a subsequent low surrogate.
unsigned int high = (unsigned char)_input[_p];
unsigned int low = (unsigned char)_input[_p + 1];
int ch2 = ((high << 8) | low);
if (ch2 >= 0xdc00 && ch2 < 0xe000) {
// Yes, this is a low surrogate.
_p += 2;
return 0x10000 + ((ch - 0xd800) << 10) + (ch2 - 0xdc00);
}
}
// No, this is just a regular character, or an unpaired surrogate.
return ch;
}

View File

@ -26,7 +26,7 @@ public:
INLINE StringDecoder(const std::string &input);
virtual ~StringDecoder();
virtual int get_next_character();
virtual char32_t get_next_character();
INLINE bool is_eof();
static void set_notify_ptr(std::ostream *ptr);
@ -48,20 +48,23 @@ class StringUtf8Decoder : public StringDecoder {
public:
INLINE StringUtf8Decoder(const std::string &input);
virtual int get_next_character();
virtual char32_t get_next_character();
};
/**
* This decoder extracts characters two at a time to get a plain wide
* character sequence.
* character sequence. It supports surrogate pairs.
*/
class StringUnicodeDecoder : public StringDecoder {
class StringUtf16Decoder : public StringDecoder {
public:
INLINE StringUnicodeDecoder(const std::string &input);
INLINE StringUtf16Decoder(const std::string &input);
virtual int get_next_character();
virtual char32_t get_next_character();
};
// Deprecated alias of StringUtf16Encoder.
typedef StringUtf16Decoder StringUnicodeDecoder;
#include "stringDecoder.I"
#endif

View File

@ -90,6 +90,7 @@ set_text(const std::string &text) {
if (!has_text() || _text != text) {
_text = text;
_flags = (_flags | F_got_text) & ~F_got_wtext;
text_changed();
}
}
@ -101,7 +102,11 @@ set_text(const std::string &text) {
*/
INLINE void TextEncoder::
set_text(const std::string &text, TextEncoder::Encoding encoding) {
set_wtext(decode_text(text, encoding));
if (encoding == _encoding) {
set_text(text);
} else {
set_wtext(decode_text(text, encoding));
}
}
/**
@ -112,6 +117,7 @@ clear_text() {
_text = std::string();
_wtext = std::wstring();
_flags |= (F_got_text | F_got_wtext);
text_changed();
}
/**
@ -151,8 +157,11 @@ get_text(TextEncoder::Encoding encoding) const {
*/
INLINE void TextEncoder::
append_text(const std::string &text) {
_text = get_text() + text;
_flags = (_flags | F_got_text) & ~F_got_wtext;
if (!text.empty()) {
_text = get_text() + text;
_flags = (_flags | F_got_text) & ~F_got_wtext;
text_changed();
}
}
/**
@ -160,9 +169,25 @@ append_text(const std::string &text) {
* wide character, up to 16 bits in Unicode.
*/
INLINE void TextEncoder::
append_unicode_char(int character) {
append_unicode_char(char32_t character) {
#if WCHAR_MAX >= 0x10FFFF
// wchar_t might be UTF-32.
_wtext = get_wtext() + std::wstring(1, (wchar_t)character);
#else
if ((character & ~0xffff) == 0) {
_wtext = get_wtext() + std::wstring(1, (wchar_t)character);
} else {
// Encode as a surrogate pair.
uint32_t v = (uint32_t)character - 0x10000u;
wchar_t wstr[2] = {
(wchar_t)((v >> 10u) | 0xd800u),
(wchar_t)((v & 0x3ffu) | 0xdc00u),
};
_wtext = get_wtext() + std::wstring(wstr, 2);
}
#endif
_flags = (_flags | F_got_wtext) & ~F_got_text;
text_changed();
}
/**
@ -195,11 +220,12 @@ get_unicode_char(size_t index) const {
* according to set_encoding().
*/
INLINE void TextEncoder::
set_unicode_char(size_t index, int character) {
set_unicode_char(size_t index, char32_t character) {
get_wtext();
if (index < _wtext.length()) {
_wtext[index] = character;
_flags &= ~F_got_text;
text_changed();
}
}
@ -257,7 +283,7 @@ reencode_text(const std::string &text, TextEncoder::Encoding from,
* otherwise. This is akin to ctype's isalpha(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isalpha(int character) {
unicode_isalpha(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -271,7 +297,7 @@ unicode_isalpha(int character) {
* otherwise. This is akin to ctype's isdigit(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isdigit(int character) {
unicode_isdigit(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
// The digits aren't actually listed in the map.
@ -286,11 +312,11 @@ unicode_isdigit(int character) {
* otherwise. This is akin to ctype's ispunct(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_ispunct(int character) {
unicode_ispunct(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
// Some punctuation marks aren't listed in the map.
return (character >= 0 && character < 128 && ispunct(character));
return (character < 128 && ispunct(character));
}
return entry->_char_type == UnicodeLatinMap::CT_punct;
}
@ -300,7 +326,7 @@ unicode_ispunct(int character) {
* otherwise. This is akin to ctype's isupper(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isupper(int character) {
unicode_isupper(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -313,7 +339,7 @@ unicode_isupper(int character) {
* otherwise. This is akin to ctype's isspace(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_isspace(int character) {
unicode_isspace(char32_t character) {
switch (character) {
case ' ':
case '\t':
@ -330,7 +356,7 @@ unicode_isspace(int character) {
* otherwise. This is akin to ctype's islower(), extended to Unicode.
*/
INLINE bool TextEncoder::
unicode_islower(int character) {
unicode_islower(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return false;
@ -343,7 +369,7 @@ unicode_islower(int character) {
* akin to ctype's toupper(), extended to Unicode.
*/
INLINE int TextEncoder::
unicode_toupper(int character) {
unicode_toupper(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return character;
@ -356,7 +382,7 @@ unicode_toupper(int character) {
* akin to ctype's tolower(), extended to Unicode.
*/
INLINE int TextEncoder::
unicode_tolower(int character) {
unicode_tolower(char32_t character) {
const UnicodeLatinMap::Entry *entry = UnicodeLatinMap::look_up(character);
if (entry == nullptr) {
return character;
@ -418,6 +444,7 @@ set_wtext(const std::wstring &wtext) {
if (!has_text() || _wtext != wtext) {
_wtext = wtext;
_flags = (_flags | F_got_wtext) & ~F_got_text;
text_changed();
}
}
@ -439,8 +466,11 @@ get_wtext() const {
*/
INLINE void TextEncoder::
append_wtext(const std::wstring &wtext) {
_wtext = get_wtext() + wtext;
_flags = (_flags | F_got_wtext) & ~F_got_text;
if (!wtext.empty()) {
_wtext = get_wtext() + wtext;
_flags = (_flags | F_got_wtext) & ~F_got_text;
text_changed();
}
}
/**

View File

@ -21,7 +21,7 @@ using std::ostream;
using std::string;
using std::wstring;
TextEncoder::Encoding TextEncoder::_default_encoding = TextEncoder::E_iso8859;
TextEncoder::Encoding TextEncoder::_default_encoding = TextEncoder::E_utf8;
/**
* Adjusts the text stored within the encoder to all uppercase letters
@ -35,6 +35,7 @@ make_upper() {
(*si) = unicode_toupper(*si);
}
_flags &= ~F_got_text;
text_changed();
}
/**
@ -49,6 +50,7 @@ make_lower() {
(*si) = unicode_tolower(*si);
}
_flags &= ~F_got_text;
text_changed();
}
/**
@ -107,11 +109,11 @@ is_wtext() const {
}
/**
* Encodes a single wide char into a one-, two-, or three-byte string,
* according to the given encoding system.
* Encodes a single Unicode character into a one-, two-, three-, or four-byte
* string, according to the given encoding system.
*/
string TextEncoder::
encode_wchar(wchar_t ch, TextEncoder::Encoding encoding) {
encode_wchar(char32_t ch, TextEncoder::Encoding encoding) {
switch (encoding) {
case E_iso8859:
if ((ch & ~0xff) == 0) {
@ -143,17 +145,38 @@ encode_wchar(wchar_t ch, TextEncoder::Encoding encoding) {
return
string(1, (char)((ch >> 6) | 0xc0)) +
string(1, (char)((ch & 0x3f) | 0x80));
} else {
} else if ((ch & ~0xffff) == 0) {
return
string(1, (char)((ch >> 12) | 0xe0)) +
string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) +
string(1, (char)((ch & 0x3f) | 0x80));
} else {
return
string(1, (char)((ch >> 18) | 0xf0)) +
string(1, (char)(((ch >> 12) & 0x3f) | 0x80)) +
string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) +
string(1, (char)((ch & 0x3f) | 0x80));
}
case E_unicode:
return
string(1, (char)(ch >> 8)) +
string(1, (char)(ch & 0xff));
case E_utf16be:
if ((ch & ~0xffff) == 0) {
// Note that this passes through surrogates and BOMs unharmed.
return
string(1, (char)(ch >> 8)) +
string(1, (char)(ch & 0xff));
} else {
// Use a surrogate pair.
uint32_t v = (uint32_t)ch - 0x10000u;
uint16_t hi = (v >> 10u) | 0xd800u;
uint16_t lo = (v & 0x3ffu) | 0xdc00u;
char encoded[4] = {
(char)(hi >> 8),
(char)(hi & 0xff),
(char)(lo >> 8),
(char)(lo & 0xff),
};
return string(encoded, 4);
}
}
return "";
@ -167,8 +190,25 @@ string TextEncoder::
encode_wtext(const wstring &wtext, TextEncoder::Encoding encoding) {
string result;
for (wstring::const_iterator pi = wtext.begin(); pi != wtext.end(); ++pi) {
result += encode_wchar(*pi, encoding);
for (size_t i = 0; i < wtext.size(); ++i) {
wchar_t ch = wtext[i];
// On some systems, wstring may be UTF-16, and contain surrogate pairs.
#if WCHAR_MAX < 0x10FFFF
if (ch >= 0xd800 && ch < 0xdc00 && (i + 1) < wtext.size()) {
// This is a high surrogate. Look for a subsequent low surrogate.
wchar_t ch2 = wtext[i + 1];
if (ch2 >= 0xdc00 && ch2 < 0xe000) {
// Yes, this is a low surrogate.
char32_t code_point = 0x10000 + ((ch - 0xd800) << 10) + (ch2 - 0xdc00);
result += encode_wchar(code_point, encoding);
i++;
continue;
}
}
#endif
result += encode_wchar(ch, encoding);
}
return result;
@ -187,9 +227,9 @@ decode_text(const string &text, TextEncoder::Encoding encoding) {
return decode_text_impl(decoder);
}
case E_unicode:
case E_utf16be:
{
StringUnicodeDecoder decoder(text);
StringUtf16Decoder decoder(text);
return decode_text_impl(decoder);
}
@ -211,7 +251,7 @@ decode_text_impl(StringDecoder &decoder) {
wstring result;
// bool expand_amp = get_expand_amp();
wchar_t character = decoder.get_next_character();
char32_t character = decoder.get_next_character();
while (!decoder.is_eof()) {
/*
if (character == '&' && expand_amp) {
@ -219,7 +259,14 @@ decode_text_impl(StringDecoder &decoder) {
character = expand_amp_sequence(decoder);
}
*/
result += character;
if (character <= WCHAR_MAX) {
result += character;
} else {
// We need to encode this as a surrogate pair.
uint32_t v = (uint32_t)character - 0x10000u;
result += (wchar_t)((v >> 10u) | 0xd800u);
result += (wchar_t)((v & 0x3ffu) | 0xdc00u);
}
character = decoder.get_next_character();
}
@ -314,6 +361,12 @@ expand_amp_sequence(StringDecoder &decoder) const {
}
*/
/**
* Called whenever the text has been changed.
*/
void TextEncoder::
text_changed() {
}
/**
*
@ -327,8 +380,8 @@ operator << (ostream &out, TextEncoder::Encoding encoding) {
case TextEncoder::E_utf8:
return out << "utf8";
case TextEncoder::E_unicode:
return out << "unicode";
case TextEncoder::E_utf16be:
return out << "utf16be";
};
return out << "**invalid TextEncoder::Encoding(" << (int)encoding << ")**";
@ -346,8 +399,9 @@ operator >> (istream &in, TextEncoder::Encoding &encoding) {
encoding = TextEncoder::E_iso8859;
} else if (word == "utf8" || word == "utf-8") {
encoding = TextEncoder::E_utf8;
} else if (word == "unicode") {
encoding = TextEncoder::E_unicode;
} else if (word == "unicode" || word == "utf16be" || word == "utf-16be" ||
word == "utf16-be" || word == "utf-16-be") {
encoding = TextEncoder::E_utf16be;
} else {
ostream *notify_ptr = StringDecoder::get_notify_ptr();
if (notify_ptr != nullptr) {

View File

@ -23,7 +23,7 @@ class StringDecoder;
/**
* This class can be used to convert text between multiple representations,
* e.g. utf-8 to Unicode. You may use it as a static class object, passing
* e.g. UTF-8 to UTF-16. You may use it as a static class object, passing
* the encoding each time, or you may create an instance and use that object,
* which will record the current encoding and retain the current string.
*
@ -35,12 +35,17 @@ PUBLISHED:
enum Encoding {
E_iso8859,
E_utf8,
E_unicode
E_utf16be,
// Deprecated alias for E_utf16be
E_unicode = E_utf16be,
};
INLINE TextEncoder();
INLINE TextEncoder(const TextEncoder &copy);
virtual ~TextEncoder() = default;
INLINE void set_encoding(Encoding encoding);
INLINE Encoding get_encoding() const;
@ -48,35 +53,46 @@ PUBLISHED:
INLINE static Encoding get_default_encoding();
MAKE_PROPERTY(default_encoding, get_default_encoding, set_default_encoding);
#ifdef CPPPARSER
EXTEND void set_text(PyObject *text);
EXTEND void set_text(PyObject *text, Encoding encoding);
#else
INLINE void set_text(const std::string &text);
INLINE void set_text(const std::string &text, Encoding encoding);
#endif
INLINE void clear_text();
INLINE bool has_text() const;
void make_upper();
void make_lower();
#ifdef CPPPARSER
EXTEND PyObject *get_text() const;
EXTEND PyObject *get_text(Encoding encoding) const;
EXTEND void append_text(PyObject *text);
#else
INLINE std::string get_text() const;
INLINE std::string get_text(Encoding encoding) const;
INLINE void append_text(const std::string &text);
INLINE void append_unicode_char(int character);
#endif
INLINE void append_unicode_char(char32_t character);
INLINE size_t get_num_chars() const;
INLINE int get_unicode_char(size_t index) const;
INLINE void set_unicode_char(size_t index, int character);
INLINE void set_unicode_char(size_t index, char32_t character);
INLINE std::string get_encoded_char(size_t index) const;
INLINE std::string get_encoded_char(size_t index, Encoding encoding) const;
INLINE std::string get_text_as_ascii() const;
INLINE static std::string reencode_text(const std::string &text, Encoding from, Encoding to);
INLINE static bool unicode_isalpha(int character);
INLINE static bool unicode_isdigit(int character);
INLINE static bool unicode_ispunct(int character);
INLINE static bool unicode_islower(int character);
INLINE static bool unicode_isupper(int character);
INLINE static bool unicode_isspace(int character);
INLINE static int unicode_toupper(int character);
INLINE static int unicode_tolower(int character);
INLINE static bool unicode_isalpha(char32_t character);
INLINE static bool unicode_isdigit(char32_t character);
INLINE static bool unicode_ispunct(char32_t character);
INLINE static bool unicode_islower(char32_t character);
INLINE static bool unicode_isupper(char32_t character);
INLINE static bool unicode_isspace(char32_t character);
INLINE static int unicode_toupper(char32_t character);
INLINE static int unicode_tolower(char32_t character);
INLINE static std::string upper(const std::string &source);
INLINE static std::string upper(const std::string &source, Encoding encoding);
@ -91,11 +107,24 @@ PUBLISHED:
std::wstring get_wtext_as_ascii() const;
bool is_wtext() const;
static std::string encode_wchar(wchar_t ch, Encoding encoding);
#ifdef CPPPARSER
EXTEND static PyObject *encode_wchar(char32_t ch, Encoding encoding);
EXTEND INLINE PyObject *encode_wtext(const std::wstring &wtext) const;
EXTEND static PyObject *encode_wtext(const std::wstring &wtext, Encoding encoding);
EXTEND INLINE PyObject *decode_text(PyObject *text) const;
EXTEND static PyObject *decode_text(PyObject *text, Encoding encoding);
#else
static std::string encode_wchar(char32_t ch, Encoding encoding);
INLINE std::string encode_wtext(const std::wstring &wtext) const;
static std::string encode_wtext(const std::wstring &wtext, Encoding encoding);
INLINE std::wstring decode_text(const std::string &text) const;
static std::wstring decode_text(const std::string &text, Encoding encoding);
#endif
MAKE_PROPERTY(text, get_text, set_text);
protected:
virtual void text_changed();
private:
enum Flags {

View File

@ -0,0 +1,30 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file textEncoder_ext.I
* @author rdb
* @date 2018-10-08
*/
/**
* Encodes a wide-text string into a single-char string, according to the
* current encoding.
*/
INLINE PyObject *Extension<TextEncoder>::
encode_wtext(const std::wstring &wtext) const {
return encode_wtext(wtext, _this->get_encoding());
}
/**
* Returns the given wstring decoded to a single-byte string, via the current
* encoding system.
*/
INLINE PyObject *Extension<TextEncoder>::
decode_text(PyObject *text) const {
return decode_text(text, _this->get_encoding());
}

View File

@ -0,0 +1,164 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file textEncoder_ext.cxx
* @author rdb
* @date 2018-09-29
*/
#include "textEncoder_ext.h"
#ifdef HAVE_PYTHON
/**
* Sets the text as a Unicode string. In Python 2, if a regular str is given,
* it is assumed to be in the TextEncoder's specified encoding.
*/
void Extension<TextEncoder>::
set_text(PyObject *text) {
if (PyUnicode_Check(text)) {
#if PY_VERSION_HEX >= 0x03030000
Py_ssize_t len;
const char *str = PyUnicode_AsUTF8AndSize(text, &len);
_this->set_text(std::string(str, len), TextEncoder::E_utf8);
#else
Py_ssize_t len = PyUnicode_GET_SIZE(text);
wchar_t *str = (wchar_t *)alloca(sizeof(wchar_t) * (len + 1));
PyUnicode_AsWideChar((PyUnicodeObject *)text, str, len);
_this->set_wtext(std::wstring(str, len));
#endif
} else {
#if PY_MAJOR_VERSION >= 3
Dtool_Raise_TypeError("expected string");
#else
char *str;
Py_ssize_t len;
if (PyString_AsStringAndSize(text, (char **)&str, &len) != -1) {
_this->set_text(std::string(str, len));
}
#endif
}
}
/**
* Sets the text as an encoded byte string of the given encoding.
*/
void Extension<TextEncoder>::
set_text(PyObject *text, TextEncoder::Encoding encoding) {
char *str;
Py_ssize_t len;
if (PyBytes_AsStringAndSize(text, &str, &len) >= 0) {
_this->set_text(std::string(str, len), encoding);
}
}
/**
* Returns the text as a string. In Python 2, the returned string is in the
* TextEncoder's specified encoding. In Python 3, it is returned as unicode.
*/
PyObject *Extension<TextEncoder>::
get_text() const {
#if PY_MAJOR_VERSION >= 3
std::wstring text = _this->get_wtext();
return PyUnicode_FromWideChar(text.data(), (Py_ssize_t)text.size());
#else
std::string text = _this->get_text();
return PyString_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
#endif
}
/**
* Returns the text as a bytes object in the given encoding.
*/
PyObject *Extension<TextEncoder>::
get_text(TextEncoder::Encoding encoding) const {
std::string text = _this->get_text(encoding);
#if PY_MAJOR_VERSION >= 3
return PyBytes_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
#else
return PyString_FromStringAndSize((char *)text.data(), (Py_ssize_t)text.size());
#endif
}
/**
* Appends the text as a string (or Unicode object in Python 2).
*/
void Extension<TextEncoder>::
append_text(PyObject *text) {
if (PyUnicode_Check(text)) {
#if PY_VERSION_HEX >= 0x03030000
Py_ssize_t len;
const char *str = PyUnicode_AsUTF8AndSize(text, &len);
std::string text_str(str, len);
if (_this->get_encoding() == TextEncoder::E_utf8) {
_this->append_text(text_str);
} else {
_this->append_wtext(TextEncoder::decode_text(text_str, TextEncoder::E_utf8));
}
#else
Py_ssize_t len = PyUnicode_GET_SIZE(text);
wchar_t *str = (wchar_t *)alloca(sizeof(wchar_t) * (len + 1));
PyUnicode_AsWideChar((PyUnicodeObject *)text, str, len);
_this->append_wtext(std::wstring(str, len));
#endif
} else {
#if PY_MAJOR_VERSION >= 3
Dtool_Raise_TypeError("expected string");
#else
char *str;
Py_ssize_t len;
if (PyString_AsStringAndSize(text, (char **)&str, &len) != -1) {
_this->append_text(std::string(str, len));
}
#endif
}
}
/**
* Encodes the given wide character as byte string in the given encoding.
*/
PyObject *Extension<TextEncoder>::
encode_wchar(char32_t ch, TextEncoder::Encoding encoding) {
std::string value = TextEncoder::encode_wchar(ch, encoding);
#if PY_MAJOR_VERSION >= 3
return PyBytes_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
#else
return PyString_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
#endif
}
/**
* Encodes a wide-text string into a single-char string, according to the
* given encoding.
*/
PyObject *Extension<TextEncoder>::
encode_wtext(const wstring &wtext, TextEncoder::Encoding encoding) {
std::string value = TextEncoder::encode_wtext(wtext, encoding);
#if PY_MAJOR_VERSION >= 3
return PyBytes_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
#else
return PyString_FromStringAndSize((char *)value.data(), (Py_ssize_t)value.size());
#endif
}
/**
* Returns the given wstring decoded to a single-byte string, via the given
* encoding system.
*/
PyObject *Extension<TextEncoder>::
decode_text(PyObject *text, TextEncoder::Encoding encoding) {
char *str;
Py_ssize_t len;
if (PyBytes_AsStringAndSize(text, &str, &len) >= 0) {
return Dtool_WrapValue(TextEncoder::decode_text(std::string(str, len), encoding));
} else {
return nullptr;
}
}
#endif // HAVE_PYTHON

View File

@ -0,0 +1,50 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file textEncoder_ext.h
* @author rdb
* @date 2018-09-29
*/
#ifndef TEXTENCODER_EXT_H
#define TEXTENCODER_EXT_H
#include "dtoolbase.h"
#ifdef HAVE_PYTHON
#include "extension.h"
#include "textEncoder.h"
#include "py_panda.h"
/**
* This class defines the extension methods for TextEncoder, which are called
* instead of any C++ methods with the same prototype.
*/
template<>
class Extension<TextEncoder> : public ExtensionBase<TextEncoder> {
public:
void set_text(PyObject *text);
void set_text(PyObject *text, TextEncoder::Encoding encoding);
PyObject *get_text() const;
PyObject *get_text(TextEncoder::Encoding encoding) const;
void append_text(PyObject *text);
static PyObject *encode_wchar(char32_t ch, TextEncoder::Encoding encoding);
INLINE PyObject *encode_wtext(const std::wstring &wtext) const;
static PyObject *encode_wtext(const std::wstring &wtext, TextEncoder::Encoding encoding);
INLINE PyObject *decode_text(PyObject *text) const;
static PyObject *decode_text(PyObject *text, TextEncoder::Encoding encoding);
};
#include "textEncoder_ext.I"
#endif // HAVE_PYTHON
#endif // TEXTENCODER_EXT_H

View File

@ -1378,7 +1378,7 @@ static const wchar_t combining_accent_map[] = {
* Returns the Entry associated with the indicated character, if there is one.
*/
const UnicodeLatinMap::Entry *UnicodeLatinMap::
look_up(wchar_t character) {
look_up(char32_t character) {
if (!_initialized) {
init();
}

View File

@ -112,17 +112,17 @@ public:
class Entry {
public:
wchar_t _character;
char32_t _character;
CharType _char_type;
char _ascii_equiv;
char _ascii_additional;
wchar_t _tolower_character;
wchar_t _toupper_character;
char32_t _tolower_character;
char32_t _toupper_character;
AccentType _accent_type;
int _additional_flags;
};
static const Entry *look_up(wchar_t character);
static const Entry *look_up(char32_t character);
static wchar_t get_combining_accent(AccentType accent);
@ -130,7 +130,7 @@ private:
static void init();
static bool _initialized;
typedef phash_map<wchar_t, const Entry *, integer_hash<wchar_t> > ByCharacter;
typedef phash_map<char32_t, const Entry *, integer_hash<char32_t> > ByCharacter;
static ByCharacter *_by_character;
enum { max_direct_chars = 256 };
static const Entry *_direct_chars[max_direct_chars];

View File

@ -1389,7 +1389,8 @@ scan_element(CPPInstance *element, CPPStructType *struct_type,
// We can only generate a getter and a setter if we can talk about the
// type it is.
if (parameter_type->as_struct_type() != nullptr) {
if (parameter_type->as_struct_type() != nullptr &&
!parameter_type->is_trivial()) {
// Wrap the type in a const reference.
parameter_type = TypeManager::wrap_const_reference(parameter_type);
}

View File

@ -722,7 +722,10 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
// Extract the __file__ attribute, if present.
Filename main_dir;
PyObject *file_attr = PyObject_GetAttrString(main_module, "__file__");
PyObject *file_attr = nullptr;
if (main_module != nullptr) {
file_attr = PyObject_GetAttrString(main_module, "__file__");
}
if (file_attr == nullptr) {
// Must be running in the interactive interpreter. Use the CWD.
main_dir = ExecutionEnvironment::get_cwd();
@ -752,6 +755,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
PyErr_Clear();
initialized_main_dir = true;
// Also, while we are at it, initialize the thread swap hook.
#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
global_thread_state_swap = PyThreadState_Swap;
#endif
}
PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);

View File

@ -28,7 +28,7 @@ typedef _typeobject PyTypeObject;
typedef struct {} PyStringObject;
typedef struct {} PyUnicodeObject;
class PyThreadState;
typedef struct _ts PyThreadState;
typedef int Py_ssize_t;
typedef struct bufferinfo Py_buffer;

View File

@ -82,26 +82,6 @@ is_debug() const {
// Instruct the compiler to optimize for the usual case.
return UNLIKELY(is_on(NS_debug));
}
#else
/**
* When NOTIFY_DEBUG is not defined, the categories are never set to "spam" or
* "debug" severities, and these methods are redefined to be static to make it
* more obvious to the compiler.
*/
constexpr bool NotifyCategory::
is_spam() {
return false;
}
/**
* When NOTIFY_DEBUG is not defined, the categories are never set to "spam" or
* "debug" severities, and these methods are redefined to be static to make it
* more obvious to the compiler.
*/
constexpr bool NotifyCategory::
is_debug() {
return false;
}
#endif
/**

View File

@ -55,8 +55,8 @@ PUBLISHED:
INLINE bool is_spam() const;
INLINE bool is_debug() const;
#else
constexpr static bool is_spam();
constexpr static bool is_debug();
constexpr static bool is_spam() { return false; }
constexpr static bool is_debug() { return false; }
#endif
INLINE bool is_info() const;
INLINE bool is_warning() const;

View File

@ -72,12 +72,6 @@ is_spam() {
// Instruct the compiler to optimize for the usual case.
return UNLIKELY(get_unsafe_ptr()->is_spam());
}
#else
template<class GetCategory>
constexpr bool NotifyCategoryProxy<GetCategory>::
is_spam() {
return false;
}
#endif
/**
@ -90,12 +84,6 @@ is_debug() {
// Instruct the compiler to optimize for the usual case.
return UNLIKELY(get_unsafe_ptr()->is_debug());
}
#else
template<class GetCategory>
constexpr bool NotifyCategoryProxy<GetCategory>::
is_debug() {
return false;
}
#endif
/**

View File

@ -75,8 +75,8 @@ public:
INLINE bool is_spam();
INLINE bool is_debug();
#else
constexpr static bool is_spam();
constexpr static bool is_debug();
constexpr static bool is_spam() { return false; }
constexpr static bool is_debug() { return false; }
#endif
INLINE bool is_info();
INLINE bool is_warning();

View File

@ -681,6 +681,9 @@ if (COMPILER == "MSVC"):
IncDirectory("FCOLLADA", GetThirdpartyDir() + "fcollada/include/FCollada")
if (PkgSkip("ASSIMP")==0):
LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/assimp.lib")
path = GetThirdpartyDir() + "assimp/lib/IrrXML.lib"
if os.path.isfile(path):
LibName("ASSIMP", GetThirdpartyDir() + "assimp/lib/IrrXML.lib")
IncDirectory("ASSIMP", GetThirdpartyDir() + "assimp/include/assimp")
if (PkgSkip("SQUISH")==0):
if GetOptimize() <= 2:
@ -947,8 +950,6 @@ if (COMPILER=="GCC"):
if GetTarget() == 'darwin':
LibName("ALWAYS", "-framework AppKit")
if (PkgSkip("OPENCV")==0):
LibName("OPENCV", "-framework QuickTime")
LibName("AGL", "-framework AGL")
LibName("CARBON", "-framework Carbon")
LibName("COCOA", "-framework Cocoa")
@ -1335,9 +1336,10 @@ def CompileCxx(obj,src,opts):
# Work around Apple compiler bug.
cmd += " -U__EXCEPTIONS"
if 'RTTI' not in opts:
target = GetTarget()
if 'RTTI' not in opts and target != "darwin":
# We always disable RTTI on Android for memory usage reasons.
if optlevel >= 4 or GetTarget() == "android":
if optlevel >= 4 or target == "android":
cmd += " -fno-rtti"
if ('SSE2' in opts or not PkgSkip("SSE2")) and not arch.startswith("arm") and arch != 'aarch64':
@ -1597,6 +1599,8 @@ def CompileLib(lib, obj, opts):
else:
cmd = GetAR() + ' cru ' + BracketNameWithQuotes(lib)
for x in obj:
if GetLinkAllStatic() and x.endswith('.a'):
continue
cmd += ' ' + BracketNameWithQuotes(x)
oscmd(cmd)
@ -3161,10 +3165,10 @@ CopyAllHeaders('panda/src/movies')
CopyAllHeaders('panda/src/pgraphnodes')
CopyAllHeaders('panda/src/pgraph')
CopyAllHeaders('panda/src/cull')
CopyAllHeaders('panda/src/display')
CopyAllHeaders('panda/src/chan')
CopyAllHeaders('panda/src/char')
CopyAllHeaders('panda/src/dgraph')
CopyAllHeaders('panda/src/display')
CopyAllHeaders('panda/src/device')
CopyAllHeaders('panda/src/pnmtext')
CopyAllHeaders('panda/src/text')
@ -3297,7 +3301,6 @@ if (PkgSkip("PANDATOOL")==0):
CopyAllHeaders('pandatool/src/ptloader')
CopyAllHeaders('pandatool/src/miscprogs')
CopyAllHeaders('pandatool/src/pstatserver')
CopyAllHeaders('pandatool/src/softprogs')
CopyAllHeaders('pandatool/src/text-stats')
CopyAllHeaders('pandatool/src/vrmlprogs')
CopyAllHeaders('pandatool/src/win-stats')
@ -3553,6 +3556,7 @@ IGATEFILES += [
"dSearchPath.h",
"executionEnvironment.h",
"textEncoder.h",
"textEncoder_ext.h",
"filename.h",
"filename_ext.h",
"globPattern.h",
@ -3817,7 +3821,7 @@ if (not RUNTIME):
if (not RUNTIME):
OPTS=['DIR:panda/src/gobj', 'BUILDING:PANDA', 'NVIDIACG', 'ZLIB', 'SQUISH']
TargetAdd('p3gobj_composite1.obj', opts=OPTS, input='p3gobj_composite1.cxx')
TargetAdd('p3gobj_composite2.obj', opts=OPTS, input='p3gobj_composite2.cxx')
TargetAdd('p3gobj_composite2.obj', opts=OPTS+['BIGOBJ'], input='p3gobj_composite2.cxx')
OPTS=['DIR:panda/src/gobj', 'NVIDIACG', 'ZLIB', 'SQUISH', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/gobj', ["*.h", "*_composite*.cxx"])
@ -3876,38 +3880,6 @@ if (not RUNTIME):
TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull'])
TargetAdd('libp3cull_igate.obj', input='libp3cull.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/chan/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/chan', 'BUILDING:PANDA']
TargetAdd('p3chan_composite1.obj', opts=OPTS, input='p3chan_composite1.cxx')
TargetAdd('p3chan_composite2.obj', opts=OPTS, input='p3chan_composite2.cxx')
OPTS=['DIR:panda/src/chan', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/chan', ["*.h", "*_composite*.cxx"])
IGATEFILES.remove('movingPart.h')
IGATEFILES.remove('animChannelFixed.h')
TargetAdd('libp3chan.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3chan.in', opts=['IMOD:panda3d.core', 'ILIB:libp3chan', 'SRCDIR:panda/src/chan'])
TargetAdd('libp3chan_igate.obj', input='libp3chan.in', opts=["DEPENDENCYONLY"])
# DIRECTORY: panda/src/char/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/char', 'BUILDING:PANDA']
TargetAdd('p3char_composite1.obj', opts=OPTS, input='p3char_composite1.cxx')
TargetAdd('p3char_composite2.obj', opts=OPTS, input='p3char_composite2.cxx')
OPTS=['DIR:panda/src/char', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/char', ["*.h", "*_composite*.cxx"])
TargetAdd('libp3char.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3char.in', opts=['IMOD:panda3d.core', 'ILIB:libp3char', 'SRCDIR:panda/src/char'])
TargetAdd('libp3char_igate.obj', input='libp3char.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/dgraph/
#
@ -3944,6 +3916,7 @@ if (not RUNTIME):
if (not RUNTIME):
OPTS=['DIR:panda/src/display', 'BUILDING:PANDA']
TargetAdd('p3display_graphicsStateGuardian.obj', opts=OPTS, input='graphicsStateGuardian.cxx')
TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx')
TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx')
@ -3962,6 +3935,38 @@ if (not RUNTIME):
TargetAdd('subprocessWindowBuffer.obj', opts=OPTS, input='subprocessWindowBuffer.cxx')
TargetAdd('libp3subprocbuffer.ilb', input='subprocessWindowBuffer.obj')
#
# DIRECTORY: panda/src/chan/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/chan', 'BUILDING:PANDA']
TargetAdd('p3chan_composite1.obj', opts=OPTS, input='p3chan_composite1.cxx')
TargetAdd('p3chan_composite2.obj', opts=OPTS, input='p3chan_composite2.cxx')
OPTS=['DIR:panda/src/chan', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/chan', ["*.h", "*_composite*.cxx"])
IGATEFILES.remove('movingPart.h')
IGATEFILES.remove('animChannelFixed.h')
TargetAdd('libp3chan.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3chan.in', opts=['IMOD:panda3d.core', 'ILIB:libp3chan', 'SRCDIR:panda/src/chan'])
TargetAdd('libp3chan_igate.obj', input='libp3chan.in', opts=["DEPENDENCYONLY"])
# DIRECTORY: panda/src/char/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/char', 'BUILDING:PANDA']
TargetAdd('p3char_composite1.obj', opts=OPTS, input='p3char_composite1.cxx')
TargetAdd('p3char_composite2.obj', opts=OPTS, input='p3char_composite2.cxx')
OPTS=['DIR:panda/src/char', 'PYTHON']
IGATEFILES=GetDirectoryContents('panda/src/char', ["*.h", "*_composite*.cxx"])
TargetAdd('libp3char.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3char.in', opts=['IMOD:panda3d.core', 'ILIB:libp3char', 'SRCDIR:panda/src/char'])
TargetAdd('libp3char_igate.obj', input='libp3char.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/pnmtext/
#
@ -4169,6 +4174,7 @@ if (not RUNTIME):
TargetAdd('libpanda.dll', input='p3device_composite2.obj')
TargetAdd('libpanda.dll', input='p3dgraph_composite1.obj')
TargetAdd('libpanda.dll', input='p3dgraph_composite2.obj')
TargetAdd('libpanda.dll', input='p3display_graphicsStateGuardian.obj')
TargetAdd('libpanda.dll', input='p3display_composite1.obj')
TargetAdd('libpanda.dll', input='p3display_composite2.obj')
TargetAdd('libpanda.dll', input='p3pipeline_composite1.obj')
@ -6348,21 +6354,6 @@ if (PkgSkip("PANDATOOL")==0):
TargetAdd('p3pstatserver_composite1.obj', opts=OPTS, input='p3pstatserver_composite1.cxx')
TargetAdd('libp3pstatserver.lib', input='p3pstatserver_composite1.obj')
#
# DIRECTORY: pandatool/src/softprogs/
#
if (PkgSkip("PANDATOOL")==0):
OPTS=['DIR:pandatool/src/softprogs', 'OPENSSL']
TargetAdd('softcvs_softCVS.obj', opts=OPTS, input='softCVS.cxx')
TargetAdd('softcvs_softFilename.obj', opts=OPTS, input='softFilename.cxx')
TargetAdd('softcvs.exe', input='softcvs_softCVS.obj')
TargetAdd('softcvs.exe', input='softcvs_softFilename.obj')
TargetAdd('softcvs.exe', input='libp3progbase.lib')
TargetAdd('softcvs.exe', input='libp3pandatoolbase.lib')
TargetAdd('softcvs.exe', input=COMMON_PANDA_LIBS)
TargetAdd('softcvs.exe', opts=['ADVAPI'])
#
# DIRECTORY: pandatool/src/text-stats/
#

View File

@ -4770,12 +4770,6 @@
<File RelativePath="..\pandatool\src\ptloader\config_ptloader.h"></File>
<File RelativePath="..\pandatool\src\ptloader\loaderFileTypePandatool.h"></File>
</Filter>
<Filter Name="softprogs">
<File RelativePath="..\pandatool\src\softprogs\softCVS.cxx"></File>
<File RelativePath="..\pandatool\src\softprogs\softFilename.h"></File>
<File RelativePath="..\pandatool\src\softprogs\softCVS.h"></File>
<File RelativePath="..\pandatool\src\softprogs\softFilename.cxx"></File>
</Filter>
<Filter Name="imageprogs">
<File RelativePath="..\pandatool\src\imageprogs\imageTrans.h"></File>
<File RelativePath="..\pandatool\src\imageprogs\imageTransformColors.cxx"></File>
@ -5305,20 +5299,6 @@
<File RelativePath="..\pandatool\src\lwo\lwoSurfaceBlockImage.h"></File>
<File RelativePath="..\pandatool\src\lwo\lwoSurfaceBlockCoordSys.cxx"></File>
</Filter>
<Filter Name="softegg">
<File RelativePath="..\pandatool\src\softegg\soft2Egg.c"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeTree.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeDesc.h"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.I"></File>
<File RelativePath="..\pandatool\src\softegg\config_softegg.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softToEggConverter.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeTree.h"></File>
<File RelativePath="..\pandatool\src\softegg\config_softegg.h"></File>
<File RelativePath="..\pandatool\src\softegg\softNodeDesc.cxx"></File>
<File RelativePath="..\pandatool\src\softegg\softToEggConverter.h"></File>
<File RelativePath="..\pandatool\src\softegg\softEggGroupUserData.h"></File>
</Filter>
<Filter Name="xfileprogs">
<File RelativePath="..\pandatool\src\xfileprogs\eggToX.cxx"></File>
<File RelativePath="..\pandatool\src\xfileprogs\xFileTrans.cxx"></File>

View File

@ -32,14 +32,14 @@ AnimControl(const std::string &name, PartBundle *part,
Namable(name),
_pending_lock(name),
_pending_cvar(_pending_lock),
_bound_joints(BitArray::all_on())
_bound_joints(BitArray::all_on()),
_part(part)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
#endif
_pending = true;
_part = part;
_anim = nullptr;
_channel_index = -1;
set_frame_rate(frame_rate);

View File

@ -39,6 +39,8 @@ class EXPCL_PANDA_CHAN AnimControl : public TypedReferenceCount, public AnimInte
public:
AnimControl(const std::string &name, PartBundle *part,
double frame_rate, int num_frames);
AnimControl(const AnimControl &copy) = delete;
void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
const BitArray &bound_joints);
void set_bound_joints(const BitArray &bound_joints);
@ -82,7 +84,7 @@ private:
// This is a PT(PartGroup) instead of a PT(PartBundle), just because we
// can't include partBundle.h for circular reasons. But it actually keeps a
// pointer to a PartBundle.
PT(PartGroup) _part;
const PT(PartGroup) _part;
PT(AnimBundle) _anim;
int _channel_index;

View File

@ -556,8 +556,15 @@ control_removed(AnimControl *control) {
CDStageWriter cdata(_cycler, pipeline_stage);
ChannelBlend::iterator cbi = cdata->_blend.find(control);
if (cbi != cdata->_blend.end()) {
cdata->_net_blend -= cbi->second;
cdata->_blend.erase(cbi);
cdata->_anim_changed = true;
// We need to make sure that any _effective_channel pointers that point
// to this control are cleared.
if (pipeline_stage == 0) {
determine_effective_channels(cdata);
}
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);

View File

@ -134,6 +134,12 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
if (accelerated) {
properties.set_force_hardware(1);
}
// Cautiously setting this to true. It appears that macOS framebuffers are
// sRGB-capable, but I don't really know how to verify this.
if (color_size == 32 && !color_float) {
properties.set_srgb_color(true);
}
}
/**

View File

@ -12,6 +12,7 @@
*/
#import "cocoaPandaApp.h"
#include "config_cocoadisplay.h"
@implementation CocoaPandaApp
- (void) sendEvent: (NSEvent *) event {

View File

@ -1254,7 +1254,7 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
if (geom->get_primitive_type() == Geom::PT_polygons) {
Thread *current_thread = Thread::get_current_thread();
CPT(GeomVertexData) data = geom->get_vertex_data()->animate_vertices(true, current_thread);
CPT(GeomVertexData) data = geom->get_animated_vertex_data(true, current_thread);
GeomVertexReader vertex(data, InternalName::get_vertex());
int num_primitives = geom->get_num_primitives();

View File

@ -753,7 +753,7 @@ render_frame() {
// frames, so we won't have to recompute it each frame.
int num_drs = win->get_num_active_display_regions();
for (int i = 0; i < num_drs; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
NodePath camera_np = dr->get_camera(current_thread);
if (!camera_np.is_empty()) {
@ -1359,7 +1359,7 @@ is_scene_root(const PandaNode *node) {
if (win->is_active() && win->get_gsg()->is_active()) {
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
NodePath camera = dr->get_camera();
if (camera.is_empty()) {
@ -1435,7 +1435,7 @@ cull_and_draw_together(GraphicsEngine::Windows wlist,
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
cull_and_draw_together(win, dr, current_thread);
}
@ -1539,7 +1539,7 @@ cull_to_bins(GraphicsEngine::Windows wlist, Thread *current_thread) {
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
PT(SceneSetup) scene_setup;
PT(CullResult) cull_result;
@ -1659,7 +1659,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
}
int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) {
DisplayRegion *dr = win->get_active_display_region(i);
PT(DisplayRegion) dr = win->get_active_display_region(i);
if (dr != nullptr) {
do_draw(win, gsg, dr, current_thread);
}

View File

@ -697,9 +697,6 @@ void GraphicsOutput::
remove_all_display_regions() {
LightMutexHolder holder(_lock);
CDWriter cdata(_cycler, true);
cdata->_active_display_regions_stale = true;
TotalDisplayRegions::iterator dri;
for (dri = _total_display_regions.begin();
dri != _total_display_regions.end();
@ -713,6 +710,12 @@ remove_all_display_regions() {
}
_total_display_regions.clear();
_total_display_regions.push_back(_overlay_display_region);
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
cdata->_active_display_regions_stale = true;
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
/**
@ -740,13 +743,8 @@ set_overlay_display_region(DisplayRegion *display_region) {
*/
int GraphicsOutput::
get_num_display_regions() const {
determine_display_regions();
int result;
{
LightMutexHolder holder(_lock);
result = _total_display_regions.size();
}
return result;
LightMutexHolder holder(_lock);
return _total_display_regions.size();
}
/**
@ -1504,13 +1502,15 @@ do_remove_display_region(DisplayRegion *display_region) {
find(_total_display_regions.begin(), _total_display_regions.end(), drp);
if (dri != _total_display_regions.end()) {
// Let's aggressively clean up the display region too.
CDWriter cdata(_cycler, true);
display_region->cleanup();
display_region->_window = nullptr;
_total_display_regions.erase(dri);
cdata->_active_display_regions_stale = true;
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
cdata->_active_display_regions_stale = true;
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
return true;
}

View File

@ -394,6 +394,7 @@ protected:
typedef CycleDataLockedReader<CData> CDLockedReader;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageWriter<CData> CDStageWriter;
protected:
int _creation_flags;

View File

@ -18,7 +18,6 @@
#include "load_dso.h"
#include "config_display.h"
#include "typeRegistry.h"
#include "pset.h"
#include "config_putil.h"
#include <algorithm>
@ -61,8 +60,8 @@ GraphicsPipeSelection() : _lock("GraphicsPipeSelection") {
// Also get the set of modules named in the various aux-display Config
// variables. We'll want to know this when we call load_modules() later.
int num_aux = aux_display.get_num_unique_values();
for (int i = 0; i < num_aux; i++) {
size_t num_aux = aux_display.get_num_unique_values();
for (size_t i = 0; i < num_aux; ++i) {
string name = aux_display.get_unique_value(i);
if (name != _default_display_module) {
_display_modules.push_back(name);
@ -124,9 +123,7 @@ print_pipe_types() const {
LightMutexHolder holder(_lock);
nout << "Known pipe types:" << std::endl;
PipeTypes::const_iterator pi;
for (pi = _pipe_types.begin(); pi != _pipe_types.end(); ++pi) {
const PipeType &pipe_type = (*pi);
for (const PipeType &pipe_type : _pipe_types) {
nout << " " << pipe_type._type << "\n";
}
if (_display_modules.empty()) {
@ -187,11 +184,9 @@ make_pipe(const string &type_name, const string &module_name) {
PT(GraphicsPipe) GraphicsPipeSelection::
make_pipe(TypeHandle type) {
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
// First, look for an exact match of the requested type.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type == type) {
// Here's an exact match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -202,8 +197,7 @@ make_pipe(TypeHandle type) {
}
// Now look for a more-specific type.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type.is_derived_from(type)) {
// Here's an approximate match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -215,8 +209,7 @@ make_pipe(TypeHandle type) {
// Couldn't find any match; load the default module and try again.
load_default_module();
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type.is_derived_from(type)) {
// Here's an approximate match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -260,13 +253,11 @@ make_default_pipe() {
load_default_module();
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
if (!_default_pipe_name.empty()) {
// First, look for an exact match of the default type name from the
// Configrc file (excepting case and hyphenunderscore).
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (cmp_nocase_uh(ptype._type.get_name(), _default_pipe_name) == 0) {
// Here's an exact match.
PT(GraphicsPipe) pipe = (*ptype._constructor)();
@ -278,8 +269,7 @@ make_default_pipe() {
// No match; look for a substring match.
string preferred_name = downcase(_default_pipe_name);
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
string ptype_name = downcase(ptype._type.get_name());
if (ptype_name.find(preferred_name) != string::npos) {
// Here's a substring match.
@ -292,8 +282,7 @@ make_default_pipe() {
}
// Couldn't find a matching pipe type; choose the first one on the list.
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
PT(GraphicsPipe) pipe = (*ptype._constructor)();
if (pipe != nullptr) {
return pipe;
@ -310,9 +299,8 @@ make_default_pipe() {
*/
void GraphicsPipeSelection::
load_aux_modules() {
DisplayModules::iterator di;
for (di = _display_modules.begin(); di != _display_modules.end(); ++di) {
load_named_module(*di);
for (const string &module : _display_modules) {
load_named_module(module);
}
_display_modules.clear();
@ -337,9 +325,7 @@ add_pipe_type(TypeHandle type, PipeConstructorFunc *func) {
// First, make sure we don't already have a GraphicsPipe of this type.
LightMutexHolder holder(_lock);
PipeTypes::const_iterator ti;
for (ti = _pipe_types.begin(); ti != _pipe_types.end(); ++ti) {
const PipeType &ptype = (*ti);
for (const PipeType &ptype : _pipe_types) {
if (ptype._type == type) {
display_cat->warning()
<< "Attempt to register GraphicsPipe type " << type
@ -375,8 +361,8 @@ do_load_default_module() {
load_named_module(_default_display_module);
DisplayModules::iterator di =
find(_display_modules.begin(), _display_modules.end(),
_default_display_module);
std::find(_display_modules.begin(), _display_modules.end(),
_default_display_module);
if (di != _display_modules.end()) {
_display_modules.erase(di);
}

View File

@ -24,7 +24,6 @@
#include "renderBuffer.h"
#include "light.h"
#include "planeNode.h"
#include "ambientLight.h"
#include "throw_event.h"
#include "clockObject.h"
#include "pStatTimer.h"
@ -60,7 +59,6 @@
#include "fogAttrib.h"
#include "config_pstatclient.h"
#include <algorithm>
#include <limits.h>
using std::string;
@ -932,12 +930,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
case Shader::SMO_frame_time: {
PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
return &t;
}
case Shader::SMO_frame_delta: {
PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
return &t;
}
case Shader::SMO_texpad_x: {
@ -949,7 +947,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
double cx = (sx * 0.5) / tex->get_x_size();
double cy = (sy * 0.5) / tex->get_y_size();
double cz = (sz * 0.5) / tex->get_z_size();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cx,cy,cz,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
return &t;
}
case Shader::SMO_texpix_x: {
@ -958,7 +956,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
double px = 1.0 / tex->get_x_size();
double py = 1.0 / tex->get_y_size();
double pz = 1.0 / tex->get_z_size();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,px,py,pz,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
return &t;
}
case Shader::SMO_attr_material: {
@ -966,7 +964,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
// Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
if (target_material->is_off()) {
t = LMatrix4(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0);
t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
}
Material *m = target_material->get_material();
@ -975,17 +973,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
LVecBase4 const &emm = m->get_emission();
LVecBase4 spc = m->get_specular();
spc[3] = m->get_shininess();
t = LMatrix4(amb[0],amb[1],amb[2],amb[3],
dif[0],dif[1],dif[2],dif[3],
emm[0],emm[1],emm[2],emm[3],
spc[0],spc[1],spc[2],spc[3]);
t.set(amb[0], amb[1], amb[2], amb[3],
dif[0], dif[1], dif[2], dif[3],
emm[0], emm[1], emm[2], emm[3],
spc[0], spc[1], spc[2], spc[3]);
return &t;
}
case Shader::SMO_attr_material2: {
const MaterialAttrib *target_material = (const MaterialAttrib *)
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
if (target_material->is_off()) {
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
return &t;
}
Material *m = target_material->get_material();
@ -1000,7 +998,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 c = target_color->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_attr_colorscale: {
@ -1010,7 +1008,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 cs = target_color->get_scale();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,cs[0],cs[1],cs[2],cs[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
return &t;
}
case Shader::SMO_attr_fog: {
@ -1022,7 +1020,8 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
PN_stdfloat start, end;
fog->get_linear_range(start, end);
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,fog->get_exp_density(),start,end,1.0f/(end-start));
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
fog->get_exp_density(), start, end, 1.0f / (end - start));
return &t;
}
case Shader::SMO_attr_fogcolor: {
@ -1033,7 +1032,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ones_mat();
}
LVecBase4 c = fog->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_alight_x: {
@ -1042,7 +1041,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
AmbientLight *lt;
DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
LColor const &c = lt->get_color();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
return &t;
}
case Shader::SMO_satten_x: {
@ -1052,7 +1051,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat());
LVecBase3 const &a = lt->get_attenuation();
PN_stdfloat x = lt->get_exponent();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,a[0],a[1],a[2],x);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
return &t;
}
case Shader::SMO_dlight_x: {
@ -1069,7 +1068,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
d.normalize();
LVecBase3 h = d + LVecBase3(0,-1,0);
h.normalize();
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],c[3],d[0],d[1],d[2],0,h[0],h[1],h[2],0);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], c[3],
d[0], d[1], d[2], 0,
h[0], h[1], h[2], 0);
return &t;
}
case Shader::SMO_plight_x: {
@ -1087,7 +1089,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
Lens *lens = lt->get_lens(0);
PN_stdfloat lnear = lens->get_near();
PN_stdfloat lfar = lens->get_far();
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],lnear,a[0],a[1],a[2],lfar);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], s[3],
p[0], p[1], p[2], lnear,
a[0], a[1], a[2], lfar);
return &t;
}
case Shader::SMO_slight_x: {
@ -1105,7 +1110,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
_scene_setup->get_world_transform()->get_mat();
LVecBase3 p = t.xform_point(lens->get_nodal_point());
LVecBase3 d = -(t.xform_vec(lens->get_view_vector()));
t = LMatrix4(c[0],c[1],c[2],c[3],s[0],s[1],s[2],s[3],p[0],p[1],p[2],0,d[0],d[1],d[2],cutoff);
t.set(c[0], c[1], c[2], c[3],
s[0], s[1], s[2], s[3],
p[0], p[1], p[2], 0,
d[0], d[1], d[2], cutoff);
return &t;
}
case Shader::SMO_light_ambient: {
@ -1149,7 +1157,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
index < ta->get_num_on_stages()) {
LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
return &t;
} else {
return &LMatrix4::ident_mat();
@ -1173,7 +1181,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
index < ta->get_num_on_stages()) {
TextureStage *ts = ta->get_on_stage(index);
PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha);
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,v,v,v,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
return &t;
} else {
return &LMatrix4::zeros_mat();
@ -1185,7 +1193,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
const PlaneNode *plane_node;
DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
LPlane p = plane_node->get_plane();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
return &t;
}
case Shader::SMO_clipplane_x: {
@ -1235,10 +1243,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
case Shader::SMO_vec_constant_x: {
const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
const PN_stdfloat *data = input.get_data();
t = LMatrix4(data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3]);
t.set(data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3]);
return &t;
}
case Shader::SMO_world_to_view: {
@ -1394,10 +1402,10 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
// There is an input specifying precisely this whole thing, with dot and
// all. Support this, even if only for backward compatibility.
const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
t = LMatrix4(data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3],
data[0],data[1],data[2],data[3]);
t.set(data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3],
data[0], data[1], data[2], data[3]);
return &t;
}
@ -1578,11 +1586,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
} else if (attrib == IN_position) {
if (np.is_empty()) {
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no position.
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
@ -1591,7 +1599,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
LVector3 dir = -(light->get_direction() * transform->get_mat());
dir *= _scene_setup->get_cs_world_transform()->get_mat();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
return &t;
} else {
LightLensNode *light;
@ -1611,11 +1619,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
} else if (attrib == IN_halfVector) {
if (np.is_empty()) {
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no half-vector.
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
@ -1627,7 +1635,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
dir.normalize();
dir += LVector3(0, 0, 1);
dir.normalize();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,dir[0],dir[1],dir[2],1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
return &t;
} else {
LightLensNode *light;
@ -1644,7 +1652,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
pos.normalize();
pos += LVector3(0, 0, 1);
pos.normalize();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,pos[0],pos[1],pos[2],1);
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
return &t;
}
@ -2722,7 +2730,7 @@ do_issue_color_scale() {
}
if (_alpha_scale_via_texture && !_has_scene_graph_color &&
target_color_scale->has_alpha_scale()) {
_vertex_colors_enabled && target_color_scale->has_alpha_scale()) {
// This color scale will set a special texture--so again, clear the
// texture.
_state_mask.clear_bit(TextureAttrib::get_class_slot());
@ -3168,6 +3176,17 @@ determine_light_color_scale() {
_scene_graph_color[3] * _current_color_scale[3]);
}
} else if (!_vertex_colors_enabled) {
// We don't have a scene graph color, but we don't want to enable vertex
// colors either, so we still need to force a white material color in
// absence of any other color.
_has_material_force_color = true;
_material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
_light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
if (!_color_blend_involves_color_scale && _color_scale_enabled) {
_material_force_color.componentwise_mult(_current_color_scale);
}
} else {
// Otherise, leave the materials alone, but we might still scale the
// lights.

View File

@ -32,6 +32,7 @@ class GraphicsWindow;
class EXPCL_PANDA_DISPLAY GraphicsWindowProc {
public:
GraphicsWindowProc();
virtual ~GraphicsWindowProc() = default;
#if defined(__WIN32__) || defined(_WIN32)
virtual LONG wnd_proc(GraphicsWindow* graphicsWindow, HWND hwnd,
UINT msg, WPARAM wparam, LPARAM lparam);

View File

@ -1,5 +1,4 @@
#include "graphicsPipeSelection.cxx"
#include "graphicsStateGuardian.cxx"
#include "graphicsThreadingModel.cxx"
#include "graphicsWindow.cxx"
#include "graphicsWindowProc.cxx"

View File

@ -12,10 +12,14 @@
*/
#include "standardMunger.h"
#include "renderState.h"
#include "graphicsStateGuardian.h"
#include "config_gobj.h"
#include "displayRegion.h"
#include "graphicsStateGuardian.h"
#include "lightAttrib.h"
#include "materialAttrib.h"
#include "renderState.h"
TypeHandle StandardMunger::_type_handle;
@ -55,24 +59,10 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
const ColorScaleAttrib *color_scale_attrib;
if (state->get_attrib(color_attrib) &&
color_attrib->get_color_type() == ColorAttrib::T_flat) {
color_attrib->get_color_type() != ColorAttrib::T_vertex) {
if (!get_gsg()->get_color_scale_via_lighting()) {
// We only need to munge the color directly if the GSG says it can't
// cheat the color via lighting (presumably, in this case, by applying
// a material).
_color = color_attrib->get_color();
if (state->get_attrib(color_scale_attrib) &&
color_scale_attrib->has_scale()) {
const LVecBase4 &cs = color_scale_attrib->get_scale();
_color.set(_color[0] * cs[0],
_color[1] * cs[1],
_color[2] * cs[2],
_color[3] * cs[3]);
}
_munge_color = true;
_should_munge_state = true;
}
// In this case, we don't need to munge anything as we can apply the
// color and color scale via glColor4f.
} else if (state->get_attrib(color_scale_attrib) &&
color_scale_attrib->has_scale()) {

View File

@ -51,12 +51,13 @@ private:
NumericType _numeric_type;
Contents _contents;
bool _munge_color;
bool _munge_color_scale;
bool _auto_shader;
bool _shader_skinning;
bool _remove_material;
protected:
bool _munge_color;
bool _munge_color_scale;
LColor _color;
LVecBase4 _color_scale;

View File

@ -18,6 +18,8 @@
#include "graphicsEngine.h"
#include "config_display.h"
#include "nativeWindowHandle.h"
#include "mouseButton.h"
#include "throw_event.h"
using std::string;

View File

@ -484,8 +484,7 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
const LMatrix4 &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv;
// Iterate through all the vertices in the Geom.
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
vdata = vdata->animate_vertices(true, current_thread);
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(true, current_thread);
CPT(GeomVertexFormat) vformat = vdata->get_format();
if (!vformat->has_column(_texcoord_name) || (_texcoord_3d && vformat->get_column(_texcoord_name)->get_num_components() < 3)) {
@ -507,7 +506,7 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
PT(GeomVertexData) modify_vdata = geom->modify_vertex_data();
// Maybe the vdata has animation that we should consider.
CPT(GeomVertexData) animated_vdata = geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread);
CPT(GeomVertexData) animated_vdata = geom->get_animated_vertex_data(true, current_thread);
GeomVertexWriter texcoord(modify_vdata, _texcoord_name, current_thread);
GeomVertexWriter color(modify_vdata, current_thread);
@ -674,9 +673,8 @@ make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4 &rel_mat) {
Thread *current_thread = Thread::get_current_thread();
PT(Geom) new_geom = geom->make_copy();
new_geom->set_vertex_data(new_geom->get_animated_vertex_data(false, current_thread));
PT(GeomVertexData) vdata = new_geom->modify_vertex_data();
new_geom->set_vertex_data(vdata->animate_vertices(false, current_thread));
vdata = new_geom->modify_vertex_data();
GeomVertexRewriter vertex(vdata, InternalName::get_vertex());
while (!vertex.is_at_end()) {
LVertex vert = vertex.get_data3();

View File

@ -10,34 +10,3 @@
* @author drose
* @date 2005-03-11
*/
/**
*
*/
INLINE DXGeomMunger9::
DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) :
StandardMunger(gsg, state, 1, NT_packed_dabc, C_color),
_texture(nullptr),
_tex_gen(nullptr)
{
const TextureAttrib *texture = nullptr;
const TexGenAttrib *tex_gen = nullptr;
state->get_attrib(texture);
state->get_attrib(tex_gen);
_texture = texture;
_tex_gen = tex_gen;
_filtered_texture = nullptr;
_reffed_filtered_texture = false;
if (texture != nullptr) {
_filtered_texture = texture->filter_to_max(gsg->get_max_texture_stages());
if (_filtered_texture != texture) {
_filtered_texture->ref();
_reffed_filtered_texture = true;
}
}
// Set a callback to unregister ourselves when either the Texture or the
// TexGen object gets deleted.
_texture.add_callback(this);
_tex_gen.add_callback(this);
}

View File

@ -19,6 +19,66 @@
GeomMunger *DXGeomMunger9::_deleted_chain = nullptr;
TypeHandle DXGeomMunger9::_type_handle;
/**
*
*/
DXGeomMunger9::
DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) :
StandardMunger(gsg, state, 1, NT_packed_dabc, C_color),
_texture(nullptr),
_tex_gen(nullptr)
{
const TextureAttrib *texture = nullptr;
const TexGenAttrib *tex_gen = nullptr;
state->get_attrib(texture);
state->get_attrib(tex_gen);
_texture = texture;
_tex_gen = tex_gen;
if (!gsg->get_color_scale_via_lighting()) {
// We might need to munge the colors, if we are overriding the vertex
// colors and the GSG can't cheat the color via lighting.
const ColorAttrib *color_attrib;
const ShaderAttrib *shader_attrib;
state->get_attrib_def(shader_attrib);
if (!shader_attrib->auto_shader() &&
shader_attrib->get_shader() == nullptr &&
state->get_attrib(color_attrib) &&
color_attrib->get_color_type() != ColorAttrib::T_vertex) {
if (color_attrib->get_color_type() == ColorAttrib::T_off) {
_color.set(1, 1, 1, 1);
} else {
_color = color_attrib->get_color();
}
const ColorScaleAttrib *color_scale_attrib;
if (state->get_attrib(color_scale_attrib) &&
color_scale_attrib->has_scale()) {
_color.componentwise_mult(color_scale_attrib->get_scale());
}
_munge_color = true;
_should_munge_state = true;
}
}
_filtered_texture = nullptr;
_reffed_filtered_texture = false;
if (texture != nullptr) {
_filtered_texture = texture->filter_to_max(gsg->get_max_texture_stages());
if (_filtered_texture != texture) {
_filtered_texture->ref();
_reffed_filtered_texture = true;
}
}
// Set a callback to unregister ourselves when either the Texture or the
// TexGen object gets deleted.
_texture.add_callback(this);
_tex_gen.add_callback(this);
}
/**
*
*/

View File

@ -28,7 +28,7 @@
*/
class EXPCL_PANDADX DXGeomMunger9 : public StandardMunger, public WeakPointerCallback {
public:
INLINE DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state);
DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state);
virtual ~DXGeomMunger9();
ALLOC_DELETED_CHAIN(DXGeomMunger9);

View File

@ -140,6 +140,7 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) :
_last_fvf = 0;
_num_bound_streams = 0;
_white_vbuffer = nullptr;
_vertex_shader_version_major = 0;
_vertex_shader_version_minor = 0;
@ -798,9 +799,9 @@ clear(DrawableRegion *clearable) {
main_flags |= D3DCLEAR_TARGET;
}
if (clearable->get_clear_depth_active()) {
if (clearable->get_clear_depth_active() &&
_screen->_presentation_params.EnableAutoDepthStencil) {
aux_flags |= D3DCLEAR_ZBUFFER;
nassertv(_screen->_presentation_params.EnableAutoDepthStencil);
}
if (clearable->get_clear_stencil_active()) {
@ -4545,6 +4546,11 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
release_all_vertex_buffers();
release_all_index_buffers();
if (_white_vbuffer != nullptr) {
_white_vbuffer->Release();
_white_vbuffer = nullptr;
}
// must be called before reset
Thread *current_thread = Thread::get_current_thread();
_prepared_objects->begin_frame(this, current_thread);
@ -5234,9 +5240,9 @@ calc_fb_properties(DWORD cformat, DWORD dformat,
#define GAMMA_1 (255.0 * 256.0)
static bool _gamma_table_initialized = false;
static unsigned short _orignial_gamma_table [256 * 3];
static unsigned short _original_gamma_table [256 * 3];
void _create_gamma_table (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) {
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) {
int i;
double gamma_correction;
@ -5298,7 +5304,7 @@ get_gamma_table(void) {
HDC hdc = GetDC(nullptr);
if (hdc) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) {
if (GetDeviceGammaRamp (hdc, (LPVOID) _original_gamma_table)) {
_gamma_table_initialized = true;
get = true;
}
@ -5323,10 +5329,10 @@ static_set_gamma(bool restore, PN_stdfloat gamma) {
unsigned short ramp [256 * 3];
if (restore && _gamma_table_initialized) {
_create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_dx9 (gamma, &_original_gamma_table [0], &_original_gamma_table [256], &_original_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]);
}
else {
_create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
_create_gamma_table_dx9 (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]);
}
if (SetDeviceGammaRamp (hdc, ramp)) {
@ -5404,6 +5410,40 @@ set_cg_device(LPDIRECT3DDEVICE9 cg_device) {
#endif // HAVE_CG
}
/**
* Returns a vertex buffer containing only a full-white color.
*/
LPDIRECT3DVERTEXBUFFER9 DXGraphicsStateGuardian9::
get_white_vbuffer() {
if (_white_vbuffer != nullptr) {
return _white_vbuffer;
}
LPDIRECT3DVERTEXBUFFER9 vbuffer;
HRESULT hr;
hr = _screen->_d3d_device->CreateVertexBuffer(sizeof(D3DCOLOR), D3DUSAGE_WRITEONLY, D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &vbuffer, nullptr);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
return nullptr;
}
D3DCOLOR *local_pointer;
hr = vbuffer->Lock(0, sizeof(D3DCOLOR), (void **) &local_pointer, D3DLOCK_DISCARD);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
return false;
}
*local_pointer = D3DCOLOR_ARGB(255, 255, 255, 255);
vbuffer->Unlock();
_white_vbuffer = vbuffer;
return vbuffer;
}
typedef std::string KEY;
typedef struct _KEY_ELEMENT

View File

@ -168,6 +168,7 @@ public:
static void set_cg_device(LPDIRECT3DDEVICE9 cg_device);
virtual bool get_supports_cg_profile(const std::string &name) const;
LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer();
protected:
void do_issue_transform();
@ -274,12 +275,6 @@ protected:
RenderBuffer::Type _cur_read_pixel_buffer; // source for copy_pixel_buffer operation
PN_stdfloat _material_ambient;
PN_stdfloat _material_diffuse;
PN_stdfloat _material_specular;
PN_stdfloat _material_shininess;
PN_stdfloat _material_emission;
enum DxgsgFogType {
None,
PerVertexFog=D3DRS_FOGVERTEXMODE,
@ -320,6 +315,7 @@ protected:
DWORD _last_fvf;
int _num_bound_streams;
LPDIRECT3DVERTEXBUFFER9 _white_vbuffer;
// Cache the data necessary to bind each particular light each frame, so if
// we bind a given light multiple times, we only have to compute its data

View File

@ -1,269 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dxInput9.cxx
* @author angelina jolie
* @date 1999-10-07
*/
#include "config_wdxdisplay9.h"
#include "dxInput9.h"
#define AXIS_RESOLUTION 2000 // use this many levels of resolution by default (could be more if needed and device supported it)
#define AXIS_RANGE_CENTERED // if defined, axis range is centered on 0, instead of starting on 0
using std::endl;
BOOL CALLBACK EnumGameCtrlsCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext ) {
DI_DeviceInfos *pDevInfos = (DI_DeviceInfos *)pContext;
(*pDevInfos).push_back(*pdidInstance);
if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "Found DevType 0x" << (void*)pdidInstance->dwDevType << ": " << pdidInstance->tszInstanceName << ": " << pdidInstance->tszProductName <<endl;
return DIENUM_CONTINUE;
}
extern BOOL CALLBACK EnumObjectsCallbackJoystick(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext);
DInput9Info::DInput9Info() {
_pDInput9 = nullptr;
_hDInputDLL = nullptr;
_JoystickPollTimer = nullptr;
}
DInput9Info::~DInput9Info() {
for(UINT i=0;i<_DeviceList.size();i++) {
_DeviceList[i]->Unacquire();
SAFE_RELEASE(_DeviceList[i]);
}
// bugbug: need to handle this if(_JoystickPollTimer!=NULL) KillTimer(...)
SAFE_RELEASE(_pDInput9);
if(_hDInputDLL) {
FreeLibrary(_hDInputDLL);
_hDInputDLL=nullptr;
}
}
bool DInput9Info::InitDirectInput() {
HRESULT hr;
// assumes dx9 exists use dynamic load so non-dinput programs don't have
// to load dinput
#define DLLNAME "dinput9.dll"
#define DINPUTCREATE "DirectInput9Create"
HINSTANCE _hDInputDLL = LoadLibrary(DLLNAME);
if(_hDInputDLL == 0) {
wdxdisplay_cat.fatal() << "LoadLibrary(" << DLLNAME <<") failed!, error=" << GetLastError() << endl;
exit(1);
}
typedef HRESULT (WINAPI * LPDIRECTINPUT9CREATE)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
LPDIRECTINPUT9CREATE pDInputCreate9;
pDInputCreate9 = (LPDIRECTINPUT9CREATE) GetProcAddress(_hDInputDLL,DINPUTCREATE);
if(pDInputCreate9 == nullptr) {
wdxdisplay_cat.fatal() << "GetProcAddr failed for " << DINPUTCREATE << endl;
exit(1);
}
// Register with the DirectInput subsystem and get a pointer to a
// IDirectInput interface we can use. Create a DInput object
if( FAILED( hr = (*pDInputCreate9)(GetModuleHandle(nullptr), DIRECTINPUT_VERSION,
IID_IDirectInput9, (VOID**)&_pDInput9, nullptr ) ) ) {
wdxdisplay_cat.error() << DINPUTCREATE << "failed" << D3DERRORSTRING(hr);
return false;
}
// enum all the joysticks,etc (but not keybdmouse)
if( FAILED( hr = _pDInput9->EnumDevices(DI9DEVCLASS_GAMECTRL,
EnumGameCtrlsCallback,
(LPVOID)&_DevInfos, DIEDFL_ATTACHEDONLY ) ) ) {
wdxdisplay_cat.error() << "EnumDevices failed" << D3DERRORSTRING(hr);
return false;
}
return true;
}
bool DInput9Info::CreateJoystickOrPad(HWND _window) {
bool bFoundDev = false;
UINT devnum=0;
char *errstr=nullptr;
// look through the list for the first joystick or gamepad
for(;devnum<_DevInfos.size();devnum++) {
DWORD devType = GET_DIDEVICE_TYPE(_DevInfos[devnum].dwDevType);
if((devType==DI9DEVTYPE_GAMEPAD) ||(devType==DI9DEVTYPE_JOYSTICK)) {
bFoundDev=true;
break;
}
}
if(!bFoundDev) {
wdxdisplay_cat.error() << "Cant find an attached Joystick or GamePad!\n";
return false;
}
LPDIRECTINPUTDEVICE9 pJoyDevice;
// Obtain an interface to the enumerated joystick.
HRESULT hr = _pDInput9->CreateDevice(_DevInfos[devnum].guidInstance, &pJoyDevice, nullptr );
if(FAILED(hr)) {
errstr="CreateDevice";
goto handle_error;
}
assert(pJoyDevice!=nullptr);
_DeviceList.push_back(pJoyDevice);
// Set the data format to "simple joystick" - a predefined data format A
// data format specifies which controls on a device we are interested in,
// and how they should be reported. This tells DInput that we will be
// passing a DIJOYSTATE2 structure to
// IDirectInputDevice::GetDeviceState().
hr = pJoyDevice->SetDataFormat(&c_dfDIJoystick2);
if(FAILED(hr)) {
errstr="SetDataFormat";
goto handle_error;
}
// must be called AFTER SetDataFormat to get all the proper flags
DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps);
hr = pJoyDevice->GetCapabilities(&DIDevCaps);
assert(SUCCEEDED(hr));
_DevCaps.push_back(DIDevCaps);
if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "Joy/Pad has " << DIDevCaps.dwAxes << " Axes, " << DIDevCaps.dwButtons << " Buttons, " << DIDevCaps.dwPOVs << " POVs" << endl;
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
hr = pJoyDevice->SetCooperativeLevel( _window, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if(FAILED(hr)) {
errstr="SetCooperativeLevel";
goto handle_error;
}
// set the minmax values property for discovered axes.
hr = pJoyDevice->EnumObjects(EnumObjectsCallbackJoystick, (LPVOID)pJoyDevice, DIDFT_AXIS);
if(FAILED(hr)) {
errstr="EnumObjects";
goto handle_error;
}
return true;
handle_error:
wdxdisplay_cat.error() << errstr << " failed for (" << _DevInfos[devnum].tszInstanceName << ":" << _DevInfos[devnum].tszProductName << ")" << D3DERRORSTRING(hr);
return false;
}
// ---------------------------------------------------------------------------
// -- Name: EnumObjectsCallback() Desc: Callback function for enumerating
// objects (axes, buttons, POVs) on a joystick. This function enables user
// interface elements for objects that are found to exist, and scales axes
// minmax values. -----------------------------------------------------------
// ------------------
BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext ) {
LPDIRECTINPUTDEVICE9 pJoyDevice = (LPDIRECTINPUTDEVICE9) pContext;
HRESULT hr;
// For axes that are returned, set the DIPROP_RANGE property for the
// enumerated axis in order to scale minmax values.
if( pdidoi->dwType & DIDFT_AXIS ) {
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
#ifdef AXIS_RANGE_CENTERED
diprg.lMin = -AXIS_RESOLUTION/2;
diprg.lMax = +AXIS_RESOLUTION/2;
#else
diprg.lMin = 0;
diprg.lMax = +AXIS_RESOLUTION;
#endif
// Set the range for the axis
hr = pJoyDevice->SetProperty( DIPROP_RANGE, &diprg.diph);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "SetProperty on axis failed" << D3DERRORSTRING(hr);
return DIENUM_STOP;
}
}
return DIENUM_CONTINUE;
}
bool DInput9Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) {
LPDIRECTINPUTDEVICE9 pJoystick = _DeviceList[devnum];
assert(pJoystick!=nullptr);
HRESULT hr;
char *errstr;
// Poll the device to read the current state
hr = pJoystick->Poll();
if( FAILED(hr) ) {
// DInput is telling us that the input stream has been interrupted.
// We aren't tracking any state between polls, so we don't have any
// special reset that needs to be done. We just re-acquire and try
// again.
if((hr==DIERR_NOTACQUIRED)||(hr == DIERR_INPUTLOST)) {
hr = pJoystick->Acquire();
if(FAILED(hr)) {
if(wdxdisplay_cat.is_spam())
wdxdisplay_cat.spam() << "Acquire failed" << D3DERRORSTRING(hr);
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This may
// occur when the app is minimized or in the process of
// switching, so just try again later
return false;
}
hr = pJoystick->Poll();
if(FAILED(hr)) {
// should never happen!
errstr = "Poll after successful Acquire failed";
goto handle_error;
}
} else {
errstr = "Unknown Poll failure";
goto handle_error;
}
}
// should we make a vector of devstate dataformats to generalize this fn
// for all device types?
// Get the input's device state
hr = pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js);
if(FAILED(hr)) {
errstr = "GetDeviceState failed";
goto handle_error;
}
return true;
handle_error:
wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr);
return false;
}

View File

@ -1,40 +0,0 @@
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file dxInput9.h
* @author blllyjo
* @date 1999-10-07
*/
#ifndef DXINPUT9_H
#define DXINPUT9_H
#define DIRECTINPUT_VERSION 0x900
#include <dinput.h>
typedef std::vector<DIDEVICEINSTANCE> DI_DeviceInfos;
typedef std::vector<DIDEVICEOBJECTINSTANCE> DI_DeviceObjInfos;
class DInput9Info {
public:
DInput9Info();
~DInput9Info();
bool InitDirectInput();
bool CreateJoystickOrPad(HWND _window);
bool ReadJoystick(int devnum, DIJOYSTATE2 &js);
HINSTANCE _hDInputDLL;
UINT_PTR _JoystickPollTimer;
LPDIRECTINPUT8 _pDInput9;
DI_DeviceInfos _DevInfos;
// arrays for all created devices. Should probably put these together in a
// struct, along with the data fmt info
std::vector<LPDIRECTINPUTDEVICE8> _DeviceList;
std::vector<DIDEVCAPS> _DevCaps;
};
#endif

View File

@ -390,6 +390,8 @@ update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
// arrays ("streams"), and we repeatedly iterate the parameters to pull
// out only those for a single stream.
bool apply_white_color = false;
int number_of_arrays = gsg->_data_reader->get_num_arrays();
for (int array_index = 0; array_index < number_of_arrays; ++array_index) {
const GeomVertexArrayDataHandle* array_reader =
@ -423,6 +425,11 @@ update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
}
}
if (name == InternalName::get_color() && !gsg->_vertex_colors_enabled) {
apply_white_color = true;
continue;
}
const GeomVertexArrayDataHandle *param_array_reader;
Geom::NumericType numeric_type;
int num_values, start, stride;
@ -435,6 +442,9 @@ update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
// shader parameter, which can cause Bad Things to happen so I'd
// like to at least get a hint as to what's gone wrong.
dxgsg9_cat.info() << "Geometry contains no data for shader parameter " << *name << "\n";
if (name == InternalName::get_color()) {
apply_white_color = true;
}
continue;
}
@ -564,6 +574,19 @@ update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
_num_bound_streams = number_of_arrays;
if (apply_white_color) {
// The shader needs a vertex color, but vertex colors are disabled.
// Bind a vertex buffer containing only one white colour.
int array_index = number_of_arrays;
LPDIRECT3DVERTEXBUFFER9 vbuffer = gsg->get_white_vbuffer();
hr = device->SetStreamSource(array_index, vbuffer, 0, 0);
if (FAILED(hr)) {
dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
}
vertex_element_array->add_diffuse_color_vertex_element(array_index, 0);
++_num_bound_streams;
}
if (_vertex_element_array != nullptr &&
_vertex_element_array->add_end_vertex_element()) {
if (dxgsg9_cat.is_debug()) {

View File

@ -1229,7 +1229,10 @@ init_resized_window() {
DWORD flags;
D3DCOLOR clear_color;
flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER;
flags = D3DCLEAR_TARGET;
if (_fb_properties.get_depth_bits() > 0) {
flags |= D3DCLEAR_ZBUFFER;
}
clear_color = 0x00000000;
hr = _wcontext._d3d_device-> Clear (0, nullptr, flags, clear_color, 0.0f, 0);
if (FAILED(hr)) {

View File

@ -17,7 +17,6 @@
#include "pandabase.h"
#include "winGraphicsWindow.h"
#include "dxGraphicsStateGuardian9.h"
#include "dxInput9.h"
#include "wdxGraphicsPipe9.h"
class wdxGraphicsPipe9;

View File

@ -38,7 +38,8 @@ INLINE void set_matrix_view(Py_buffer &view, int flags, int length, int size, bo
} else if (size == 4 && double_prec) {
mat_size = sizeof(UnalignedLMatrix4d);
} else {
assert(false);
nassertv_always(false);
return; // Make sure compiler knows control flow doesn't proceed.
}
view.len = length * mat_size;

View File

@ -97,11 +97,11 @@ __getbuffer__(PyObject *self, Py_buffer *view, int flags) const;
#ifdef _MSC_VER
// Ugh... MSVC needs this because they still don't have a decent linker.
#include "PTA_uchar.h"
#include "PTA_ushort.h"
#include "PTA_float.h"
#include "PTA_double.h"
#include "PTA_int.h"
#include "pta_uchar.h"
#include "pta_ushort.h"
#include "pta_float.h"
#include "pta_double.h"
#include "pta_int.h"
template class EXPORT_THIS Extension<PTA_uchar>;
template class EXPORT_THIS Extension<PTA_ushort>;

View File

@ -51,7 +51,7 @@
// OpenGL ES 2 has no fixed-function pipeline.
#undef SUPPORT_FIXED_FUNCTION
#ifdef IS_OSX
#ifdef BUILD_IPHONE
#include <OpenGLES/ES2/gl.h>
// #include <OpenGLESES2glext.h>
#else

View File

@ -54,7 +54,7 @@
#define __glext_h_
#define ES1_GLEXT_H_GUARD
#ifdef IS_OSX
#ifdef BUILD_IPHONE
#include <OpenGLES/ES1/gl.h>
// #include <OpenGLESES1glext.h>
#else

View File

@ -226,12 +226,14 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
if (!resource) {
resource = "unknown";
}
GLCAT.error()
<< "Could not find Cg varying " << cgGetParameterName(p);
if (attribname) {
GLCAT.error(false) << " : " << attribname;
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Could not find Cg varying " << cgGetParameterName(p);
if (attribname) {
GLCAT.debug(false) << " : " << attribname;
}
GLCAT.debug(false) << " (" << resource << ") in the compiled GLSL program.\n";
}
GLCAT.error(false) << " (" << resource << ") in the compiled GLSL program.\n";
} else if (loc != 0 && bind._id._name == "vtx_position") {
// We really have to bind the vertex position to attribute 0, since
@ -312,10 +314,10 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
GLCAT.debug(false)
<< " is bound to a conventional attribute (" << resource << ")\n";
}
}
if (loc == CA_unknown) {
// Suggest fix to developer.
GLCAT.error() << "Try using a different semantic.\n";
if (loc == CA_unknown) {
// Suggest fix to developer.
GLCAT.debug() << "Try using a different semantic.\n";
}
}
#endif

View File

@ -1097,6 +1097,15 @@ bind_slot_multisample(bool rb_resize, Texture **attach, RenderTexturePlane slot,
#endif
glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rbm[slot]);
GLuint format = GL_DEPTH_COMPONENT;
#ifndef OPENGLES
if (_fb_properties.get_float_depth()) {
if (!glgsg->_use_remapped_depth_range) {
format = GL_DEPTH_COMPONENT32F;
} else {
format = GL_DEPTH_COMPONENT32F_NV;
}
} else
#endif
if (tex) {
switch (tex->get_format()) {
case Texture::F_depth_component16:

View File

@ -4392,7 +4392,8 @@ update_standard_vertex_arrays(bool force) {
GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
} else
#endif // NDEBUG
if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
if (_vertex_colors_enabled &&
_data_reader->get_color_info(array_reader, num_values, numeric_type,
start, stride)) {
if (!setup_array_data(client_pointer, array_reader, force)) {
return false;
@ -4409,7 +4410,13 @@ update_standard_vertex_arrays(bool force) {
glDisableClientState(GL_COLOR_ARRAY);
// Since we don't have per-vertex color, the implicit color is white.
GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
if (_color_scale_via_lighting) {
GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
} else {
LColor color = _scene_graph_color;
color.componentwise_mult(_current_color_scale);
GLPf(Color4)(color[0], color[1], color[2], color[3]);
}
}
// Now set up each of the active texture coordinate stages--or at least
@ -8918,6 +8925,9 @@ get_panda_wrap_mode(GLenum wm) {
case GL_REPEAT:
return SamplerState::WM_repeat;
case GL_MIRRORED_REPEAT:
return SamplerState::WM_mirror;
#ifndef OPENGLES
case GL_MIRROR_CLAMP_EXT:
case GL_MIRROR_CLAMP_TO_EDGE_EXT:

View File

@ -2440,9 +2440,9 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
if (p == _color_attrib_index) {
// Vertex colors are disabled or not present. Apply flat color.
#ifdef STDFLOAT_DOUBLE
_glgsg->_glVertexAttrib4dv(p, color_attrib->get_color().get_data());
_glgsg->_glVertexAttrib4dv(p, _glgsg->_scene_graph_color.get_data());
#else
_glgsg->_glVertexAttrib4fv(p, color_attrib->get_color().get_data());
_glgsg->_glVertexAttrib4fv(p, _glgsg->_scene_graph_color.get_data());
#endif
}
}

View File

@ -286,6 +286,28 @@ make_nonindexed(bool composite_only) {
return num_changed;
}
/**
* Returns a GeomVertexData that represents the results of computing the
* vertex animation on the CPU for this Geom's vertex data.
*
* If there is no CPU-defined vertex animation on this object, this just
* returns the original object.
*
* If there is vertex animation, but the VertexTransform values have not
* changed since last time, this may return the same pointer it returned
* previously. Even if the VertexTransform values have changed, it may still
* return the same pointer, but with its contents modified (this is preferred,
* since it allows the graphics backend to update vertex buffers optimally).
*
* If force is false, this method may return immediately with stale data, if
* the vertex data is not completely resident. If force is true, this method
* will never return stale data, but may block until the data is available.
*/
CPT(GeomVertexData) Geom::
get_animated_vertex_data(bool force, Thread *current_thread) const {
return get_vertex_data()->animate_vertices(force, current_thread);
}
/**
* Replaces the ith GeomPrimitive object stored within the Geom with the new
* object.
@ -1311,8 +1333,7 @@ compute_internal_bounds(Geom::CData *cdata, Thread *current_thread) const {
int num_vertices = 0;
// Get the vertex data, after animation.
CPT(GeomVertexData) vertex_data = cdata->_data.get_read_pointer(current_thread);
vertex_data = vertex_data->animate_vertices(true, current_thread);
CPT(GeomVertexData) vertex_data = get_animated_vertex_data(true, current_thread);
// Now actually compute the bounding volume. We do this by using
// calc_tight_bounds to determine our box first.

View File

@ -85,6 +85,8 @@ PUBLISHED:
void offset_vertices(const GeomVertexData *data, int offset);
int make_nonindexed(bool composite_only);
CPT(GeomVertexData) get_animated_vertex_data(bool force, Thread *current_thread) const;
INLINE bool is_empty() const;
INLINE size_t get_num_primitives() const;

View File

@ -45,7 +45,9 @@ has_column(const InternalName *name) const {
*/
INLINE int GeomVertexArrayData::
get_num_rows() const {
return get_handle()->get_num_rows();
CDReader cdata(_cycler);
nassertr(_array_format->get_stride() != 0, 0);
return cdata->_buffer.get_size() / _array_format->get_stride();
}
/**

View File

@ -60,9 +60,20 @@ has_column(const InternalName *name) const {
*/
INLINE int GeomVertexData::
get_num_rows() const {
GeomVertexDataPipelineReader reader(this, Thread::get_current_thread());
reader.check_array_readers();
return reader.get_num_rows();
CPT(GeomVertexArrayData) array;
{
CDReader cdata(_cycler);
nassertr(cdata->_format->get_num_arrays() == cdata->_arrays.size(), 0);
if (cdata->_arrays.size() == 0) {
// No arrays means no rows. Weird but legal.
return 0;
}
array = cdata->_arrays[0].get_read_pointer();
}
return array->get_num_rows();
}
/**
@ -761,7 +772,9 @@ set_object(const GeomVertexData *object) {
_cdata = (GeomVertexData::CData *)_object->_cycler.read_unlocked(_current_thread);
_got_array_readers = false;
#ifdef DO_PIPELINING
_cdata->ref();
#endif // DO_PIPELINING
}
/**

View File

@ -621,13 +621,26 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
const TransformBlend &blend = blend_table->get_blend(from.get_data1i());
LVecBase4 weights = LVecBase4::zero();
LVecBase4i indices(0, 0, 0, 0);
nassertv(blend.get_num_transforms() <= 4);
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
weights[i] = blend.get_weight(i);
indices[i] = add_transform(transform_table, blend.get_transform(i),
already_added);
if (blend.get_num_transforms() <= 4) {
for (size_t i = 0; i < blend.get_num_transforms(); i++) {
weights[i] = blend.get_weight(i);
indices[i] = add_transform(transform_table, blend.get_transform(i),
already_added);
}
} else {
// Limit the number of blends to the four with highest weights.
TransformBlend blend2(blend);
blend2.limit_transforms(4);
blend2.normalize_weights();
for (size_t i = 0; i < 4; i++) {
weights[i] = blend2.get_weight(i);
indices[i] = add_transform(transform_table, blend2.get_transform(i),
already_added);
}
}
if (weight.has_column()) {
weight.set_data4(weights);
}

View File

@ -1619,8 +1619,8 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
++qsi) {
Shader *shader = qsi->first;
ShaderContext *sc = shader->prepare_now(this, gsg);
if (qti->second != nullptr) {
qti->second->set_result(sc);
if (qsi->second != nullptr) {
qsi->second->set_result(sc);
}
}

View File

@ -40,7 +40,7 @@ do_task() {
// become a kind of a leak (if the texture is never rendered again on
// this GSG, we'll just end up carrying the texture memory in RAM
// forever, instead of dumping it as soon as it gets prepared).
_texture->prepare(_pgo);
_pgo->enqueue_texture(_texture);
}
}

View File

@ -84,7 +84,7 @@ operator = (const TextureStage &other) {
_combine_rgb_operand2 = other._combine_rgb_operand2;
_combine_alpha_mode = other._combine_alpha_mode;
_combine_alpha_source0 = other._combine_alpha_source0;
_combine_alpha_operand0 = _combine_alpha_operand0;
_combine_alpha_operand0 = other._combine_alpha_operand0;
_combine_alpha_source1 = other._combine_alpha_source1;
_combine_alpha_operand1 = other._combine_alpha_operand1;
_combine_alpha_source2 = other._combine_alpha_source2;

View File

@ -866,7 +866,7 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
PT(Geom) geom = orig_geom->make_copy();
// Ensure that any vertex animation has been applied.
geom->set_vertex_data(geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread));
geom->set_vertex_data(geom->get_animated_vertex_data(true, current_thread));
// Now get a modifiable pointer to the vertex data in the new Geom. This
// will actually perform a deep copy of the vertex data.

View File

@ -445,7 +445,7 @@ do_flush() {
if (data_sent > 0) {
total_sent += data_sent;
}
double last_report = 0;
while (!okflag && tcp->Active() &&
(data_sent > 0 || tcp->GetLastError() == LOCAL_BLOCKING_ERROR)) {
if (data_sent == 0) {

View File

@ -64,7 +64,7 @@ private:
CGGammaValue _gOriginalRedTable[ 256 ];
CGGammaValue _gOriginalGreenTable[ 256 ];
CGGammaValue _gOriginalBlueTable[ 256 ];
CGTableCount _sampleCount;
uint32_t _sampleCount;
CGDisplayErr _cgErr;
public:

View File

@ -68,7 +68,6 @@ write(std::ostream &out, int indent) const {
out.width(indent+2); out<<""; out<<"_lifespan "<<_lifespan<<"\n";
out.width(indent+2); out<<""; out<<"_alive "<<_alive<<"\n";
out.width(indent+2); out<<""; out<<"_index "<<_index<<"\n";
out.width(indent+2); out<<""; out<<"_last_position "<<_last_position<<"\n";
PhysicsObject::write(out, indent+2);
#endif //] NDEBUG
}

View File

@ -62,8 +62,6 @@ private:
PN_stdfloat _lifespan;
bool _alive;
int _index;
LPoint3 _last_position;
};
#include "baseParticle.I"

View File

@ -68,7 +68,7 @@ make_off() {
*/
CPT(RenderAttrib) ColorAttrib::
make_default() {
return make_off();
return make_vertex();
}
/**

View File

@ -88,7 +88,7 @@ public:
register_type(_type_handle, "ColorAttrib",
RenderAttrib::get_class_type());
_attrib_slot = register_slot(_type_handle, 100,
new ColorAttrib(T_off, LColor(1, 1, 1, 1)));
new ColorAttrib(T_vertex, LColor::zero()));
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -54,6 +54,9 @@ apply_transform_and_state(CullTraverser *trav) {
CPT(TransformState) node_transform = _node_reader.get_transform();
node_effects->cull_callback(trav, *this, node_transform, node_state);
apply_transform(node_transform);
// The cull callback may have changed the node properties.
_node_reader.check_cached(false);
}
if (!node_state->is_empty()) {

View File

@ -376,8 +376,7 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
geom = transformer.premunge_geom(geom, munger);
// Prepare each of the vertex arrays in the munged Geom.
CPT(GeomVertexData) vdata = geom->get_vertex_data(current_thread);
vdata = vdata->animate_vertices(false, current_thread);
CPT(GeomVertexData) vdata = geom->get_animated_vertex_data(false, current_thread);
GeomVertexDataPipelineReader vdata_reader(vdata, current_thread);
int num_arrays = vdata_reader.get_num_arrays();
for (int i = 0; i < num_arrays; ++i) {
@ -474,7 +473,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
CPT(Geom) geom = (*gi)._geom.get_read_pointer();
geom->calc_tight_bounds(min_point, max_point, found_any,
geom->get_vertex_data(current_thread)->animate_vertices(true, current_thread),
geom->get_animated_vertex_data(true, current_thread),
!next_transform->is_identity(), mat,
current_thread);
}

View File

@ -211,7 +211,7 @@ garbage_collect() {
}
num_this_pass = std::min(num_this_pass, size);
size_t stop_at_element = (_garbage_index + num_this_pass) % size;
size_t stop_at_element = (si + num_this_pass) % size;
do {
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
@ -229,6 +229,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -950,6 +950,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -1216,6 +1216,9 @@ garbage_collect() {
// still need to visit.
--size;
--si;
if (stop_at_element > 0) {
--stop_at_element;
}
}
si = (si + 1) % size;

View File

@ -11,14 +11,6 @@
* @date 2007-06-20
*/
/**
*
*/
INLINE BlockerSimple::
BlockerSimple() {
_flags = 0;
}
/**
*
*/

View File

@ -28,7 +28,7 @@
*/
class EXPCL_PANDA_PIPELINE BlockerSimple {
protected:
INLINE BlockerSimple();
constexpr BlockerSimple() = default;
INLINE ~BlockerSimple();
protected:
@ -38,7 +38,7 @@ protected:
F_has_waiters = 0x40000000,
};
unsigned int _flags;
unsigned int _flags = 0;
friend class ThreadSimpleManager;
};

View File

@ -71,7 +71,10 @@ init_libpipeline() {
}
initialized = true;
#ifdef DO_PIPELINING
CycleData::init_type();
#endif
MainThread::init_type();
ExternalThread::init_type();
GenericThread::init_type();

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_longjmp_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_longjmp_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
setmp() / longjmp(). This is the hackier implementation,
@ -90,14 +89,14 @@ void
cs_longjmp(cs_jmp_buf env) {
_asm {
mov eax, env;
mov ebx, [eax + 0];
mov edi, [eax + 4];
mov esi, [eax + 8];
mov ebp, [eax + 12];
mov esp, [eax + 16];
mov edx, [eax + 20];
frstor [eax + 24]; /* restore floating-point state */
mov eax, 1; /* return 1 from setjmp: pass 2 return */
@ -251,7 +250,7 @@ setup_context_1(void) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
/* Copy all of the input parameters to static variables, then begin
@ -263,7 +262,7 @@ init_thread_context(struct ThreadContext *context,
st_data = data;
setup_context_1();
}
}
void
save_thread_context(struct ThreadContext *context,

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_posix_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_posix_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
posix threads to manage the different execution contexts. This
@ -44,7 +43,7 @@ struct ThreadContext {
pthread_mutex_t _ready_mutex;
pthread_cond_t _ready_cvar;
int _ready_flag;
/* This is set FALSE while the thread is alive, and TRUE if the
thread is to be terminated when it next wakes up. */
int _terminated;
@ -83,19 +82,19 @@ thread_main(void *data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
context->_thread_func = thread_func;
context->_data = data;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stack_size);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&(context->_thread), &attr, thread_main, context);
pthread_attr_destroy(&attr);
pthread_create(&(context->_thread), &attr, thread_main, context);
pthread_attr_destroy(&attr);
}
void
@ -142,7 +141,7 @@ switch_to_thread_context(struct ThreadContext *from_context,
/* We've been rudely terminated. Exit gracefully. */
pthread_exit(NULL);
}
/* Now we have been signaled again, and we're ready to resume the
thread. */
longjmp(from_context->_jmp_context, 1);
@ -164,7 +163,7 @@ alloc_thread_context() {
pthread_mutexattr_init(&attr);
// The symbol PTHREAD_MUTEX_DEFAULT isn't always available?
// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
int result = pthread_mutex_init(&context->_ready_mutex, &attr);
pthread_mutex_init(&context->_ready_mutex, &attr);
pthread_mutexattr_destroy(&attr);
pthread_cond_init(&context->_ready_cvar, NULL);

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_ucontext_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_ucontext_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
getcontext() / setcontext(). This is the preferred implementation,
@ -43,7 +42,7 @@ begin_context(ThreadFunction *thread_func, void *data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
if (getcontext(&context->_ucontext) != 0) {

View File

@ -1,8 +1,4 @@
/* Filename: contextSwitch_windows_src.c
* Created by: drose (15Apr10)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
@ -10,7 +6,10 @@
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* @file contextSwitch_windows_src.c
* @author drose
* @date 2010-04-15
*/
/* This is the implementation of user-space context switching using
native Windows threading constructs to manage the different
@ -37,7 +36,7 @@ struct ThreadContext {
/* This event is in the signaled state when the thread is ready to
roll. */
HANDLE _ready;
/* This is set FALSE while the thread is alive, and TRUE if the
thread is to be terminated when it next wakes up. */
int _terminated;
@ -71,13 +70,13 @@ thread_main(LPVOID data) {
}
void
init_thread_context(struct ThreadContext *context,
init_thread_context(struct ThreadContext *context,
unsigned char *stack, size_t stack_size,
ThreadFunction *thread_func, void *data) {
context->_thread_func = thread_func;
context->_data = data;
context->_thread = CreateThread(NULL, stack_size,
context->_thread = CreateThread(NULL, stack_size,
thread_main, context, 0, NULL);
}
@ -117,7 +116,7 @@ switch_to_thread_context(struct ThreadContext *from_context,
/* We've been rudely terminated. Exit gracefully. */
ExitThread(1);
}
/* Now we have been signaled again, and we're ready to resume the
thread. */
longjmp(from_context->_jmp_context, 1);

View File

@ -54,6 +54,9 @@ public:
INLINE CycleData(const CycleData &copy) = default;
virtual ~CycleData();
CycleData &operator = (CycleData &&from) = default;
CycleData &operator = (const CycleData &copy) = default;
virtual CycleData *make_copy() const=0;
virtual void write_datagram(BamWriter *, Datagram &) const;

View File

@ -45,6 +45,19 @@ CycleDataLockedReader(const CycleDataLockedReader<CycleDataType> &copy) :
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedReader<CycleDataType>::
CycleDataLockedReader(CycleDataLockedReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -61,19 +74,6 @@ operator = (const CycleDataLockedReader<CycleDataType> &copy) {
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedReader<CycleDataType>::
CycleDataLockedReader(CycleDataLockedReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -177,6 +177,18 @@ operator = (const CycleDataLockedReader<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataLockedReader<CycleDataType>::
operator = (CycleDataLockedReader<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
*
*/

View File

@ -47,6 +47,20 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader<CycleDataType> &copy
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer),
_stage(from._stage)
{
from._pointer = nullptr;
}
/**
*
*/
@ -64,20 +78,6 @@ operator = (const CycleDataLockedStageReader<CycleDataType> &copy) {
_cycler->increment_read(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_cycler(from._cycler),
_current_thread(from._current_thread),
_pointer(from._pointer),
_stage(from._stage)
{
from._pointer = nullptr;
}
/**
*
*/
@ -174,6 +174,17 @@ CycleDataLockedStageReader(const CycleDataLockedStageReader<CycleDataType> &copy
{
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataLockedStageReader<CycleDataType>::
CycleDataLockedStageReader(CycleDataLockedStageReader<CycleDataType> &&from) noexcept :
_pointer(from._cycler)
{
from._pointer = nullptr;
}
/**
*
*/
@ -183,6 +194,18 @@ operator = (const CycleDataLockedStageReader<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataLockedStageReader<CycleDataType>::
operator = (CycleDataLockedStageReader<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
*
*/

View File

@ -62,23 +62,6 @@ CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy) :
_cycler->increment_write(_pointer);
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (const CycleDataStageWriter<CycleDataType> &copy) {
nassertv(_pointer == nullptr);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
_stage = copy._stage;
nassertv(_pointer != nullptr);
_cycler->increment_write(_pointer);
}
/**
* This flavor of the constructor elevates the pointer from the
* CycleDataLockedStageReader from a read to a write pointer (and invalidates
@ -128,6 +111,23 @@ CycleDataStageWriter(CycleDataStageWriter<CycleDataType> &&from) noexcept :
from._pointer = nullptr;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (const CycleDataStageWriter<CycleDataType> &copy) {
nassertv(_pointer == nullptr);
nassertv(_current_thread == copy._current_thread);
_cycler = copy._cycler;
_pointer = copy._pointer;
_stage = copy._stage;
nassertv(_pointer != nullptr);
_cycler->increment_write(_pointer);
}
/**
*
*/
@ -227,6 +227,17 @@ CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy) :
{
}
/**
*
*/
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(CycleDataStageWriter<CycleDataType> &&from) noexcept :
_pointer(from._pointer)
{
from._pointer = nullptr;
}
/**
*
*/
@ -236,6 +247,18 @@ operator = (const CycleDataStageWriter<CycleDataType> &copy) {
_pointer = copy._pointer;
}
/**
*
*/
template<class CycleDataType>
INLINE void CycleDataStageWriter<CycleDataType>::
operator = (CycleDataStageWriter<CycleDataType> &&from) noexcept {
nassertv(_pointer == nullptr);
_pointer = from._pointer;
from._pointer = nullptr;
}
/**
* This flavor of the constructor elevates the pointer from the
* CycleDataLockedStageReader from a read to a write pointer (and invalidates

View File

@ -225,7 +225,7 @@ call_python_func(PyObject *function, PyObject *args) {
} else {
// No exception. Restore the thread state normally.
PyThreadState *state = PyThreadState_Swap(orig_thread_state);
PyThreadState_Swap(orig_thread_state);
thread_states.push_back(new_thread_state);
// PyThreadState_Clear(new_thread_state);
// PyThreadState_Delete(new_thread_state);

View File

@ -51,14 +51,6 @@ is_threading_supported() {
return true;
}
/**
*
*/
INLINE bool ThreadSimpleImpl::
is_true_threads() {
return (is_os_threads != 0);
}
/**
*
*/

View File

@ -141,8 +141,8 @@ start(ThreadPriority priority, bool joinable) {
#ifdef HAVE_PYTHON
// Query the current Python thread state.
_python_state = PyThreadState_Swap(nullptr);
PyThreadState_Swap(_python_state);
_python_state = thread_state_swap(nullptr);
thread_state_swap(_python_state);
#endif // HAVE_PYTHON
init_thread_context(_context, _stack, _stack_size, st_begin_thread, this);
@ -201,6 +201,14 @@ prepare_for_exit() {
manager->prepare_for_exit();
}
/**
*
*/
bool ThreadSimpleImpl::
is_true_threads() {
return (is_os_threads != 0);
}
/**
*
*/
@ -238,7 +246,7 @@ st_begin_thread(void *data) {
void ThreadSimpleImpl::
begin_thread() {
#ifdef HAVE_PYTHON
PyThreadState_Swap(_python_state);
thread_state_swap(_python_state);
#endif // HAVE_PYTHON
#ifdef HAVE_POSIX_THREADS

View File

@ -63,7 +63,7 @@ public:
INLINE static void bind_thread(Thread *thread);
INLINE static bool is_threading_supported();
INLINE static bool is_true_threads();
static bool is_true_threads();
INLINE static bool is_simple_threads();
INLINE static void sleep(double seconds);
INLINE static void yield();

View File

@ -20,7 +20,9 @@
#include "mainThread.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#endif
@ -235,7 +237,7 @@ next_context() {
#ifdef HAVE_PYTHON
// Save the current Python thread state.
_current_thread->_python_state = PyThreadState_Swap(nullptr);
_current_thread->_python_state = thread_state_swap(nullptr);
#endif // HAVE_PYTHON
#ifdef DO_PSTATS
@ -256,7 +258,7 @@ next_context() {
#endif // DO_PSTATS
#ifdef HAVE_PYTHON
PyThreadState_Swap(_current_thread->_python_state);
thread_state_swap(_current_thread->_python_state);
#endif // HAVE_PYTHON
}
@ -468,16 +470,6 @@ init_pointers() {
_pointers_initialized = true;
_global_ptr = new ThreadSimpleManager;
Thread::get_main_thread();
#ifdef HAVE_PYTHON
// Ensure that the Python threading system is initialized and ready to go.
#if PY_VERSION_HEX >= 0x03020000
Py_Initialize();
#endif
PyEval_InitThreads();
#endif
}
}

View File

@ -1010,61 +1010,6 @@ clear_glyph_shift() {
invalidate_with_measure();
}
/**
* Changes the text that is displayed under the TextNode.
*/
INLINE void TextNode::
set_text(const std::string &text) {
MutexHolder holder(_lock);
TextEncoder::set_text(text);
invalidate_with_measure();
}
/**
* The two-parameter version of set_text() accepts an explicit encoding; the
* text is immediately decoded and stored as a wide-character string.
* Subsequent calls to get_text() will return the same text re-encoded using
* whichever encoding is specified by set_encoding().
*/
INLINE void TextNode::
set_text(const std::string &text, TextNode::Encoding encoding) {
MutexHolder holder(_lock);
TextEncoder::set_text(text, encoding);
invalidate_with_measure();
}
/**
* Removes the text from the TextNode.
*/
INLINE void TextNode::
clear_text() {
MutexHolder holder(_lock);
TextEncoder::clear_text();
invalidate_with_measure();
}
/**
* Appends the indicates string to the end of the stored text.
*/
INLINE void TextNode::
append_text(const std::string &text) {
MutexHolder holder(_lock);
TextEncoder::append_text(text);
invalidate_with_measure();
}
/**
* Appends a single character to the end of the stored text. This may be a
* wide character, up to 16 bits in Unicode.
*/
INLINE void TextNode::
append_unicode_char(wchar_t character) {
MutexHolder holder(_lock);
TextEncoder::append_unicode_char(character);
invalidate_with_measure();
}
/**
* Returns a string that represents the contents of the text, as it has been
* formatted by wordwrap rules.
@ -1086,28 +1031,6 @@ calc_width(const std::string &line) const {
return calc_width(decode_text(line));
}
/**
* Changes the text that is displayed under the TextNode, with a wide text.
* This automatically sets the string reported by get_text() to the 8-bit
* encoded version of the same string.
*/
INLINE void TextNode::
set_wtext(const std::wstring &wtext) {
MutexHolder holder(_lock);
TextEncoder::set_wtext(wtext);
invalidate_with_measure();
}
/**
* Appends the indicates string to the end of the stored wide-character text.
*/
INLINE void TextNode::
append_wtext(const std::wstring &wtext) {
MutexHolder holder(_lock);
TextEncoder::append_wtext(wtext);
invalidate_with_measure();
}
/**
* Returns a wstring that represents the contents of the text, as it has been
* formatted by wordwrap rules.

Some files were not shown because too many files have changed in this diff Show More