mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Merge branch 'master' into cmake
This commit is contained in:
commit
df805bd02b
@ -1240,7 +1240,7 @@ shadow_inherited_field(const string &name) {
|
||||
}
|
||||
|
||||
// If we get here, the named field wasn't in the list. Huh.
|
||||
nassertv(false);
|
||||
nassert_raise("named field not in list");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,8 +184,8 @@ class CommonFilters:
|
||||
if ("BlurSharpen" in configuration):
|
||||
blur0=self.textures["blur0"]
|
||||
blur1=self.textures["blur1"]
|
||||
self.blur.append(self.manager.renderQuadInto(colortex=blur0,div=2))
|
||||
self.blur.append(self.manager.renderQuadInto(colortex=blur1))
|
||||
self.blur.append(self.manager.renderQuadInto("filter-blur0", colortex=blur0,div=2))
|
||||
self.blur.append(self.manager.renderQuadInto("filter-blur1", colortex=blur1))
|
||||
self.blur[0].setShaderInput("src", self.textures["color"])
|
||||
self.blur[0].setShader(self.loadShader("filter-blurx.sha"))
|
||||
self.blur[1].setShaderInput("src", blur0)
|
||||
@ -195,9 +195,9 @@ class CommonFilters:
|
||||
ssao0=self.textures["ssao0"]
|
||||
ssao1=self.textures["ssao1"]
|
||||
ssao2=self.textures["ssao2"]
|
||||
self.ssao.append(self.manager.renderQuadInto(colortex=ssao0))
|
||||
self.ssao.append(self.manager.renderQuadInto(colortex=ssao1,div=2))
|
||||
self.ssao.append(self.manager.renderQuadInto(colortex=ssao2))
|
||||
self.ssao.append(self.manager.renderQuadInto("filter-ssao0", colortex=ssao0))
|
||||
self.ssao.append(self.manager.renderQuadInto("filter-ssao1", colortex=ssao1,div=2))
|
||||
self.ssao.append(self.manager.renderQuadInto("filter-ssao2", colortex=ssao2))
|
||||
self.ssao[0].setShaderInput("depth", self.textures["depth"])
|
||||
self.ssao[0].setShaderInput("normal", self.textures["aux"])
|
||||
self.ssao[0].setShaderInput("random", loader.loadTexture("maps/random.rgb"))
|
||||
@ -215,21 +215,21 @@ class CommonFilters:
|
||||
bloom3=self.textures["bloom3"]
|
||||
if (bloomconf.size == "large"):
|
||||
scale=8
|
||||
downsampler="filter-down4.sha"
|
||||
downsampler="filter-down4"
|
||||
elif (bloomconf.size == "medium"):
|
||||
scale=4
|
||||
downsampler="filter-copy.sha"
|
||||
downsampler="filter-copy"
|
||||
else:
|
||||
scale=2
|
||||
downsampler="filter-copy.sha"
|
||||
self.bloom.append(self.manager.renderQuadInto(colortex=bloom0, div=2, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto(colortex=bloom1, div=scale, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto(colortex=bloom2, div=scale, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto(colortex=bloom3, div=scale, align=scale))
|
||||
downsampler="filter-copy"
|
||||
self.bloom.append(self.manager.renderQuadInto("filter-bloomi", colortex=bloom0, div=2, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto(downsampler, colortex=bloom1, div=scale, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto("filter-bloomx", colortex=bloom2, div=scale, align=scale))
|
||||
self.bloom.append(self.manager.renderQuadInto("filter-bloomy", colortex=bloom3, div=scale, align=scale))
|
||||
self.bloom[0].setShaderInput("src", self.textures["color"])
|
||||
self.bloom[0].setShader(self.loadShader("filter-bloomi.sha"))
|
||||
self.bloom[1].setShaderInput("src", bloom0)
|
||||
self.bloom[1].setShader(self.loadShader(downsampler))
|
||||
self.bloom[1].setShader(self.loadShader(downsampler + ".sha"))
|
||||
self.bloom[2].setShaderInput("src", bloom1)
|
||||
self.bloom[2].setShader(self.loadShader("filter-bloomx.sha"))
|
||||
self.bloom[3].setShaderInput("src", bloom2)
|
||||
|
@ -236,7 +236,7 @@ class FilterManager(DirectObject):
|
||||
|
||||
return quad
|
||||
|
||||
def renderQuadInto(self, mul=1, div=1, align=1, depthtex=None, colortex=None, auxtex0=None, auxtex1=None):
|
||||
def renderQuadInto(self, name="filter-stage", mul=1, div=1, align=1, depthtex=None, colortex=None, auxtex0=None, auxtex1=None):
|
||||
|
||||
""" Creates an offscreen buffer for an intermediate
|
||||
computation. Installs a quad into the buffer. Returns
|
||||
@ -250,7 +250,7 @@ class FilterManager(DirectObject):
|
||||
|
||||
depthbits = bool(depthtex != None)
|
||||
|
||||
buffer = self.createBuffer("filter-stage", winx, winy, texgroup, depthbits)
|
||||
buffer = self.createBuffer(name, winx, winy, texgroup, depthbits)
|
||||
|
||||
if (buffer == None):
|
||||
return None
|
||||
|
@ -6975,7 +6975,11 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
||||
out << " if (wrap != nullptr) {\n"
|
||||
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Mapping_Getitem;\n";
|
||||
if (!property->_setter_remaps.empty()) {
|
||||
if (property->_has_this) {
|
||||
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
|
||||
} else {
|
||||
out << " {\n";
|
||||
}
|
||||
out << " wrap->_setitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Mapping_Setitem;\n";
|
||||
out << " }\n";
|
||||
}
|
||||
@ -7006,7 +7010,11 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
||||
" wrap->_len_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Len;\n"
|
||||
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_Getitem;\n";
|
||||
if (!property->_setter_remaps.empty()) {
|
||||
if (property->_has_this) {
|
||||
out << " if (!DtoolInstance_IS_CONST(self)) {\n";
|
||||
} else {
|
||||
out << " {\n";
|
||||
}
|
||||
out << " wrap->_setitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_Setitem;\n";
|
||||
if (property->_inserter != nullptr) {
|
||||
out << " wrap->_insert_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Sequence_insert;\n";
|
||||
|
@ -110,7 +110,7 @@ out(NotifySeverity severity, bool prefix) const {
|
||||
nout << *this << "(" << severity << "): ";
|
||||
}
|
||||
if (assert_abort) {
|
||||
nassertr(false, nout);
|
||||
nassert_raise("unprotected debug statement");
|
||||
}
|
||||
|
||||
return nout;
|
||||
|
@ -58,6 +58,24 @@ release() {
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the reference count. Only has impact if the class that manages
|
||||
* this StreamWrapper's lifetime (eg. Multifile) respects it.
|
||||
*/
|
||||
INLINE void StreamWrapperBase::
|
||||
ref() const {
|
||||
AtomicAdjust::inc(_ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the reference count. Only has impact if the class that manages
|
||||
* this StreamWrapper's lifetime (eg. Multifile) respects it.
|
||||
*/
|
||||
INLINE bool StreamWrapperBase::
|
||||
unref() const {
|
||||
return AtomicAdjust::dec(_ref_count);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "dtoolbase.h"
|
||||
#include "mutexImpl.h"
|
||||
#include "atomicAdjust.h"
|
||||
|
||||
/**
|
||||
* The base class for both IStreamWrapper and OStreamWrapper, this provides
|
||||
@ -30,8 +31,17 @@ PUBLISHED:
|
||||
INLINE void acquire();
|
||||
INLINE void release();
|
||||
|
||||
public:
|
||||
INLINE void ref() const;
|
||||
INLINE bool unref() const;
|
||||
|
||||
private:
|
||||
MutexImpl _lock;
|
||||
|
||||
// This isn't really designed as a reference counted class, but it is useful
|
||||
// to treat it as one when dealing with substreams created by Multifile.
|
||||
mutable AtomicAdjust::Integer _ref_count = 1;
|
||||
|
||||
#ifdef SIMPLE_THREADS
|
||||
// In the SIMPLE_THREADS case, we need to use a bool flag, because MutexImpl
|
||||
// defines to nothing in this case--but we still need to achieve a form of
|
||||
|
@ -828,7 +828,7 @@ if (COMPILER=="GCC"):
|
||||
SmartPkgEnable("EIGEN", "eigen3", (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
|
||||
SmartPkgEnable("ARTOOLKIT", "", ("AR"), "AR/ar.h")
|
||||
SmartPkgEnable("FCOLLADA", "", ChooseLib(fcollada_libs, "FCOLLADA"), ("FCollada", "FCollada/FCollada.h"))
|
||||
SmartPkgEnable("ASSIMP", "", ("assimp"), "assimp/Importer.hpp")
|
||||
SmartPkgEnable("ASSIMP", "assimp", ("assimp"), "assimp/Importer.hpp")
|
||||
SmartPkgEnable("FFMPEG", ffmpeg_libs, ffmpeg_libs, ("libavformat/avformat.h", "libavcodec/avcodec.h", "libavutil/avutil.h"))
|
||||
SmartPkgEnable("SWSCALE", "libswscale", "libswscale", ("libswscale/swscale.h"), target_pkg = "FFMPEG", thirdparty_dir = "ffmpeg")
|
||||
SmartPkgEnable("SWRESAMPLE","libswresample", "libswresample", ("libswresample/swresample.h"), target_pkg = "FFMPEG", thirdparty_dir = "ffmpeg")
|
||||
@ -872,6 +872,13 @@ if (COMPILER=="GCC"):
|
||||
else:
|
||||
PkgDisable("OPENCV")
|
||||
|
||||
if not PkgSkip("ASSIMP") and \
|
||||
os.path.isfile(GetThirdpartyDir() + "assimp/lib/libassimp.a"):
|
||||
# Also pick up IrrXML, which is needed when linking statically.
|
||||
irrxml = GetThirdpartyDir() + "assimp/lib/libIrrXML.a"
|
||||
if os.path.isfile(irrxml):
|
||||
LibName("ASSIMP", irrxml)
|
||||
|
||||
rocket_libs = ("RocketCore", "RocketControls")
|
||||
if (GetOptimize() <= 3):
|
||||
rocket_libs += ("RocketDebugger",)
|
||||
|
@ -553,6 +553,7 @@ uncache_sound(const Filename &file_name) {
|
||||
if (sd->_movie->get_filename() == path ||
|
||||
sd->_movie->get_filename() == file_name) {
|
||||
exqi = _expiring_streams.erase(exqi);
|
||||
delete sd;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ PUBLISHED:
|
||||
INLINE double get_base_frame_rate() const;
|
||||
INLINE int get_num_frames() const;
|
||||
|
||||
MAKE_PROPERTY(base_frame_rate, get_base_frame_rate);
|
||||
MAKE_PROPERTY(num_frames, get_num_frames);
|
||||
|
||||
virtual void output(std::ostream &out) const;
|
||||
|
||||
protected:
|
||||
|
@ -41,6 +41,8 @@ public:
|
||||
PUBLISHED:
|
||||
INLINE AnimBundle *get_bundle() const;
|
||||
|
||||
MAKE_PROPERTY(bundle, get_bundle);
|
||||
|
||||
static AnimBundle *find_anim_bundle(PandaNode *root);
|
||||
|
||||
private:
|
||||
|
@ -57,6 +57,8 @@ PUBLISHED:
|
||||
INLINE const TransformState *get_value_transform() const;
|
||||
INLINE PandaNode *get_value_node() const;
|
||||
|
||||
MAKE_PROPERTY(value_node, get_value_node, set_value_node);
|
||||
|
||||
protected:
|
||||
virtual AnimGroup *make_copy(AnimGroup *parent) const;
|
||||
|
||||
|
@ -239,7 +239,7 @@ set_table(char table_id, const CPTA_stdfloat &table) {
|
||||
if (table.size() > 1 && (int)table.size() < num_frames) {
|
||||
// The new table has an invalid number of frames--it doesn't match the
|
||||
// bundle's requirement.
|
||||
nassertv(false);
|
||||
nassert_raise("mismatched number of frames");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ PUBLISHED:
|
||||
INLINE bool has_table(char table_id) const;
|
||||
INLINE void clear_table(char table_id);
|
||||
|
||||
MAKE_MAP_PROPERTY(tables, has_table, get_table, set_table, clear_table);
|
||||
|
||||
public:
|
||||
virtual void write(std::ostream &out, int indent_level) const;
|
||||
|
||||
|
@ -10,3 +10,25 @@
|
||||
* @author drose
|
||||
* @date 2003-10-20
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the value of the channel. This will return the value explicitly
|
||||
* specified by set_value() unless a value node was specified using
|
||||
* set_value_node().
|
||||
*/
|
||||
INLINE PN_stdfloat AnimChannelScalarDynamic::
|
||||
get_value() const {
|
||||
if (_value_node != nullptr) {
|
||||
return _value->get_pos()[0];
|
||||
} else {
|
||||
return _float_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node that was set via set_value_node(), if any.
|
||||
*/
|
||||
INLINE PandaNode *AnimChannelScalarDynamic::
|
||||
get_value_node() const {
|
||||
return _value_node;
|
||||
}
|
||||
|
@ -84,16 +84,12 @@ has_changed(int, double, int, double) {
|
||||
*/
|
||||
void AnimChannelScalarDynamic::
|
||||
get_value(int, PN_stdfloat &value) {
|
||||
if (_value_node != nullptr) {
|
||||
value = _value->get_pos()[0];
|
||||
|
||||
} else {
|
||||
value = _float_value;
|
||||
}
|
||||
value = get_value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly sets the value.
|
||||
* Explicitly sets the value. This will remove any node assigned via
|
||||
* set_value_node().
|
||||
*/
|
||||
void AnimChannelScalarDynamic::
|
||||
set_value(PN_stdfloat value) {
|
||||
@ -104,7 +100,8 @@ set_value(PN_stdfloat value) {
|
||||
|
||||
/**
|
||||
* Specifies a node whose transform will be queried each frame to implicitly
|
||||
* specify the transform of this joint.
|
||||
* specify the transform of this joint. This will override the values set by
|
||||
* set_value().
|
||||
*/
|
||||
void AnimChannelScalarDynamic::
|
||||
set_value_node(PandaNode *value_node) {
|
||||
|
@ -41,11 +41,16 @@ public:
|
||||
virtual bool has_changed(int last_frame, double last_frac,
|
||||
int this_frame, double this_frac);
|
||||
virtual void get_value(int frame, PN_stdfloat &value);
|
||||
INLINE PN_stdfloat get_value() const;
|
||||
INLINE PandaNode *get_value_node() const;
|
||||
|
||||
PUBLISHED:
|
||||
void set_value(PN_stdfloat value);
|
||||
void set_value_node(PandaNode *node);
|
||||
|
||||
MAKE_PROPERTY(value, get_value, set_value);
|
||||
MAKE_PROPERTY(value_node, get_value_node, set_value_node);
|
||||
|
||||
protected:
|
||||
virtual AnimGroup *make_copy(AnimGroup *parent) const;
|
||||
|
||||
|
@ -104,7 +104,7 @@ set_table(const CPTA_stdfloat &table) {
|
||||
if (table.size() > 1 && (int)table.size() < num_frames) {
|
||||
// The new table has an invalid number of frames--it doesn't match the
|
||||
// bundle's requirement.
|
||||
nassertv(false);
|
||||
nassert_raise("mismatched number of frames");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,8 @@ PUBLISHED:
|
||||
INLINE bool has_table() const;
|
||||
INLINE void clear_table();
|
||||
|
||||
MAKE_PROPERTY2(table, has_table, get_table, set_table, clear_table);
|
||||
|
||||
public:
|
||||
virtual void write(std::ostream &out, int indent_level) const;
|
||||
|
||||
|
@ -523,6 +523,14 @@ get_draw_region_pcollector() {
|
||||
return _draw_region_pcollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique name used for debugging.
|
||||
*/
|
||||
INLINE const std::string &DisplayRegion::
|
||||
get_debug_name() const {
|
||||
return _debug_name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -677,13 +677,32 @@ do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
|
||||
*/
|
||||
void DisplayRegion::
|
||||
set_active_index(int index) {
|
||||
#ifdef DO_PSTATS
|
||||
#if defined(DO_PSTATS) || !defined(NDEBUG)
|
||||
std::ostringstream strm;
|
||||
strm << "dr_" << index;
|
||||
string name = strm.str();
|
||||
|
||||
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), name);
|
||||
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), name);
|
||||
// To make a more useful name for PStats and debug output, we add the scene
|
||||
// graph name and camera name.
|
||||
NodePath camera = get_camera();
|
||||
if (!camera.is_empty()) {
|
||||
Camera *camera_node = DCAST(Camera, camera.node());
|
||||
if (camera_node != nullptr) {
|
||||
NodePath scene_root = camera_node->get_scene();
|
||||
if (scene_root.is_empty()) {
|
||||
scene_root = camera.get_top();
|
||||
}
|
||||
strm << scene_root.get_name();
|
||||
}
|
||||
}
|
||||
|
||||
// And add the index in case we have two scene graphs with the same name.
|
||||
strm << "#" << index;
|
||||
|
||||
_debug_name = strm.str();
|
||||
#endif
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), _debug_name);
|
||||
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), _debug_name);
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,8 @@ public:
|
||||
INLINE PStatCollector &get_cull_region_pcollector();
|
||||
INLINE PStatCollector &get_draw_region_pcollector();
|
||||
|
||||
INLINE const std::string &get_debug_name() const;
|
||||
|
||||
struct Region {
|
||||
INLINE Region();
|
||||
|
||||
@ -277,6 +279,7 @@ private:
|
||||
|
||||
PStatCollector _cull_region_pcollector;
|
||||
PStatCollector _draw_region_pcollector;
|
||||
std::string _debug_name;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "displayRegionCullCallbackData.h"
|
||||
#include "displayRegionDrawCallbackData.h"
|
||||
#include "callbackGraphicsWindow.h"
|
||||
#include "depthTestAttrib.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
@ -1174,7 +1175,8 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
|
||||
nassertv(sattr->get_shader() != nullptr);
|
||||
const Shader *shader = sattr->get_shader();
|
||||
nassertv(shader != nullptr);
|
||||
nassertv(gsg != nullptr);
|
||||
|
||||
ReMutexHolder holder(_lock);
|
||||
@ -1184,8 +1186,10 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
|
||||
string draw_name = gsg->get_threading_model().get_draw_name();
|
||||
if (draw_name.empty()) {
|
||||
// A single-threaded environment. No problem.
|
||||
gsg->push_group_marker(std::string("Compute ") + shader->get_filename(Shader::ST_compute).get_basename());
|
||||
gsg->set_state_and_transform(state, TransformState::make_identity());
|
||||
gsg->dispatch_compute(work_groups[0], work_groups[1], work_groups[2]);
|
||||
gsg->pop_group_marker();
|
||||
|
||||
} else {
|
||||
// A multi-threaded environment. We have to wait until the draw thread
|
||||
@ -1431,7 +1435,13 @@ cull_and_draw_together(GraphicsEngine::Windows wlist,
|
||||
}
|
||||
|
||||
if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) {
|
||||
if (win->is_any_clear_active()) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
gsg->push_group_marker("Clear");
|
||||
win->clear(current_thread);
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; i++) {
|
||||
@ -1468,6 +1478,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
nassertv(gsg != nullptr);
|
||||
|
||||
gsg->push_group_marker(dr->get_debug_name());
|
||||
|
||||
PT(SceneSetup) scene_setup;
|
||||
|
||||
{
|
||||
@ -1476,6 +1488,7 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
gsg->prepare_display_region(&dr_reader);
|
||||
|
||||
if (dr_reader.is_any_clear_active()) {
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
gsg->clear(dr);
|
||||
}
|
||||
|
||||
@ -1512,6 +1525,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1651,7 +1666,12 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
// a current context for PStatGPUTimer to work.
|
||||
{
|
||||
PStatGPUTimer timer(gsg, win->get_draw_window_pcollector(), current_thread);
|
||||
if (win->is_any_clear_active()) {
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
win->get_gsg()->push_group_marker("Clear");
|
||||
win->clear(current_thread);
|
||||
win->get_gsg()->pop_group_marker();
|
||||
}
|
||||
|
||||
if (display_cat.is_spam()) {
|
||||
display_cat.spam()
|
||||
@ -2000,6 +2020,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
// Statistics
|
||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
gsg->push_group_marker(dr->get_debug_name());
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
@ -2015,6 +2037,7 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
win->change_scenes(&dr_reader);
|
||||
gsg->prepare_display_region(&dr_reader);
|
||||
if (dr_reader.is_any_clear_active()) {
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
gsg->clear(dr_reader.get_object());
|
||||
}
|
||||
|
||||
@ -2024,9 +2047,12 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
if (cbobj != nullptr) {
|
||||
// Issue the draw callback on this DisplayRegion.
|
||||
|
||||
// Set the GSG to the initial state.
|
||||
// Set the GSG to the initial state. We disable depth testing since that
|
||||
// is the default OpenGL state, and some libraries (eg. Kivy) expect that.
|
||||
static CPT(RenderState) state = RenderState::make(
|
||||
DepthTestAttrib::make(DepthTestAttrib::M_none));
|
||||
gsg->clear_before_callback();
|
||||
gsg->set_state_and_transform(RenderState::make_empty(), TransformState::make_identity());
|
||||
gsg->set_state_and_transform(state, TransformState::make_identity());
|
||||
|
||||
DisplayRegionDrawCallbackData cbdata(cull_result, scene_setup);
|
||||
cbobj->do_callback(&cbdata);
|
||||
@ -2034,11 +2060,7 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
// We don't trust the state the callback may have left us in.
|
||||
gsg->clear_state_and_transform();
|
||||
|
||||
// The callback has taken care of the drawing.
|
||||
return;
|
||||
}
|
||||
|
||||
if (cull_result == nullptr || scene_setup == nullptr) {
|
||||
} else if (cull_result == nullptr || scene_setup == nullptr) {
|
||||
// Nothing to see here.
|
||||
|
||||
} else if (dr->is_stereo()) {
|
||||
@ -2059,6 +2081,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2668,8 +2692,14 @@ thread_main() {
|
||||
|
||||
case TS_do_compute:
|
||||
nassertd(_gsg != nullptr && _state != nullptr) break;
|
||||
{
|
||||
const ShaderAttrib *sattr;
|
||||
_state->get_attrib(sattr);
|
||||
_gsg->push_group_marker(std::string("Compute ") + sattr->get_shader()->get_filename(Shader::ST_compute).get_basename());
|
||||
_gsg->set_state_and_transform(_state, TransformState::make_identity());
|
||||
_gsg->dispatch_compute(_work_groups[0], _work_groups[1], _work_groups[2]);
|
||||
_gsg->pop_group_marker();
|
||||
}
|
||||
break;
|
||||
|
||||
case TS_do_extract:
|
||||
|
@ -703,6 +703,15 @@ get_draw_window_pcollector() {
|
||||
return _draw_window_pcollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PStatCollector for timing the clear operation for just this
|
||||
* GraphicsOutput.
|
||||
*/
|
||||
INLINE PStatCollector &GraphicsOutput::
|
||||
get_clear_window_pcollector() {
|
||||
return _clear_window_pcollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the spam message associated with begin_frame
|
||||
*/
|
||||
|
@ -77,6 +77,7 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
_lock("GraphicsOutput"),
|
||||
_cull_window_pcollector(_cull_pcollector, name),
|
||||
_draw_window_pcollector(_draw_pcollector, name),
|
||||
_clear_window_pcollector(_draw_window_pcollector, "Clear"),
|
||||
_size(0, 0)
|
||||
{
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
@ -411,15 +412,39 @@ is_active() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
CDLockedReader cdata(_cycler);
|
||||
if (!cdata->_active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cdata->_one_shot_frame != -1) {
|
||||
// If one_shot is in effect, then we are active only for the one indicated
|
||||
// frame.
|
||||
if (cdata->_one_shot_frame != ClockObject::get_global_clock()->get_frame_count()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return cdata->_active;
|
||||
|
||||
// If the window has a clear value set, it is active.
|
||||
if (is_any_clear_active()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we triggered a copy operation, it is also active.
|
||||
if (_trigger_copy) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The window is active if at least one display region is active.
|
||||
if (cdata->_active_display_regions_stale) {
|
||||
CDWriter cdataw(((GraphicsOutput *)this)->_cycler, cdata, false);
|
||||
((GraphicsOutput *)this)->do_determine_display_regions(cdataw);
|
||||
return !cdataw->_active_display_regions.empty();
|
||||
} else {
|
||||
return !cdata->_active_display_regions.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -289,6 +289,7 @@ public:
|
||||
|
||||
INLINE PStatCollector &get_cull_window_pcollector();
|
||||
INLINE PStatCollector &get_draw_window_pcollector();
|
||||
INLINE PStatCollector &get_clear_window_pcollector();
|
||||
|
||||
protected:
|
||||
virtual void pixel_factor_changed();
|
||||
@ -409,6 +410,7 @@ protected:
|
||||
static PStatCollector _draw_pcollector;
|
||||
PStatCollector _cull_window_pcollector;
|
||||
PStatCollector _draw_window_pcollector;
|
||||
PStatCollector _clear_window_pcollector;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -92,7 +92,6 @@ PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes
|
||||
PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures");
|
||||
PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive:Draw");
|
||||
PStatCollector GraphicsStateGuardian::_draw_set_state_pcollector("Draw:Set State");
|
||||
PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
|
||||
PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
|
||||
PStatCollector GraphicsStateGuardian::_compute_dispatch_pcollector("Draw:Compute dispatch");
|
||||
|
||||
@ -744,7 +743,7 @@ issue_timer_query(int pstats_index) {
|
||||
*/
|
||||
void GraphicsStateGuardian::
|
||||
dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
|
||||
nassertv(false /* Compute shaders not supported by GSG */);
|
||||
nassert_raise("Compute shaders not supported by GSG");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -685,7 +685,6 @@ public:
|
||||
static PStatCollector _texture_state_pcollector;
|
||||
static PStatCollector _draw_primitive_pcollector;
|
||||
static PStatCollector _draw_set_state_pcollector;
|
||||
static PStatCollector _clear_pcollector;
|
||||
static PStatCollector _flush_pcollector;
|
||||
static PStatCollector _compute_dispatch_pcollector;
|
||||
static PStatCollector _wait_occlusion_pcollector;
|
||||
|
@ -192,7 +192,8 @@ write(ostream &out, int indent_level) const {
|
||||
|
||||
default:
|
||||
// invalid group type
|
||||
nassertv(false);
|
||||
nassert_raise("invalid EggGroup type");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_of_type(EggBin::get_class_type())) {
|
||||
|
@ -445,7 +445,8 @@ add_vertex(EggVertex *vertex, int index) {
|
||||
}
|
||||
|
||||
// Oops, you duplicated a vertex index.
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("duplicate vertex index");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_unique_vertices.insert(vertex);
|
||||
|
@ -142,7 +142,8 @@ get_value(int row, LMatrix4d &mat) const {
|
||||
|
||||
default:
|
||||
// The contents string contained an invalid letter.
|
||||
nassertv(false);
|
||||
nassert_raise("invalid letter in contents string");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,7 +368,8 @@ get_value(int row, LMatrix4d &mat) const {
|
||||
|
||||
default:
|
||||
// One of the child tables had an invalid name.
|
||||
nassertv(false);
|
||||
nassert_raise("invalid name in child table");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ wake_task(AsyncTask *task) {
|
||||
return;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected task state");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ output(std::ostream &out) const {
|
||||
*/
|
||||
void PointerEvent::
|
||||
write_datagram(Datagram &dg) const {
|
||||
nassertv(false && "This function not implemented yet.");
|
||||
nassert_raise("This function not implemented yet.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,5 +37,5 @@ write_datagram(Datagram &dg) const {
|
||||
*/
|
||||
void PointerEvent::
|
||||
read_datagram(DatagramIterator &scan) {
|
||||
nassertv(false && "This function not implemented yet.");
|
||||
nassert_raise("This function not implemented yet.");
|
||||
}
|
||||
|
@ -333,7 +333,10 @@ close() {
|
||||
if (_owns_stream) {
|
||||
// We prefer to delete the IStreamWrapper over the ostream, if possible.
|
||||
if (_read != nullptr) {
|
||||
// Only delete it if no SubStream is still referencing it.
|
||||
if (!_read->unref()) {
|
||||
delete _read;
|
||||
}
|
||||
} else if (_write != nullptr) {
|
||||
delete _write;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#endif // HAVE_TAR
|
||||
|
||||
#ifdef HAVE_TAR
|
||||
istream *Patchfile::_tar_istream = nullptr;
|
||||
std::istream *Patchfile::_tar_istream = nullptr;
|
||||
#endif // HAVE_TAR
|
||||
|
||||
using std::endl;
|
||||
|
@ -88,6 +88,13 @@ open(IStreamWrapper *source, OStreamWrapper *dest, streampos start, streampos en
|
||||
_append = append;
|
||||
_gpos = _start;
|
||||
_ppos = _start;
|
||||
|
||||
if (source != nullptr) {
|
||||
source->ref();
|
||||
}
|
||||
if (dest != nullptr) {
|
||||
dest->ref();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,6 +105,12 @@ close() {
|
||||
// Make sure the write buffer is flushed.
|
||||
sync();
|
||||
|
||||
if (_source != nullptr && !_source->unref()) {
|
||||
delete _source;
|
||||
}
|
||||
if (_dest != nullptr && !_dest->unref()) {
|
||||
delete _dest;
|
||||
}
|
||||
_source = nullptr;
|
||||
_dest = nullptr;
|
||||
_start = 0;
|
||||
|
@ -23,6 +23,7 @@
|
||||
class EXPCL_PANDA_EXPRESS SubStreamBuf : public std::streambuf {
|
||||
public:
|
||||
SubStreamBuf();
|
||||
SubStreamBuf(const SubStreamBuf ©) = delete;
|
||||
virtual ~SubStreamBuf();
|
||||
|
||||
void open(IStreamWrapper *source, OStreamWrapper *dest, std::streampos start, std::streampos end, bool append);
|
||||
|
@ -210,6 +210,23 @@ FfmpegAudioCursor::
|
||||
*/
|
||||
void FfmpegAudioCursor::
|
||||
cleanup() {
|
||||
if (_audio_ctx && _audio_ctx->codec) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
|
||||
// We need to drain the codec to prevent a memory leak.
|
||||
avcodec_send_packet(_audio_ctx, nullptr);
|
||||
while (avcodec_receive_frame(_audio_ctx, _frame) == 0) {}
|
||||
avcodec_flush_buffers(_audio_ctx);
|
||||
#endif
|
||||
|
||||
avcodec_close(_audio_ctx);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
|
||||
avcodec_free_context(&_audio_ctx);
|
||||
#else
|
||||
delete _audio_ctx;
|
||||
#endif
|
||||
}
|
||||
_audio_ctx = nullptr;
|
||||
|
||||
if (_frame) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101)
|
||||
av_frame_free(&_frame);
|
||||
@ -237,16 +254,6 @@ cleanup() {
|
||||
_buffer = nullptr;
|
||||
}
|
||||
|
||||
if ((_audio_ctx)&&(_audio_ctx->codec)) {
|
||||
avcodec_close(_audio_ctx);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
|
||||
avcodec_free_context(&_audio_ctx);
|
||||
#else
|
||||
delete _audio_ctx;
|
||||
#endif
|
||||
}
|
||||
_audio_ctx = nullptr;
|
||||
|
||||
if (_format_ctx) {
|
||||
_ffvfile.close();
|
||||
_format_ctx = nullptr;
|
||||
|
@ -595,7 +595,14 @@ close_stream() {
|
||||
// Hold the global lock while we free avcodec objects.
|
||||
ReMutexHolder av_holder(_av_lock);
|
||||
|
||||
if ((_video_ctx)&&(_video_ctx->codec)) {
|
||||
if (_video_ctx && _video_ctx->codec) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100)
|
||||
// We need to drain the codec to prevent a memory leak.
|
||||
avcodec_send_packet(_video_ctx, nullptr);
|
||||
while (avcodec_receive_frame(_video_ctx, _frame) == 0) {}
|
||||
avcodec_flush_buffers(_video_ctx);
|
||||
#endif
|
||||
|
||||
avcodec_close(_video_ctx);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 52, 0)
|
||||
avcodec_free_context(&_video_ctx);
|
||||
|
@ -189,7 +189,10 @@ register_protocol() {
|
||||
}
|
||||
|
||||
// Here's a good place to call this global ffmpeg initialization function.
|
||||
// However, ffmpeg (but not libav) deprecated this, hence this check.
|
||||
#if LIBAVFORMAT_VERSION_MICRO < 100 || LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
av_register_all();
|
||||
#endif
|
||||
|
||||
// And this one.
|
||||
avformat_network_init();
|
||||
|
@ -32,7 +32,7 @@ get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
|
||||
UpdateSeq modified) {
|
||||
#if defined(OPENGLES) || !defined(SUPPORT_FIXED_FUNCTION)
|
||||
// Display lists not supported by OpenGL ES.
|
||||
nassertr(false, false);
|
||||
nassert_raise("OpenGL ES does not support display lists");
|
||||
return false;
|
||||
|
||||
#else
|
||||
|
@ -113,8 +113,6 @@ clear(Thread *current_thread) {
|
||||
<< get_name() << " " << (void *)this << "\n";
|
||||
}
|
||||
|
||||
PStatGPUTimer timer(glgsg, glgsg->_clear_pcollector);
|
||||
|
||||
// Disable the scissor test, so we can clear the whole buffer.
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glgsg->_scissor_enabled = false;
|
||||
@ -232,6 +230,9 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
}
|
||||
}
|
||||
|
||||
CLP(GraphicsStateGuardian) *glgsg = (CLP(GraphicsStateGuardian) *)_gsg.p();
|
||||
glgsg->push_group_marker(std::string(CLASSPREFIX_QUOTED "GraphicsBuffer ") + get_name());
|
||||
|
||||
// Figure out the desired size of the buffer.
|
||||
if (mode == FM_render) {
|
||||
clear_cube_map_selection();
|
||||
@ -257,6 +258,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (_needs_rebuild) {
|
||||
// If we still need rebuild, something went wrong with
|
||||
// rebuild_bitplanes().
|
||||
glgsg->pop_group_marker();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1316,6 +1318,8 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
report_my_gl_errors();
|
||||
|
||||
glgsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,30 @@
|
||||
* @date 1999-02-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* If debug markers are enabled, pushes the beginning of a group marker.
|
||||
*/
|
||||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
push_group_marker(const std::string &marker) {
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (_glPushGroupMarker != nullptr) {
|
||||
_glPushGroupMarker(marker.size(), marker.data());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* If debug markers are enabled, closes a group debug marker.
|
||||
*/
|
||||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
pop_group_marker() {
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (_glPopGroupMarker != nullptr) {
|
||||
_glPopGroupMarker();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any outstanding error codes and outputs them, if found. If
|
||||
* NDEBUG is defined, this function does nothing. The return value is true if
|
||||
|
@ -91,6 +91,7 @@ PStatCollector CLP(GraphicsStateGuardian)::_vertex_array_update_pcollector("Draw
|
||||
PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Update texture");
|
||||
PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO");
|
||||
PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors");
|
||||
PStatCollector CLP(GraphicsStateGuardian)::_check_residency_pcollector("*:PStats:Check residency");
|
||||
|
||||
// The following noop functions are assigned to the corresponding glext
|
||||
// function pointers in the class, in case the functions are not defined by
|
||||
@ -616,6 +617,22 @@ reset() {
|
||||
// Print out a list of all extensions.
|
||||
report_extensions();
|
||||
|
||||
// Check if we are running under a profiling tool such as apitrace.
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (has_extension("GL_EXT_debug_marker")) {
|
||||
_glPushGroupMarker = (PFNGLPUSHGROUPMARKEREXTPROC)
|
||||
get_extension_func("glPushGroupMarkerEXT");
|
||||
_glPopGroupMarker = (PFNGLPOPGROUPMARKEREXTPROC)
|
||||
get_extension_func("glPopGroupMarkerEXT");
|
||||
|
||||
// Start a group right away.
|
||||
push_group_marker("reset");
|
||||
} else {
|
||||
_glPushGroupMarker = nullptr;
|
||||
_glPopGroupMarker = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize OpenGL debugging output first, if enabled and supported.
|
||||
_supports_debug = false;
|
||||
_use_object_labels = false;
|
||||
@ -1737,14 +1754,6 @@ reset() {
|
||||
get_extension_func("glUniform3iv");
|
||||
_glUniform4iv = (PFNGLUNIFORM4IVPROC)
|
||||
get_extension_func("glUniform4iv");
|
||||
_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
|
||||
get_extension_func("glUniform1uiv");
|
||||
_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
|
||||
get_extension_func("glUniform2uiv");
|
||||
_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
|
||||
get_extension_func("glUniform3uiv");
|
||||
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
|
||||
get_extension_func("glUniform4uiv");
|
||||
_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
|
||||
get_extension_func("glUniformMatrix3fv");
|
||||
_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
|
||||
@ -1759,9 +1768,35 @@ reset() {
|
||||
get_extension_func("glVertexAttribPointer");
|
||||
|
||||
if (is_at_least_gl_version(3, 0)) {
|
||||
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
|
||||
get_extension_func("glBindFragDataLocation");
|
||||
_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
|
||||
get_extension_func("glVertexAttribIPointer");
|
||||
_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
|
||||
get_extension_func("glUniform1uiv");
|
||||
_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
|
||||
get_extension_func("glUniform2uiv");
|
||||
_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
|
||||
get_extension_func("glUniform3uiv");
|
||||
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
|
||||
get_extension_func("glUniform4uiv");
|
||||
|
||||
} else if (has_extension("GL_EXT_gpu_shader4")) {
|
||||
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
|
||||
get_extension_func("glBindFragDataLocationEXT");
|
||||
_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
|
||||
get_extension_func("glVertexAttribIPointerEXT");
|
||||
_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
|
||||
get_extension_func("glUniform1uivEXT");
|
||||
_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
|
||||
get_extension_func("glUniform2uivEXT");
|
||||
_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
|
||||
get_extension_func("glUniform3uivEXT");
|
||||
_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
|
||||
get_extension_func("glUniform4uivEXT");
|
||||
|
||||
} else {
|
||||
_glBindFragDataLocation = nullptr;
|
||||
_glVertexAttribIPointer = nullptr;
|
||||
}
|
||||
if (is_at_least_gl_version(4, 1) ||
|
||||
@ -1790,6 +1825,7 @@ reset() {
|
||||
_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
|
||||
get_extension_func("glVertexAttribPointerARB");
|
||||
|
||||
_glBindFragDataLocation = nullptr;
|
||||
_glVertexAttribIPointer = nullptr;
|
||||
_glVertexAttribLPointer = nullptr;
|
||||
}
|
||||
@ -1841,6 +1877,13 @@ reset() {
|
||||
} else {
|
||||
_glVertexAttribIPointer = nullptr;
|
||||
}
|
||||
|
||||
if (has_extension("GL_EXT_blend_func_extended")) {
|
||||
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
|
||||
get_extension_func("glBindFragDataLocationEXT");
|
||||
} else {
|
||||
_glBindFragDataLocation = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
@ -3373,6 +3416,8 @@ reset() {
|
||||
}
|
||||
#endif
|
||||
|
||||
pop_group_marker();
|
||||
|
||||
// Now that the GSG has been initialized, make it available for
|
||||
// optimizations.
|
||||
add_gsg(this);
|
||||
@ -3405,7 +3450,6 @@ finish() {
|
||||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
clear(DrawableRegion *clearable) {
|
||||
PStatGPUTimer timer(this, _clear_pcollector);
|
||||
report_my_gl_errors();
|
||||
|
||||
if (!clearable->is_any_clear_active()) {
|
||||
@ -3710,6 +3754,10 @@ clear_before_callback() {
|
||||
_glClientActiveTexture(GL_TEXTURE0);
|
||||
#endif
|
||||
|
||||
// It's also quite reasonable to presume there aren't any funny color write
|
||||
// mask settings active.
|
||||
clear_color_write_mask();
|
||||
|
||||
// Clear the bound sampler object, so that we do not inadvertently override
|
||||
// the callback's desired sampler settings.
|
||||
#ifndef OPENGLES_1
|
||||
@ -3932,6 +3980,7 @@ end_frame(Thread *current_thread) {
|
||||
// connects PStats, at which point it will then correct the assessment. No
|
||||
// harm done.
|
||||
if (has_fixed_function_pipeline() && PStatClient::is_connected()) {
|
||||
PStatTimer timer(_check_residency_pcollector);
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
|
||||
|
||||
@ -7191,6 +7240,8 @@ do_issue_shade_model() {
|
||||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_shader() {
|
||||
PStatTimer timer(_draw_set_state_shader_pcollector);
|
||||
|
||||
ShaderContext *context = 0;
|
||||
Shader *shader = (Shader *)_target_shader->get_shader();
|
||||
|
||||
@ -10640,6 +10691,85 @@ reissue_transforms() {
|
||||
_current_vertex_format.clear();
|
||||
memset(_vertex_attrib_columns, 0, sizeof(const GeomVertexColumn *) * 32);
|
||||
#endif
|
||||
|
||||
// Some libraries (Kivy) leave their buffers bound. How clumsy of them.
|
||||
if (_supports_buffers) {
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
_current_vbuffer_index = 0;
|
||||
_current_ibuffer_index = 0;
|
||||
}
|
||||
#ifndef OPENGLES
|
||||
if (_supports_glsl) {
|
||||
_glDisableVertexAttribArray(0);
|
||||
_glDisableVertexAttribArray(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Since this is called by clear_state_and_transform(), we also should reset
|
||||
// the states that won't automatically be respecified when clearing the
|
||||
// state mask.
|
||||
_active_color_write_mask = ColorWriteAttrib::C_all;
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
if (_dithering_enabled) {
|
||||
glEnable(GL_DITHER);
|
||||
} else {
|
||||
glDisable(GL_DITHER);
|
||||
}
|
||||
if (_depth_test_enabled) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
if (_stencil_test_enabled) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
} else {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
if (_blend_enabled) {
|
||||
glEnable(GL_BLEND);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
#ifndef OPENGLES_2
|
||||
if (_multisample_mode != 0) {
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
} else {
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_SAMPLE_ALPHA_TO_ONE);
|
||||
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
|
||||
}
|
||||
if (_line_smooth_enabled) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
} else {
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_polygon_smooth_enabled) {
|
||||
glEnable(GL_POLYGON_SMOOTH);
|
||||
} else {
|
||||
glDisable(GL_POLYGON_SMOOTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (has_fixed_function_pipeline()) {
|
||||
if (_alpha_test_enabled) {
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
} else {
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
if (_point_smooth_enabled) {
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
} else {
|
||||
glDisable(GL_POINT_SMOOTH);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
@ -10902,7 +11032,6 @@ set_state_and_transform(const RenderState *target,
|
||||
_instance_count = _target_shader->get_instance_count();
|
||||
|
||||
if (_target_shader != _state_shader) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
|
||||
do_issue_shader();
|
||||
_state_shader = _target_shader;
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
@ -11058,7 +11187,7 @@ set_state_and_transform(const RenderState *target,
|
||||
int texture_slot = TextureAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
|
||||
!_state_mask.get_bit(texture_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
|
||||
PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
|
||||
determine_target_texture();
|
||||
do_issue_texture();
|
||||
|
||||
@ -14015,7 +14144,7 @@ extract_texture_image(PTA_uchar &image, size_t &page_size,
|
||||
Texture::ComponentType type,
|
||||
Texture::CompressionMode compression, int n) {
|
||||
#ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
|
||||
nassertr(false, false);
|
||||
nassert_raise("OpenGL ES does not support extracting texture data");
|
||||
return false;
|
||||
#else
|
||||
|
||||
|
@ -146,6 +146,7 @@ typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum d
|
||||
// GLSL shader functions
|
||||
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
||||
typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
|
||||
typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
|
||||
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
|
||||
@ -275,6 +276,9 @@ public:
|
||||
|
||||
static void APIENTRY debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
|
||||
|
||||
INLINE virtual void push_group_marker(const std::string &marker) final;
|
||||
INLINE virtual void pop_group_marker() final;
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
|
||||
@ -960,6 +964,7 @@ public:
|
||||
// GLSL functions
|
||||
PFNGLATTACHSHADERPROC _glAttachShader;
|
||||
PFNGLBINDATTRIBLOCATIONPROC _glBindAttribLocation;
|
||||
PFNGLBINDFRAGDATALOCATIONPROC _glBindFragDataLocation;
|
||||
PFNGLCOMPILESHADERPROC _glCompileShader;
|
||||
PFNGLCREATEPROGRAMPROC _glCreateProgram;
|
||||
PFNGLCREATESHADERPROC _glCreateShader;
|
||||
@ -1091,6 +1096,11 @@ public:
|
||||
GLuint _white_texture;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifndef OPENGLES_1
|
||||
PFNGLPUSHGROUPMARKEREXTPROC _glPushGroupMarker;
|
||||
PFNGLPOPGROUPMARKEREXTPROC _glPopGroupMarker;
|
||||
#endif
|
||||
|
||||
bool _show_texture_usage;
|
||||
int _show_texture_usage_max_size;
|
||||
int _show_texture_usage_index;
|
||||
@ -1118,6 +1128,7 @@ public:
|
||||
static PStatCollector _texture_update_pcollector;
|
||||
static PStatCollector _fbo_bind_pcollector;
|
||||
static PStatCollector _check_error_pcollector;
|
||||
static PStatCollector _check_residency_pcollector;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
|
@ -3219,6 +3219,11 @@ glsl_compile_and_link() {
|
||||
_glgsg->_glBindAttribLocation(_glsl_program, 8, "texcoord");
|
||||
}
|
||||
|
||||
// Also bind the p3d_FragData array to the first index always.
|
||||
if (_glgsg->_glBindFragDataLocation != nullptr) {
|
||||
_glgsg->_glBindFragDataLocation(_glsl_program, 0, "p3d_FragData");
|
||||
}
|
||||
|
||||
// If we requested to retrieve the shader, we should indicate that before
|
||||
// linking.
|
||||
bool retrieve_binary = false;
|
||||
|
@ -71,7 +71,10 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
|
||||
glxGraphicsStateGuardian *glxgsg;
|
||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||
{
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
glXMakeCurrent(_display, _pbuffer, glxgsg->_context);
|
||||
}
|
||||
|
||||
// Now that we have made the context current to a window, we can reset the
|
||||
// GSG state if this is the first time it has been used. (We can't just
|
||||
@ -125,6 +128,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
void glxGraphicsBuffer::
|
||||
close_buffer() {
|
||||
if (_gsg != nullptr) {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
glXMakeCurrent(_display, None, nullptr);
|
||||
|
||||
if (_pbuffer != None) {
|
||||
@ -179,6 +183,8 @@ open_buffer() {
|
||||
|
||||
nassertr(glxgsg->_supports_pbuffer, false);
|
||||
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
|
||||
static const int max_attrib_list = 32;
|
||||
int attrib_list[max_attrib_list];
|
||||
int n = 0;
|
||||
|
@ -74,7 +74,10 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
|
||||
glxGraphicsStateGuardian *glxgsg;
|
||||
DCAST_INTO_R(glxgsg, _gsg, false);
|
||||
{
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
glXMakeCurrent(_display, _glx_pixmap, glxgsg->_context);
|
||||
}
|
||||
|
||||
// Now that we have made the context current to a window, we can reset the
|
||||
// GSG state if this is the first time it has been used. (We can't just
|
||||
@ -127,6 +130,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
*/
|
||||
void glxGraphicsPixmap::
|
||||
close_buffer() {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
if (_gsg != nullptr) {
|
||||
glXMakeCurrent(_display, None, nullptr);
|
||||
_gsg.clear();
|
||||
@ -197,6 +201,7 @@ open_buffer() {
|
||||
}
|
||||
}
|
||||
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
_x_pixmap = XCreatePixmap(_display, _drawable,
|
||||
get_x_size(), get_y_size(), visual_info->depth);
|
||||
if (_x_pixmap == None) {
|
||||
|
@ -64,6 +64,9 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
*/
|
||||
glxGraphicsStateGuardian::
|
||||
~glxGraphicsStateGuardian() {
|
||||
// Actually, the lock might have already destructed, so we can't reliably
|
||||
// grab the X11 lock here.
|
||||
//LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
destroy_temp_xwindow();
|
||||
if (_visuals != nullptr) {
|
||||
XFree(_visuals);
|
||||
@ -224,6 +227,7 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
||||
X11_Display *display,
|
||||
int screen, bool need_pbuffer, bool need_pixmap) {
|
||||
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
_display = display;
|
||||
_screen = screen;
|
||||
_context = nullptr;
|
||||
@ -457,6 +461,7 @@ gl_get_error() const {
|
||||
*/
|
||||
void glxGraphicsStateGuardian::
|
||||
query_gl_version() {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
PosixGraphicsStateGuardian::query_gl_version();
|
||||
|
||||
show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
|
||||
@ -483,6 +488,7 @@ query_gl_version() {
|
||||
*/
|
||||
void glxGraphicsStateGuardian::
|
||||
get_extra_extensions() {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
save_extensions(glXQueryExtensionsString(_display, _screen));
|
||||
}
|
||||
|
||||
@ -497,6 +503,8 @@ do_get_extension_func(const char *name) {
|
||||
nassertr(name != nullptr, nullptr);
|
||||
|
||||
if (glx_get_proc_address) {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
|
||||
// First, check if we have glXGetProcAddress available. This will be
|
||||
// superior if we can get it.
|
||||
|
||||
|
@ -89,6 +89,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
glxgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
glxgsg->push_group_marker(std::string("glxGraphicsWindow ") + get_name());
|
||||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
@ -97,6 +98,34 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after rendering is
|
||||
* completed for a given frame. It should do whatever finalization is
|
||||
* required.
|
||||
*/
|
||||
void glxGraphicsWindow::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
end_frame_spam(mode);
|
||||
nassertv(_gsg != nullptr);
|
||||
|
||||
if (mode == FM_render) {
|
||||
// end_render_texture();
|
||||
copy_to_textures();
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
|
||||
glxGraphicsStateGuardian *glxgsg;
|
||||
DCAST_INTO_V(glxgsg, _gsg);
|
||||
glxgsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after begin_flip() has
|
||||
* been called on all windows, to finish the exchange of the front and back
|
||||
@ -125,6 +154,8 @@ end_flip() {
|
||||
*/
|
||||
void glxGraphicsWindow::
|
||||
close_window() {
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
|
||||
if (_gsg != nullptr) {
|
||||
glXMakeCurrent(_display, None, nullptr);
|
||||
_gsg.clear();
|
||||
@ -175,6 +206,8 @@ open_window() {
|
||||
return false;
|
||||
}
|
||||
|
||||
LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
|
||||
|
||||
if (glxgsg->_fbconfig != None) {
|
||||
setup_colormap(glxgsg->_fbconfig);
|
||||
} else {
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
virtual ~glxGraphicsWindow() {};
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_flip();
|
||||
|
||||
protected:
|
||||
|
@ -1504,7 +1504,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a prepared_objects
|
||||
// that the geom didn't know about.
|
||||
nassertv(false);
|
||||
nassert_raise("unknown PreparedGraphicsObjects");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1844,8 +1844,11 @@ check_valid(const GeomVertexDataPipelineReader *data_reader) const {
|
||||
bool GeomPipelineReader::
|
||||
draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomVertexDataPipelineReader *data_reader, bool force) const {
|
||||
bool all_ok;
|
||||
{
|
||||
PStatTimer timer(Geom::_draw_primitive_setup_pcollector);
|
||||
bool all_ok = gsg->begin_draw_primitives(this, data_reader, force);
|
||||
all_ok = gsg->begin_draw_primitives(this, data_reader, force);
|
||||
}
|
||||
if (all_ok) {
|
||||
Geom::Primitives::const_iterator pi;
|
||||
for (pi = _cdata->_primitives.begin();
|
||||
|
@ -47,7 +47,7 @@ GeomCacheManager() :
|
||||
GeomCacheManager::
|
||||
~GeomCacheManager() {
|
||||
// Shouldn't be deleting this global object.
|
||||
nassertv(false);
|
||||
nassert_raise("attempt to delete GeomCacheManager");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +221,7 @@ add_vertex(int vertex) {
|
||||
((uint32_t *)ptr)[num_rows] = vertex;
|
||||
break;
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unsupported index type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1510,7 +1510,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a prepared_objects
|
||||
// which the data array didn't know about.
|
||||
nassertv(false);
|
||||
nassert_raise("unknown PreparedGraphicsObjects");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2230,7 +2230,7 @@ get_vertex(int i) const {
|
||||
return ((uint32_t *)ptr)[i];
|
||||
break;
|
||||
default:
|
||||
nassertr(false, -1);
|
||||
nassert_raise("unsupported index type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2296,7 +2296,7 @@ get_referenced_vertices(BitArray &bits) const {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unsupported index type");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -139,7 +139,7 @@ CPT(GeomVertexArrayData) GeomTrifans::
|
||||
rotate_impl() const {
|
||||
// Actually, we can't rotate fans without chaging the winding order. It's
|
||||
// an error to define a flat shade model for a GeomTrifan.
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("GeomTrifans cannot have flat shading model");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a prepared_objects
|
||||
// which the data array didn't know about.
|
||||
nassertv(false);
|
||||
nassert_raise("unknown PreparedGraphicsObjects");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1121,8 @@ do_set_color(GeomVertexData *vdata, const LColor &color) {
|
||||
const GeomVertexColumn *column;
|
||||
int array_index;
|
||||
if (!format->get_array_info(InternalName::get_color(), array_index, column)) {
|
||||
nassertv(false);
|
||||
nassert_raise("no color column");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t stride = format->get_array(array_index)->get_stride();
|
||||
|
@ -3705,7 +3705,7 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a prepared_objects
|
||||
// which the texture didn't know about.
|
||||
nassertv(false);
|
||||
nassert_raise("unknown PreparedGraphicsObjects");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4897,8 +4897,8 @@ do_read_ktx(CData *cdata, istream &in, const string &filename, bool header_only)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
nassertr(false, false);
|
||||
break;
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6591,8 +6591,9 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com
|
||||
|
||||
default:
|
||||
// Eh?
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
cdata->_format = F_rgb;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7989,7 +7990,8 @@ convert_from_pfm(PTA_uchar &image, size_t page_size, int z,
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((unsigned char *)p == &image[idx] + page_size);
|
||||
@ -8199,7 +8201,8 @@ convert_to_pfm(PfmFile &pfm, int x_size, int y_size,
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
|
||||
nassertr((unsigned char *)p == &image[idx] + page_size, false);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "depthTestAttrib.h"
|
||||
#include "depthWriteAttrib.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "omniBoundingVolume.h"
|
||||
#include <stdio.h> // For sprintf/snprintf
|
||||
|
||||
PStatCollector SceneGraphAnalyzerMeter::_show_analyzer_pcollector("*:Show scene graph analysis");
|
||||
@ -29,9 +30,16 @@ TypeHandle SceneGraphAnalyzerMeter::_type_handle;
|
||||
*
|
||||
*/
|
||||
SceneGraphAnalyzerMeter::
|
||||
SceneGraphAnalyzerMeter(const std::string &name, PandaNode *node) : TextNode(name) {
|
||||
SceneGraphAnalyzerMeter(const std::string &name, PandaNode *node) :
|
||||
TextNode(name),
|
||||
_last_aspect_ratio(-1) {
|
||||
|
||||
set_cull_callback();
|
||||
|
||||
// Don't do frustum culling, as the text will always be in view.
|
||||
set_bounds(new OmniBoundingVolume());
|
||||
set_final(true);
|
||||
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
|
||||
_update_interval = scene_graph_analyzer_meter_update_interval;
|
||||
@ -41,7 +49,7 @@ SceneGraphAnalyzerMeter(const std::string &name, PandaNode *node) : TextNode(nam
|
||||
|
||||
set_align(A_left);
|
||||
set_transform(LMatrix4::scale_mat(scene_graph_analyzer_meter_scale) *
|
||||
LMatrix4::translate_mat(LVector3::rfu(-1.0f + scene_graph_analyzer_meter_side_margins * scene_graph_analyzer_meter_scale, 0.0f, 1.0f - scene_graph_analyzer_meter_scale)));
|
||||
LMatrix4::translate_mat(LVector3::rfu(scene_graph_analyzer_meter_side_margins * scene_graph_analyzer_meter_scale, 0.0f, -scene_graph_analyzer_meter_scale)));
|
||||
set_card_color(0.0f, 0.0f, 0.0f, 0.4);
|
||||
set_card_as_margin(scene_graph_analyzer_meter_side_margins, scene_graph_analyzer_meter_side_margins, 0.1f, 0.0f);
|
||||
set_usage_hint(Geom::UH_client);
|
||||
@ -77,6 +85,11 @@ setup_window(GraphicsOutput *window) {
|
||||
_root.set_material_off(1);
|
||||
_root.set_two_sided(1, 1);
|
||||
|
||||
// If we don't set this explicitly, Panda will cause it to be rendered
|
||||
// in a back-to-front cull bin, which will cause the bounding volume
|
||||
// to be computed unnecessarily. Saves a little bit of overhead.
|
||||
_root.set_bin("unsorted", 0);
|
||||
|
||||
// Create a display region that covers the entire window.
|
||||
_display_region = _window->make_display_region();
|
||||
_display_region->set_sort(scene_graph_analyzer_meter_layer_sort);
|
||||
@ -87,10 +100,11 @@ setup_window(GraphicsOutput *window) {
|
||||
|
||||
PT(Lens) lens = new OrthographicLens;
|
||||
|
||||
static const PN_stdfloat left = -1.0f;
|
||||
static const PN_stdfloat right = 1.0f;
|
||||
static const PN_stdfloat bottom = -1.0f;
|
||||
static const PN_stdfloat top = 1.0f;
|
||||
// We choose these values such that we can place the text against (0, 0).
|
||||
static const PN_stdfloat left = 0.0f;
|
||||
static const PN_stdfloat right = 2.0f;
|
||||
static const PN_stdfloat bottom = -2.0f;
|
||||
static const PN_stdfloat top = 0.0f;
|
||||
lens->set_film_size(right - left, top - bottom);
|
||||
lens->set_film_offset((right + left) * 0.5, (top + bottom) * 0.5);
|
||||
lens->set_near_far(-1000, 1000);
|
||||
@ -138,6 +152,22 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
// Statistics
|
||||
PStatTimer timer(_show_analyzer_pcollector, current_thread);
|
||||
|
||||
// This is probably a good time to check if the aspect ratio on the window
|
||||
// has changed.
|
||||
int width = _display_region->get_pixel_width();
|
||||
int height = _display_region->get_pixel_height();
|
||||
PN_stdfloat aspect_ratio = 1;
|
||||
if (width != 0 && height != 0) {
|
||||
aspect_ratio = (PN_stdfloat)height / (PN_stdfloat)width;
|
||||
}
|
||||
|
||||
// Scale the transform by the calculated aspect ratio.
|
||||
if (aspect_ratio != _last_aspect_ratio) {
|
||||
_aspect_ratio_transform = TransformState::make_scale(LVecBase3(aspect_ratio, 1, 1));
|
||||
_last_aspect_ratio = aspect_ratio;
|
||||
}
|
||||
data._net_transform = data._net_transform->compose(_aspect_ratio_transform);
|
||||
|
||||
// Check to see if it's time to update.
|
||||
double now = _clock_object->get_frame_time(current_thread);
|
||||
double elapsed = now - _last_update;
|
||||
|
@ -72,6 +72,9 @@ private:
|
||||
PandaNode *_node;
|
||||
ClockObject *_clock_object;
|
||||
|
||||
PN_stdfloat _last_aspect_ratio;
|
||||
CPT(TransformState) _aspect_ratio_transform;
|
||||
|
||||
static PStatCollector _show_analyzer_pcollector;
|
||||
|
||||
public:
|
||||
|
@ -54,7 +54,7 @@ set_default_gsg(GraphicsStateGuardianBase *default_gsg) {
|
||||
LightMutexHolder holder(gsg_list->_lock);
|
||||
if (find(gsg_list->_gsgs.begin(), gsg_list->_gsgs.end(), default_gsg) == gsg_list->_gsgs.end()) {
|
||||
// The specified GSG doesn't exist or it has already destructed.
|
||||
nassertv(false);
|
||||
nassert_raise("GSG not found or already destructed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,9 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void push_group_marker(const std::string &marker) {}
|
||||
virtual void pop_group_marker() {}
|
||||
|
||||
PUBLISHED:
|
||||
static GraphicsStateGuardianBase *get_default_gsg();
|
||||
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
|
||||
|
@ -59,7 +59,8 @@ FlacAudioCursor::
|
||||
FlacAudioCursor(FlacAudio *src, std::istream *stream) :
|
||||
MovieAudioCursor(src),
|
||||
_is_valid(false),
|
||||
_drflac(nullptr)
|
||||
_drflac(nullptr),
|
||||
_stream(stream)
|
||||
{
|
||||
nassertv(stream != nullptr);
|
||||
nassertv(stream->good());
|
||||
@ -91,6 +92,9 @@ FlacAudioCursor::
|
||||
if (_drflac != nullptr) {
|
||||
drflac_close(_drflac);
|
||||
}
|
||||
if (_stream != nullptr) {
|
||||
VirtualFileSystem::close_read_file(_stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
|
||||
protected:
|
||||
drflac *_drflac;
|
||||
std::istream *_stream;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -43,7 +43,7 @@ Socket_Address(const struct sockaddr &inaddr) {
|
||||
_addr6 = (const sockaddr_in6 &)inaddr;
|
||||
|
||||
} else {
|
||||
nassertv(false);
|
||||
nassert_raise("unsupported address family");
|
||||
clear();
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ operator == (const Socket_Address &in) const {
|
||||
}
|
||||
|
||||
// Unsupported address family.
|
||||
nassertr(false, false);
|
||||
nassert_raise("unsupported address family");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ operator < (const Socket_Address &in) const {
|
||||
}
|
||||
|
||||
// Unsupported address family.
|
||||
nassertr(false, false);
|
||||
nassert_raise("unsupported address family");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ get_ip() const {
|
||||
getnameinfo(&_addr, sizeof(sockaddr_in6), buf, sizeof(buf), nullptr, 0, NI_NUMERICHOST);
|
||||
|
||||
} else {
|
||||
nassertr(false, std::string());
|
||||
nassert_raise("unsupported address family");
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
@ -124,7 +124,7 @@ get_ip_port() const {
|
||||
sprintf(buf + strlen(buf), "]:%hu", get_port());
|
||||
|
||||
} else {
|
||||
nassertr(false, std::string());
|
||||
nassert_raise("unsupported address family");
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
|
@ -478,7 +478,8 @@ check_send_error(bool okflag) {
|
||||
if (!okflag) {
|
||||
static ConfigVariableBool abort_send_error("abort-send-error", false);
|
||||
if (abort_send_error) {
|
||||
nassertr(false, false);
|
||||
nassert_raise("send error");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume any error means the connection has been reset; tell our manager
|
||||
|
@ -46,7 +46,8 @@ DatagramTCPHeader(const NetDatagram &datagram, int header_size) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("invalid header size");
|
||||
return;
|
||||
}
|
||||
|
||||
nassertv((int)_header.get_length() == header_size);
|
||||
|
@ -276,7 +276,7 @@ get_timewarp_curve(int n) const {
|
||||
n--;
|
||||
}
|
||||
}
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("index out of range");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ make_new_bin(int bin_index, GraphicsStateGuardianBase *gsg,
|
||||
}
|
||||
|
||||
// Hmm, unknown (or unregistered) bin type.
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("unknown bin type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,10 @@ draw(Thread *current_thread) {
|
||||
nassertv(bin_index >= 0);
|
||||
|
||||
if (bin_index < (int)_bins.size() && _bins[bin_index] != nullptr) {
|
||||
|
||||
_gsg->push_group_marker(_bins[bin_index]->get_name());
|
||||
_bins[bin_index]->draw(force, current_thread);
|
||||
_gsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ make(LightAttrib::Operation op, Light *light) {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ make(LightAttrib::Operation op, Light *light1, Light *light2) {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ make(LightAttrib::Operation op, Light *light1, Light *light2,
|
||||
return attrib;
|
||||
}
|
||||
|
||||
nassertr(false, make());
|
||||
nassert_raise("invalid operation");
|
||||
return make();
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,8 @@ get_state(const NodePath &other, Thread *current_thread) const {
|
||||
} else {
|
||||
pgraph_cat.error()
|
||||
<< *this << " is not related to " << other << "\n";
|
||||
nassertr(false, RenderState::make_empty());
|
||||
nassert_raise("unrelated nodes");
|
||||
return RenderState::make_empty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,7 +793,8 @@ get_transform(const NodePath &other, Thread *current_thread) const {
|
||||
} else {
|
||||
pgraph_cat.error()
|
||||
<< *this << " is not related to " << other << "\n";
|
||||
nassertr(false, TransformState::make_identity());
|
||||
nassert_raise("unrelated nodes");
|
||||
return TransformState::make_identity();
|
||||
}
|
||||
}
|
||||
|
||||
@ -877,7 +879,8 @@ get_prev_transform(const NodePath &other, Thread *current_thread) const {
|
||||
} else {
|
||||
pgraph_cat.error()
|
||||
<< *this << " is not related to " << other << "\n";
|
||||
nassertr(false, TransformState::make_identity());
|
||||
nassert_raise("unrelated nodes");
|
||||
return TransformState::make_identity();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2383,7 +2383,8 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map, Thread *current_thread) const
|
||||
<< "Don't know how to copy nodes of type " << get_type() << "\n";
|
||||
|
||||
if (no_unsupported_copy) {
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("unsupported copy");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ register_slot(TypeHandle type_handle, int sort, RenderAttrib *default_attrib) {
|
||||
pgraph_cat->error()
|
||||
<< "Too many registered RenderAttribs; not registering "
|
||||
<< type_handle << "\n";
|
||||
nassertr(false, 0);
|
||||
nassert_raise("out of RenderAttrib slots");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -333,7 +333,8 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||
<< child_node->get_type() << "\n";
|
||||
|
||||
if (no_unsupported_copy) {
|
||||
nassertv(false);
|
||||
nassert_raise("unsupported copy");
|
||||
return;
|
||||
}
|
||||
resist_copy = true;
|
||||
|
||||
|
@ -85,7 +85,7 @@ void AmbientLight::
|
||||
bind(GraphicsStateGuardianBase *, const NodePath &, int) {
|
||||
// AmbientLights aren't bound to light id's; this function should never be
|
||||
// called.
|
||||
nassertv(false);
|
||||
nassert_raise("cannot bind AmbientLight");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,7 +161,8 @@ call_python_func(PyObject *function, PyObject *args) {
|
||||
#ifndef HAVE_THREADS
|
||||
// Shouldn't be possible to come here without having some kind of
|
||||
// threading support enabled.
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("threading support disabled");
|
||||
return nullptr;
|
||||
#else
|
||||
|
||||
#ifdef SIMPLE_THREADS
|
||||
|
@ -346,7 +346,8 @@ load(const PNMImage &pnmimage) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -410,7 +411,8 @@ store(PNMImage &pnmimage) const {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -877,7 +879,8 @@ set_no_data_nan(int num_channels) {
|
||||
_has_point = has_point_nan_4;
|
||||
break;
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
clear_no_data_value();
|
||||
@ -909,7 +912,8 @@ set_no_data_value(const LPoint4f &no_data_value) {
|
||||
_has_point = has_point_4;
|
||||
break;
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -938,7 +942,8 @@ set_no_data_threshold(const LPoint4f &no_data_value) {
|
||||
_has_point = has_point_threshold_4;
|
||||
break;
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1121,7 +1126,8 @@ quick_filter_from(const PfmFile &from) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return;
|
||||
}
|
||||
|
||||
new_data.push_back(0.0);
|
||||
@ -1826,7 +1832,8 @@ compute_planar_bounds(const LPoint2f ¢er, PN_float32 point_dist, PN_float32
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("invalid coordinate system");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Rotate the bounding volume back into the original space of the screen.
|
||||
@ -1879,7 +1886,8 @@ compute_sample_point(LPoint3f &result,
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,8 +596,8 @@ set_color_space(ColorSpace color_space) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
break;
|
||||
nassert_raise("invalid color space");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the new encoding settings.
|
||||
@ -852,7 +852,7 @@ get_channel_val(int x, int y, int channel) const {
|
||||
pnmimage_cat.error()
|
||||
<< "Invalid request for channel " << channel << " in "
|
||||
<< get_num_channels() << "-channel image.\n";
|
||||
nassertr(false, 0);
|
||||
nassert_raise("unexpected channel count");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -888,7 +888,8 @@ set_channel_val(int x, int y, int channel, xelval value) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -918,7 +919,7 @@ get_channel(int x, int y, int channel) const {
|
||||
pnmimage_cat.error()
|
||||
<< "Invalid request for channel " << channel << " in "
|
||||
<< get_num_channels() << "-channel image.\n";
|
||||
nassertr(false, 0);
|
||||
nassert_raise("unexpected channel count");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -954,7 +955,8 @@ set_channel(int x, int y, int channel, float value) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("unexpected channel count");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2126,7 +2128,7 @@ setup_encoding() {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("invalid color space");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -2153,7 +2155,7 @@ setup_encoding() {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertv(false);
|
||||
nassert_raise("invalid color space");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -295,29 +295,6 @@ PixelSpec(const xel &rgb, xelval alpha) :
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE PNMImageHeader::PixelSpec::
|
||||
PixelSpec(const PixelSpec ©) :
|
||||
_red(copy._red),
|
||||
_green(copy._green),
|
||||
_blue(copy._blue),
|
||||
_alpha(copy._alpha)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void PNMImageHeader::PixelSpec::
|
||||
operator = (const PixelSpec ©) {
|
||||
_red = copy._red;
|
||||
_green = copy._green;
|
||||
_blue = copy._blue;
|
||||
_alpha = copy._alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -113,6 +113,9 @@ PUBLISHED:
|
||||
// make_histogram(). Note that pixels are stored by integer value, not by
|
||||
// floating-point scaled value.
|
||||
class EXPCL_PANDA_PNMIMAGE PixelSpec {
|
||||
public:
|
||||
INLINE PixelSpec() = default;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE PixelSpec(xelval gray_value);
|
||||
INLINE PixelSpec(xelval gray_value, xelval alpha);
|
||||
@ -120,8 +123,6 @@ PUBLISHED:
|
||||
INLINE PixelSpec(xelval red, xelval green, xelval blue, xelval alpha);
|
||||
INLINE PixelSpec(const xel &rgb);
|
||||
INLINE PixelSpec(const xel &rgb, xelval alpha);
|
||||
INLINE PixelSpec(const PixelSpec ©);
|
||||
INLINE void operator = (const PixelSpec ©);
|
||||
|
||||
INLINE bool operator < (const PixelSpec &other) const;
|
||||
INLINE bool operator == (const PixelSpec &other) const;
|
||||
|
@ -283,7 +283,8 @@ write_pfm(const PfmFile &pfm) {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
(*_file) << pfm.get_x_size() << " " << pfm.get_y_size() << "\n";
|
||||
|
||||
|
@ -135,7 +135,8 @@ write_header() {
|
||||
break;
|
||||
|
||||
default:
|
||||
nassertr(false, false);
|
||||
nassert_raise("unexpected channel count");
|
||||
return false;
|
||||
}
|
||||
|
||||
// For some reason, we have problems with SGI image files whose pixmax value
|
||||
|
@ -93,7 +93,7 @@ has_max_num_bits() {
|
||||
*/
|
||||
INLINE int SparseArray::
|
||||
get_max_num_bits() {
|
||||
nassertr(false, 0);
|
||||
nassert_raise("SparseArray has no maximum bit count");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2536,7 +2536,7 @@ get_primitive(TypeHandle prim_type) {
|
||||
return _points;
|
||||
}
|
||||
|
||||
nassertr(false, nullptr);
|
||||
nassert_raise("unexpected primitive type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -202,8 +202,6 @@ make_geom_munger(const RenderState *state, Thread *current_thread) {
|
||||
*/
|
||||
void TinyGraphicsStateGuardian::
|
||||
clear(DrawableRegion *clearable) {
|
||||
PStatTimer timer(_clear_pcollector);
|
||||
|
||||
if ((!clearable->get_clear_color_active())&&
|
||||
(!clearable->get_clear_depth_active())&&
|
||||
(!clearable->get_clear_stencil_active())) {
|
||||
|
@ -487,7 +487,8 @@ fetch_buffer() {
|
||||
block[i + 2] = ex;
|
||||
}
|
||||
#else
|
||||
nassertr(false /* Not compiled with JPEG support*/, nullptr);
|
||||
nassert_raise("JPEG support not compiled-in");
|
||||
return nullptr;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
wglgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
wglgsg->push_group_marker(std::string("wglGraphicsWindow ") + get_name());
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
@ -114,6 +115,10 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_V(wglgsg, _gsg);
|
||||
wglgsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,11 @@ ConfigVariableBool x_error_abort
|
||||
"of an error from the X window system. This can make it easier "
|
||||
"to discover where these errors are generated."));
|
||||
|
||||
ConfigVariableBool x_init_threads
|
||||
("x-init-threads", false,
|
||||
PRC_DESC("Set this true to ask Panda3D to call XInitThreads() upon loading "
|
||||
"the display module, which may help with some threading issues."));
|
||||
|
||||
ConfigVariableInt x_wheel_up_button
|
||||
("x-wheel-up-button", 4,
|
||||
PRC_DESC("This is the mouse button index of the wheel_up event: which "
|
||||
|
@ -26,6 +26,7 @@ extern EXPCL_PANDAX11 void init_libx11display();
|
||||
|
||||
extern ConfigVariableString display_cfg;
|
||||
extern ConfigVariableBool x_error_abort;
|
||||
extern ConfigVariableBool x_init_threads;
|
||||
|
||||
extern ConfigVariableInt x_wheel_up_button;
|
||||
extern ConfigVariableInt x_wheel_down_button;
|
||||
|
@ -66,6 +66,12 @@ x11GraphicsPipe(const std::string &display) :
|
||||
_im = (XIM)nullptr;
|
||||
_hidden_cursor = None;
|
||||
|
||||
// According to the documentation, we should call this before making any
|
||||
// other Xlib calls if we wish to use the Xlib locking system.
|
||||
if (x_init_threads) {
|
||||
XInitThreads();
|
||||
}
|
||||
|
||||
install_error_handlers();
|
||||
|
||||
_display = XOpenDisplay(display_spec.c_str());
|
||||
|
@ -218,6 +218,23 @@ move_pointer(int device, int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the entire framebuffer before rendering, according to the settings
|
||||
* of get_color_clear_active() and get_depth_clear_active() (inherited from
|
||||
* DrawableRegion).
|
||||
*
|
||||
* This function is called only within the draw thread.
|
||||
*/
|
||||
void x11GraphicsWindow::
|
||||
clear(Thread *current_thread) {
|
||||
if (is_any_clear_active()) {
|
||||
// Evidently the NVIDIA driver may call glXCreateNewContext inside
|
||||
// prepare_display_region, so we need to hold the X11 lock.
|
||||
LightReMutexHolder holder(x11GraphicsPipe::_x_mutex);
|
||||
GraphicsOutput::clear(current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread before beginning
|
||||
* rendering for a given frame. It should do whatever setup is required, and
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
virtual MouseData get_pointer(int device) const;
|
||||
virtual bool move_pointer(int device, int x, int y);
|
||||
|
||||
virtual void clear(Thread *current_thread);
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
|
@ -79,7 +79,7 @@ Open(const char *file, const char *mode) {
|
||||
return new PandaIOStream(*stream);
|
||||
|
||||
} else {
|
||||
nassertr(false, nullptr); // Not implemented on purpose.
|
||||
nassert_raise("write mode not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ get_frame_rate() const {
|
||||
void EggBackPointer::
|
||||
extend_to(int num_frames) {
|
||||
// Whoops, can't extend this kind of table!
|
||||
nassertv(false);
|
||||
nassert_raise("can't extend this kind of table");
|
||||
}
|
||||
|
||||
/**
|
||||
|
21
tests/pnmimage/test_pnmimage.py
Normal file
21
tests/pnmimage/test_pnmimage.py
Normal file
@ -0,0 +1,21 @@
|
||||
from panda3d.core import PNMImage, PNMImageHeader
|
||||
|
||||
|
||||
def test_pixelspec_ctor():
|
||||
assert tuple(PNMImage.PixelSpec(1)) == (1, 1, 1, 0)
|
||||
assert tuple(PNMImage.PixelSpec(1, 2)) == (1, 1, 1, 2)
|
||||
assert tuple(PNMImage.PixelSpec(1, 2, 3)) == (1, 2, 3, 0)
|
||||
assert tuple(PNMImage.PixelSpec(1, 2, 3, 4)) == (1, 2, 3, 4)
|
||||
|
||||
assert tuple(PNMImage.PixelSpec((1, 2, 3))) == (1, 2, 3, 0)
|
||||
assert tuple(PNMImage.PixelSpec((1, 2, 3), 4)) == (1, 2, 3, 4)
|
||||
|
||||
# Copy constructor
|
||||
spec = PNMImage.PixelSpec(1, 2, 3, 4)
|
||||
assert tuple(PNMImage.PixelSpec(spec)) == (1, 2, 3, 4)
|
||||
|
||||
|
||||
def test_pixelspec_coerce():
|
||||
img = PNMImage(1, 1, 4)
|
||||
img.set_pixel(0, 0, (1, 2, 3, 4))
|
||||
assert img.get_pixel(0, 0) == (1, 2, 3, 4)
|
Loading…
x
Reference in New Issue
Block a user