diff --git a/dtool/src/dtoolbase/deletedBufferChain.I b/dtool/src/dtoolbase/deletedBufferChain.I index 683b5b285e..d9514929c5 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.I +++ b/dtool/src/dtoolbase/deletedBufferChain.I @@ -59,7 +59,7 @@ node_to_buffer(DeletedBufferChain::ObjectNode *node) { #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) // In development mode, we increment the pointer so that the // returned data does not overlap our _flag member. - return (void *)(((char *)node) + get_flag_reserved_bytes()); + return (void *)(((char *)node) + flag_reserved_bytes); #else return (void *)node; #endif // NDEBUG @@ -75,33 +75,8 @@ buffer_to_node(void *ptr) { #if defined(USE_DELETEDCHAINFLAG) && defined(USE_DELETED_CHAIN) // In development mode, we decrement the pointer to undo the // increment we did above. - return (ObjectNode *)(((char *)ptr) - get_flag_reserved_bytes()); + return (ObjectNode *)(((char *)ptr) - flag_reserved_bytes); #else return (ObjectNode *)ptr; #endif // NDEBUG } - -//////////////////////////////////////////////////////////////////// -// Function: DeletedBufferChain::get_flag_reserved_bytes -// Access: Private, Static -// Description: Returns the number of extra bytes reserved at the -// beginning of each buffer for the _flag member. -//////////////////////////////////////////////////////////////////// -INLINE size_t DeletedBufferChain:: -get_flag_reserved_bytes() { -#ifndef USE_DELETEDCHAINFLAG - // Without DELETEDCHAINFLAG, we don't even store the _flag member at - // all, and this method is never called. - static const size_t flag_reserved_bytes = 0; - -#elif defined(LINMATH_ALIGN) - // With SSE2 alignment, we need all 16 bytes to preserve alignment. - static const size_t flag_reserved_bytes = 16; - -#else - // Otherwise, we only need enough space for the Integer itself. - static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer); -#endif // USE_DELETEDCHAINFLAG - - return flag_reserved_bytes; -} diff --git a/dtool/src/dtoolbase/deletedBufferChain.cxx b/dtool/src/dtoolbase/deletedBufferChain.cxx index 33e5672949..d02f10ead0 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.cxx +++ b/dtool/src/dtoolbase/deletedBufferChain.cxx @@ -25,17 +25,10 @@ DeletedBufferChain:: DeletedBufferChain(size_t buffer_size) { _deleted_chain = NULL; _buffer_size = buffer_size; - _alloc_size = _buffer_size; - -#ifdef USE_DELETEDCHAINFLAG - // In development mode, we also need to reserve space for _flag. - _alloc_size += get_flag_reserved_bytes(); -#endif // USE_DELETEDCHAINFLAG // We must allocate at least this much space for bookkeeping // reasons. _buffer_size = max(_buffer_size, sizeof(ObjectNode)); - _alloc_size = max(_alloc_size, sizeof(ObjectNode)); } //////////////////////////////////////////////////////////////////// @@ -51,6 +44,9 @@ allocate(size_t size, TypeHandle type_handle) { //TAU_PROFILE("void *DeletedBufferChain::allocate(size_t, TypeHandle)", " ", TAU_USER); assert(size <= _buffer_size); + // Determine how much space to allocate. + const size_t alloc_size = _buffer_size + flag_reserved_bytes; + ObjectNode *obj; _lock.acquire(); @@ -67,8 +63,8 @@ allocate(size_t size, TypeHandle type_handle) { void *ptr = node_to_buffer(obj); #ifdef DO_MEMORY_USAGE - // type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_inactive, _alloc_size); - type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, _alloc_size); + // type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_inactive, alloc_size); + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); #endif // DO_MEMORY_USAGE return ptr; @@ -78,7 +74,7 @@ allocate(size_t size, TypeHandle type_handle) { // If we get here, the deleted_chain is empty; we have to allocate a // new object from the system pool. - obj = (ObjectNode *)NeverFreeMemory::alloc(_alloc_size); + obj = (ObjectNode *)NeverFreeMemory::alloc(alloc_size); #ifdef USE_DELETEDCHAINFLAG obj->_flag = DCF_alive; @@ -87,7 +83,7 @@ allocate(size_t size, TypeHandle type_handle) { void *ptr = node_to_buffer(obj); #ifdef DO_MEMORY_USAGE - type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, _alloc_size); + type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size); #endif // DO_MEMORY_USAGE return ptr; @@ -110,8 +106,10 @@ deallocate(void *ptr, TypeHandle type_handle) { assert(ptr != (void *)NULL); #ifdef DO_MEMORY_USAGE - type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_active, _alloc_size); - // type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_inactive, _alloc_size); + type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_active, + _buffer_size + flag_reserved_bytes); + // type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_inactive, + // _buffer_size + flag_reserved_bytes); #endif // DO_MEMORY_USAGE diff --git a/dtool/src/dtoolbase/deletedBufferChain.h b/dtool/src/dtoolbase/deletedBufferChain.h index 07825423ed..301ee5d297 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.h +++ b/dtool/src/dtoolbase/deletedBufferChain.h @@ -93,13 +93,24 @@ private: static INLINE void *node_to_buffer(ObjectNode *node); static INLINE ObjectNode *buffer_to_node(void *buffer); - static INLINE size_t get_flag_reserved_bytes(); ObjectNode *_deleted_chain; MutexImpl _lock; size_t _buffer_size; - size_t _alloc_size; + +#ifndef USE_DELETEDCHAINFLAG + // Without DELETEDCHAINFLAG, we don't even store the _flag member at all. + static const size_t flag_reserved_bytes = 0; + +#elif defined(LINMATH_ALIGN) + // With SSE2 alignment, we need all 16 bytes to preserve alignment. + static const size_t flag_reserved_bytes = 16; + +#else + // Otherwise, we only need enough space for the Integer itself. + static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer); +#endif // USE_DELETEDCHAINFLAG friend class MemoryHook; }; diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 807803fc1d..8bf4f4c2f6 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -975,7 +975,12 @@ def CompileCxx(obj,src,opts): if ("BIGOBJ" in opts) or GetTargetArch() == 'x64': cmd += " /bigobj" - cmd += " /Zm300 -D_HAS_EXCEPTIONS=0 /DWIN32_VC /DWIN32" + cmd += " /Zm300 /DWIN32_VC /DWIN32" + if 'EXCEPTIONS' in opts: + cmd += " /EHsc" + else: + cmd += " -D_HAS_EXCEPTIONS=0" + if GetTargetArch() == 'x64': cmd += " /DWIN64_VC /DWIN64" @@ -1139,8 +1144,10 @@ def CompileCxx(obj,src,opts): cmd += " -pthread" if not src.endswith(".c"): - # We don't use exceptions. - if 'EXCEPTIONS' not in opts: + # We don't use exceptions for most modules. + if 'EXCEPTIONS' in opts: + cmd += " -fexceptions" + else: cmd += " -fno-exceptions" if 'RTTI' not in opts: @@ -3646,14 +3653,14 @@ if (not RUNTIME): # if (PkgSkip("VISION") == 0) and (not RUNTIME): - OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG'] + OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS'] TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx') TargetAdd('libp3vision.dll', input='p3vision_composite1.obj') TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3vision.dll', opts=OPTS) - OPTS=['DIR:panda/src/vision', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG'] + OPTS=['DIR:panda/src/vision', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS'] IGATEFILES=GetDirectoryContents('panda/src/vision', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3vision.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3vision.in', opts=['IMOD:panda3d.vision', 'ILIB:libp3vision', 'SRCDIR:panda/src/vision']) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 4aca23a373..1dcdf62a40 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1050,30 +1050,37 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { name = name->append(texname->get_basename()); } } - const GLint p = _glsl_parameter_map[bind._id._seqno]; + GLint p = _glsl_parameter_map[bind._id._seqno]; - if (_glgsg->_data_reader->get_array_info(name, - array_reader, num_values, numeric_type, - start, stride)) { + int num_elements, element_stride; + if (_glgsg->_data_reader->get_array_info(name, array_reader, + num_values, numeric_type, + start, stride, + num_elements, element_stride)) { const unsigned char *client_pointer; if (!_glgsg->setup_array_data(client_pointer, array_reader, force)) { return false; } + client_pointer += start; - _glgsg->_glEnableVertexAttribArray(p); + for (int i = 0; i < num_elements; ++i) { + _glgsg->_glEnableVertexAttribArray(p); -#ifndef OPENGLES - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), - stride, client_pointer + start); - } else -#endif - if (numeric_type == GeomEnums::NT_packed_dabc) { - _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, - GL_TRUE, stride, client_pointer + start); - } else { - _glgsg->_glVertexAttribPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), - GL_TRUE, stride, client_pointer + start); + #ifndef OPENGLES + if (bind._integer) { + _glgsg->_glVertexAttribIPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), + stride, client_pointer); + } else + #endif + if (numeric_type == GeomEnums::NT_packed_dabc) { + _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, + GL_TRUE, stride, client_pointer); + } else { + _glgsg->_glVertexAttribPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), + GL_TRUE, stride, client_pointer); + } + ++p; + client_pointer += element_stride; } } else { _glgsg->_glDisableVertexAttribArray(p); diff --git a/panda/src/gobj/geomEnums.h b/panda/src/gobj/geomEnums.h index ffa4d14515..519bb48d52 100644 --- a/panda/src/gobj/geomEnums.h +++ b/panda/src/gobj/geomEnums.h @@ -202,6 +202,10 @@ PUBLISHED: C_color, // 3- or 4-component color, ordered R, G, B, [A] C_index, // An index value into some other table C_morph_delta, // A delta from some base value, defining a blend shape + + // A transformation matrix. This is typically three or four + // columns, but we pretend it's only one for convenience. + C_matrix, }; // The type of animation data that is represented by a particular diff --git a/panda/src/gobj/geomVertexColumn.I b/panda/src/gobj/geomVertexColumn.I index e74e47d7d2..a92e066c04 100644 --- a/panda/src/gobj/geomVertexColumn.I +++ b/panda/src/gobj/geomVertexColumn.I @@ -116,6 +116,17 @@ get_num_values() const { return _num_values; } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexColumn::get_num_elements +// Access: Published +// Description: Returns the number of times this column is repeated. +// This is usually 1, except for matrices. +//////////////////////////////////////////////////////////////////// +INLINE int GeomVertexColumn:: +get_num_elements() const { + return _num_elements; +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexColumn::get_numeric_type // Access: Published @@ -165,6 +176,18 @@ get_column_alignment() const { return _column_alignment; } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexColumn::get_element_stride +// Access: Published +// Description: This value is only relevant for matrix types. +// Returns the number of bytes to add to access the +// next row of the matrix. +//////////////////////////////////////////////////////////////////// +INLINE int GeomVertexColumn:: +get_element_stride() const { + return _element_stride; +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexColumn::get_component_bytes // Access: Published diff --git a/panda/src/gobj/geomVertexColumn.cxx b/panda/src/gobj/geomVertexColumn.cxx index d629121ffc..1698384d07 100644 --- a/panda/src/gobj/geomVertexColumn.cxx +++ b/panda/src/gobj/geomVertexColumn.cxx @@ -168,6 +168,7 @@ setup() { nassertv(_num_components > 0 && _start >= 0); _num_values = _num_components; + _num_elements = 1; if (_numeric_type == NT_stdfloat) { if (vertices_float64) { @@ -209,6 +210,10 @@ setup() { break; } + if (_contents == C_matrix) { + _num_elements = _num_components; + } + if (_column_alignment < 1) { // The default column alignment is to align to the individual // numeric components, or to vertex_column_alignment, whichever is @@ -219,7 +224,8 @@ setup() { // Enforce the column alignment requirements on the _start byte. _start = ((_start + _column_alignment - 1) / _column_alignment) * _column_alignment; - _total_bytes = _component_bytes * _num_components; + _element_stride = _component_bytes * _num_components; + _total_bytes = _element_stride * _num_elements; if (_packer != NULL) { delete _packer; @@ -334,7 +340,6 @@ make_packer() const { break; } return new Packer_color; - default: // Otherwise, we just read it as a generic value. switch (get_numeric_type()) { diff --git a/panda/src/gobj/geomVertexColumn.h b/panda/src/gobj/geomVertexColumn.h index 88384c4909..fc8bfff031 100644 --- a/panda/src/gobj/geomVertexColumn.h +++ b/panda/src/gobj/geomVertexColumn.h @@ -52,10 +52,12 @@ PUBLISHED: INLINE InternalName *get_name() const; INLINE int get_num_components() const; INLINE int get_num_values() const; + INLINE int get_num_elements() const; INLINE NumericType get_numeric_type() const; INLINE Contents get_contents() const; INLINE int get_start() const; INLINE int get_column_alignment() const; + INLINE int get_element_stride() const; INLINE int get_component_bytes() const; INLINE int get_total_bytes() const; INLINE bool has_homogeneous_coord() const; @@ -96,10 +98,12 @@ private: PT(InternalName) _name; int _num_components; int _num_values; + int _num_elements; NumericType _numeric_type; Contents _contents; int _start; int _column_alignment; + int _element_stride; int _component_bytes; int _total_bytes; Packer *_packer; diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 32b067facf..5d4029834d 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -2358,6 +2358,34 @@ get_array_info(const InternalName *name, return false; } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexDataPipelineReader::get_array_info +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +bool GeomVertexDataPipelineReader:: +get_array_info(const InternalName *name, + const GeomVertexArrayDataHandle *&array_reader, + int &num_values, + GeomVertexDataPipelineReader::NumericType &numeric_type, + int &start, int &stride, + int &num_elements, int &element_stride) const { + nassertr(_got_array_readers, false); + int array_index; + const GeomVertexColumn *column; + if (_cdata->_format->get_array_info(name, array_index, column)) { + array_reader = _array_readers[array_index]; + num_values = column->get_num_values(); + numeric_type = column->get_numeric_type(); + start = column->get_start(); + stride = _cdata->_format->get_array(array_index)->get_stride(); + num_elements = column->get_num_elements(); + element_stride = column->get_element_stride(); + return true; + } + return false; +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexDataPipelineReader::get_vertex_info // Access: Public diff --git a/panda/src/gobj/geomVertexData.h b/panda/src/gobj/geomVertexData.h index ec3ff8ae3e..cab0d62e1c 100644 --- a/panda/src/gobj/geomVertexData.h +++ b/panda/src/gobj/geomVertexData.h @@ -450,6 +450,12 @@ public: int &num_values, NumericType &numeric_type, int &start, int &stride) const; + bool get_array_info(const InternalName *name, + const GeomVertexArrayDataHandle *&array_reader, + int &num_values, NumericType &numeric_type, + int &start, int &stride, + int &num_elements, int &element_stride) const; + INLINE bool has_vertex() const; INLINE bool is_vertex_transformed() const; bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader, diff --git a/panda/src/gobj/geomVertexFormat.h b/panda/src/gobj/geomVertexFormat.h index aad2ae68a3..8efbfdc708 100644 --- a/panda/src/gobj/geomVertexFormat.h +++ b/panda/src/gobj/geomVertexFormat.h @@ -138,10 +138,11 @@ PUBLISHED: INLINE static const GeomVertexFormat *get_v3t2(); INLINE static const GeomVertexFormat *get_v3n3t2(); - // These formats, with the DirectX-style packed color, are not - // supported directly by OpenGL. If you use them, the - // GLGraphicsStateGuardian will automatically convert to OpenGL - // form (with a small runtime overhead). + // These formats, with the DirectX-style packed color, may not be + // supported directly by OpenGL. If you use them and the driver + // does not support them, the GLGraphicsStateGuardian will + // automatically convert to native OpenGL form (with a small + // runtime overhead). INLINE static const GeomVertexFormat *get_v3cp(); INLINE static const GeomVertexFormat *get_v3cpt2(); INLINE static const GeomVertexFormat *get_v3n3cp(); diff --git a/panda/src/gobj/geomVertexReader.I b/panda/src/gobj/geomVertexReader.I index 1c19429d51..0dba5f8108 100644 --- a/panda/src/gobj/geomVertexReader.I +++ b/panda/src/gobj/geomVertexReader.I @@ -524,6 +524,62 @@ get_data4f() { return _packer->get_data4f(inc_pointer()); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix3f +// Access: Published +// Description: Returns the 3-by-3 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix3f GeomVertexReader:: +get_matrix3f() { + nassertr(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() >= 3, + LMatrix3f::ident_mat()); + + size_t col_stride = _packer->_column->get_element_stride(); + const unsigned char *pointer = inc_pointer(); + + LMatrix3f mat; + mat.set_row(0, _packer->get_data3f(pointer)); + pointer += col_stride; + mat.set_row(1, _packer->get_data3f(pointer)); + pointer += col_stride; + mat.set_row(2, _packer->get_data3f(pointer)); + return mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix4f +// Access: Published +// Description: Returns the 4-by-4 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix4f GeomVertexReader:: +get_matrix4f() { + nassertr(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() >= 4, + LMatrix4f::ident_mat()); + + size_t col_stride = _packer->_column->get_element_stride(); + const unsigned char *pointer = inc_pointer(); + + LMatrix4f mat; + mat.set_row(0, _packer->get_data4f(pointer)); + pointer += col_stride; + mat.set_row(1, _packer->get_data4f(pointer)); + pointer += col_stride; + mat.set_row(2, _packer->get_data4f(pointer)); + pointer += col_stride; + mat.set_row(3, _packer->get_data4f(pointer)); + return mat; +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexReader::get_data1d // Access: Published @@ -576,6 +632,62 @@ get_data4d() { return _packer->get_data4d(inc_pointer()); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix3d +// Access: Published +// Description: Returns the 3-by-3 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix3d GeomVertexReader:: +get_matrix3d() { + nassertr(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() >= 3, + LMatrix3d::ident_mat()); + + size_t col_stride = _packer->_column->get_element_stride(); + const unsigned char *pointer = inc_pointer(); + + LMatrix3d mat; + mat.set_row(0, _packer->get_data3d(pointer)); + pointer += col_stride; + mat.set_row(1, _packer->get_data3d(pointer)); + pointer += col_stride; + mat.set_row(2, _packer->get_data3d(pointer)); + return mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix4d +// Access: Published +// Description: Returns the 4-by-4 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix4d GeomVertexReader:: +get_matrix4d() { + nassertr(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() >= 4, + LMatrix4d::ident_mat()); + + size_t col_stride = _packer->_column->get_element_stride(); + const unsigned char *pointer = inc_pointer(); + + LMatrix4d mat; + mat.set_row(0, _packer->get_data4d(pointer)); + pointer += col_stride; + mat.set_row(1, _packer->get_data4d(pointer)); + pointer += col_stride; + mat.set_row(2, _packer->get_data4d(pointer)); + pointer += col_stride; + mat.set_row(3, _packer->get_data4d(pointer)); + return mat; +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexReader::get_data1 // Access: Published @@ -640,6 +752,40 @@ get_data4() { #endif } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix3 +// Access: Published +// Description: Returns the 3-by-3 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix3 GeomVertexReader:: +get_matrix3() { +#ifndef STDFLOAT_DOUBLE + return get_matrix3f(); +#else + return get_matrix3d(); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexReader::get_matrix4 +// Access: Published +// Description: Returns the 4-by-4 matrix associated with the read +// row and advances the read row. This is a special +// method that only works when the column in question +// contains a matrix of an appropriate size. +//////////////////////////////////////////////////////////////////// +INLINE LMatrix4 GeomVertexReader:: +get_matrix4() { +#ifndef STDFLOAT_DOUBLE + return get_matrix4f(); +#else + return get_matrix4d(); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexReader::get_data1i // Access: Published diff --git a/panda/src/gobj/geomVertexReader.h b/panda/src/gobj/geomVertexReader.h index d2f8611dfb..814b2af020 100644 --- a/panda/src/gobj/geomVertexReader.h +++ b/panda/src/gobj/geomVertexReader.h @@ -110,16 +110,22 @@ PUBLISHED: INLINE const LVecBase2f &get_data2f(); INLINE const LVecBase3f &get_data3f(); INLINE const LVecBase4f &get_data4f(); + INLINE LMatrix3f get_matrix3f(); + INLINE LMatrix4f get_matrix4f(); INLINE double get_data1d(); INLINE const LVecBase2d &get_data2d(); INLINE const LVecBase3d &get_data3d(); INLINE const LVecBase4d &get_data4d(); + INLINE LMatrix3d get_matrix3d(); + INLINE LMatrix4d get_matrix4d(); INLINE PN_stdfloat get_data1(); INLINE const LVecBase2 &get_data2(); INLINE const LVecBase3 &get_data3(); INLINE const LVecBase4 &get_data4(); + INLINE LMatrix3 get_matrix3(); + INLINE LMatrix4 get_matrix4(); INLINE int get_data1i(); INLINE const LVecBase2i &get_data2i(); diff --git a/panda/src/gobj/geomVertexWriter.I b/panda/src/gobj/geomVertexWriter.I index 5c63dc46a9..9c33d9c27d 100644 --- a/panda/src/gobj/geomVertexWriter.I +++ b/panda/src/gobj/geomVertexWriter.I @@ -538,6 +538,60 @@ set_data4f(const LVecBase4f &data) { _packer->set_data4f(inc_pointer(), data); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix3f +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix3f(const LMatrix3f &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 3); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_pointer(); + + _packer->set_data3f(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data3f(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data3f(pointer, mat.get_row(2)); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix4f +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix4f(const LMatrix4f &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 4); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_pointer(); + + _packer->set_data4f(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(2)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(3)); +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::set_data1d // Access: Published @@ -640,6 +694,60 @@ set_data4d(const LVecBase4d &data) { _packer->set_data4d(inc_pointer(), data); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix3d +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix3d(const LMatrix3d &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 3); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_pointer(); + + _packer->set_data3d(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data3d(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data3d(pointer, mat.get_row(2)); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix4d +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix4d(const LMatrix4d &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 4); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_pointer(); + + _packer->set_data4d(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(2)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(3)); +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::set_data1 // Access: Published @@ -766,6 +874,44 @@ set_data4(const LVecBase4 &data) { #endif } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix3 +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix3(const LMatrix3 &mat) { +#ifndef STDFLOAT_DOUBLE + set_matrix3f(mat); +#else + set_matrix3d(mat); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::set_matrix4 +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// It is an error for the write row to advance past +// the end of data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +set_matrix4(const LMatrix4 &mat) { +#ifndef STDFLOAT_DOUBLE + set_matrix4f(mat); +#else + set_matrix4d(mat); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::set_data1i // Access: Published @@ -1012,6 +1158,60 @@ add_data4f(const LVecBase4f &data) { _packer->set_data4f(inc_add_pointer(), data); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix3f +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix3f(const LMatrix3f &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 3); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_add_pointer(); + + _packer->set_data3f(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data3f(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data3f(pointer, mat.get_row(2)); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix4f +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix4f(const LMatrix4f &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 4); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_add_pointer(); + + _packer->set_data4f(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(2)); + pointer += col_stride; + _packer->set_data4f(pointer, mat.get_row(3)); +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::add_data1d // Access: Published @@ -1114,6 +1314,60 @@ add_data4d(const LVecBase4d &data) { _packer->set_data4d(inc_add_pointer(), data); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix3d +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix3d(const LMatrix3d &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 3); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_add_pointer(); + + _packer->set_data3d(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data3d(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data3d(pointer, mat.get_row(2)); +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix4d +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix4d(const LMatrix4d &mat) { + nassertv(has_column() && + _packer->_column->get_contents() == C_matrix && + _packer->_column->get_num_elements() == 4); + + size_t col_stride = _packer->_column->get_element_stride(); + unsigned char *pointer = inc_add_pointer(); + + _packer->set_data4d(pointer, mat.get_row(0)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(1)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(2)); + pointer += col_stride; + _packer->set_data4d(pointer, mat.get_row(3)); +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::add_data1 // Access: Published @@ -1240,6 +1494,44 @@ add_data4(const LVecBase4 &data) { #endif } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix3 +// Access: Published +// Description: Sets the write row to a 3-by-3 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix3(const LMatrix3 &mat) { +#ifndef STDFLOAT_DOUBLE + add_matrix3f(mat); +#else + add_matrix3d(mat); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexWriter::add_matrix4 +// Access: Published +// Description: Sets the write row to a 4-by-4 matrix, and advances +// the write row. This is a special method that can +// only be used on matrix columns. +// +// If the write row advances past the end of data, +// implicitly adds a new row to the data. +//////////////////////////////////////////////////////////////////// +INLINE void GeomVertexWriter:: +add_matrix4(const LMatrix4 &mat) { +#ifndef STDFLOAT_DOUBLE + add_matrix4f(mat); +#else + add_matrix4d(mat); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexWriter::add_data1i // Access: Published diff --git a/panda/src/gobj/geomVertexWriter.h b/panda/src/gobj/geomVertexWriter.h index 2109353757..e29cfb149c 100644 --- a/panda/src/gobj/geomVertexWriter.h +++ b/panda/src/gobj/geomVertexWriter.h @@ -123,6 +123,8 @@ PUBLISHED: INLINE void set_data3f(const LVecBase3f &data); INLINE void set_data4f(float x, float y, float z, float w); INLINE void set_data4f(const LVecBase4f &data); + INLINE void set_matrix3f(const LMatrix3f &mat); + INLINE void set_matrix4f(const LMatrix4f &mat); INLINE void set_data1d(double data); INLINE void set_data2d(double x, double y); @@ -131,6 +133,8 @@ PUBLISHED: INLINE void set_data3d(const LVecBase3d &data); INLINE void set_data4d(double x, double y, double z, double w); INLINE void set_data4d(const LVecBase4d &data); + INLINE void set_matrix3d(const LMatrix3d &mat); + INLINE void set_matrix4d(const LMatrix4d &mat); INLINE void set_data1(PN_stdfloat data); INLINE void set_data2(PN_stdfloat x, PN_stdfloat y); @@ -139,6 +143,8 @@ PUBLISHED: INLINE void set_data3(const LVecBase3 &data); INLINE void set_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w); INLINE void set_data4(const LVecBase4 &data); + INLINE void set_matrix3(const LMatrix3 &mat); + INLINE void set_matrix4(const LMatrix4 &mat); INLINE void set_data1i(int data); INLINE void set_data2i(int a, int b); @@ -158,6 +164,8 @@ PUBLISHED: INLINE void add_data3f(const LVecBase3f &data); INLINE void add_data4f(float x, float y, float z, float w); INLINE void add_data4f(const LVecBase4f &data); + INLINE void add_matrix3f(const LMatrix3f &mat); + INLINE void add_matrix4f(const LMatrix4f &mat); INLINE void add_data1d(double data); INLINE void add_data2d(double x, double y); @@ -166,6 +174,8 @@ PUBLISHED: INLINE void add_data3d(const LVecBase3d &data); INLINE void add_data4d(double x, double y, double z, double w); INLINE void add_data4d(const LVecBase4d &data); + INLINE void add_matrix3d(const LMatrix3d &mat); + INLINE void add_matrix4d(const LMatrix4d &mat); INLINE void add_data1(PN_stdfloat data); INLINE void add_data2(PN_stdfloat x, PN_stdfloat y); @@ -174,6 +184,8 @@ PUBLISHED: INLINE void add_data3(const LVecBase3 &data); INLINE void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w); INLINE void add_data4(const LVecBase4 &data); + INLINE void add_matrix3(const LMatrix3 &mat); + INLINE void add_matrix4(const LMatrix4 &mat); INLINE void add_data1i(int data); INLINE void add_data2i(int a, int b); diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index cc498a9772..99d4c9629e 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -752,8 +752,8 @@ handle_reshape() { // _props origin should reflect upper left of view rectangle properties.set_origin(view_rect.left, view_rect.top); - if (windisplay_cat.is_spam()) { - windisplay_cat.spam() + if (windisplay_cat.is_debug()) { + windisplay_cat.debug() << "reshape to origin: (" << properties.get_x_origin() << "," << properties.get_y_origin() << "), size: (" << properties.get_x_size() << "," << properties.get_y_size() << ")\n"; @@ -1488,7 +1488,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { } // Resist calling handle_reshape before the window has opened. - if (_hWnd == NULL) { + if (_hWnd != NULL) { handle_reshape(); } break;