mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Merge branch 'master' of https://github.com/panda3d/panda3d
This commit is contained in:
commit
1d1ee63b8e
@ -203,6 +203,11 @@ def processType(handle, type):
|
||||
if docstring:
|
||||
print >>handle, docstring
|
||||
print >>handle, interrogate_type_enum_value_name(type, i_value), "=", interrogate_type_enum_value(type, i_value), ","
|
||||
|
||||
elif interrogate_type_is_typedef(type):
|
||||
wrapped_type = translated_type_name(interrogate_type_wrapped_type(type))
|
||||
print >>handle, "typedef %s %s;" % (wrapped_type, typename)
|
||||
return
|
||||
else:
|
||||
if interrogate_type_is_struct(type):
|
||||
classtype = "struct"
|
||||
@ -211,7 +216,7 @@ def processType(handle, type):
|
||||
elif interrogate_type_is_union(type):
|
||||
classtype = "union"
|
||||
else:
|
||||
print "I don't know what type %s is" % typename
|
||||
print "I don't know what type %s is" % interrogate_type_true_name(type)
|
||||
return
|
||||
|
||||
if len(derivations) > 0:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2636,7 +2636,7 @@ write_module_class(ostream &out, Object *obj) {
|
||||
write_function_slot(out, 2, slots, "bf_getsegcount");
|
||||
write_function_slot(out, 2, slots, "bf_getcharbuffer");
|
||||
out << "#endif\n";
|
||||
out << "#if PY_MAJOR_VERSION >= 0x02060000\n";
|
||||
out << "#if PY_VERSION_HEX >= 0x02060000\n";
|
||||
write_function_slot(out, 2, slots, "bf_getbuffer");
|
||||
write_function_slot(out, 2, slots, "bf_releasebuffer");
|
||||
out << "#endif\n";
|
||||
|
@ -167,13 +167,16 @@ output(ostream &out) const {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletBodyNode::
|
||||
add_shape(BulletShape *shape, const TransformState *ts) {
|
||||
add_shape(BulletShape *bullet_shape, const TransformState *ts) {
|
||||
|
||||
nassertv(get_object());
|
||||
nassertv(ts);
|
||||
|
||||
nassertv(!(shape->ptr()->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE
|
||||
&& ((btConvexHullShape *)shape->ptr())->getNumVertices() == 0));
|
||||
btCollisionShape *shape = bullet_shape->ptr();
|
||||
nassertv(shape != NULL);
|
||||
|
||||
nassertv(!(shape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE &&
|
||||
((btConvexHullShape *)shape)->getNumVertices() == 0));
|
||||
|
||||
// Transform
|
||||
btTransform trans = TransformState_to_btTrans(ts);
|
||||
@ -195,13 +198,13 @@ add_shape(BulletShape *shape, const TransformState *ts) {
|
||||
// After adding the shape we will have one shape, but with transform.
|
||||
// We need to wrap the shape within a compound shape, in oder to
|
||||
// be able to set the local transform.
|
||||
next = shape->ptr();
|
||||
next = shape;
|
||||
}
|
||||
else {
|
||||
// After adding the shape we will have a total of one shape, without
|
||||
// local transform. We can set the shape directly.
|
||||
next = new btCompoundShape();
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape->ptr());
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape);
|
||||
}
|
||||
|
||||
get_object()->setCollisionShape(next);
|
||||
@ -216,7 +219,7 @@ add_shape(BulletShape *shape, const TransformState *ts) {
|
||||
// to the compound shape.
|
||||
next = previous;
|
||||
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape->ptr());
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape);
|
||||
}
|
||||
else {
|
||||
// We have one shape which is NOT a compound shape, and want to add
|
||||
@ -225,7 +228,7 @@ add_shape(BulletShape *shape, const TransformState *ts) {
|
||||
|
||||
btTransform previous_trans = btTransform::getIdentity();
|
||||
((btCompoundShape *)next)->addChildShape(previous_trans, previous);
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape->ptr());
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape);
|
||||
|
||||
get_object()->setCollisionShape(next);
|
||||
_shape = next;
|
||||
@ -238,10 +241,10 @@ add_shape(BulletShape *shape, const TransformState *ts) {
|
||||
nassertv(previous->getShapeType() == COMPOUND_SHAPE_PROXYTYPE);
|
||||
|
||||
next = previous;
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape->ptr());
|
||||
((btCompoundShape *)next)->addChildShape(trans, shape);
|
||||
}
|
||||
|
||||
_shapes.push_back(shape);
|
||||
_shapes.push_back(bullet_shape);
|
||||
|
||||
// Restore the local scaling again
|
||||
np.set_scale(scale);
|
||||
@ -778,7 +781,7 @@ int BulletBodyNode::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = PandaNode::complete_pointers(p_list, manager);
|
||||
|
||||
BulletShape *shape = DCAST(BulletShape, p_list[pi++]);
|
||||
PT(BulletShape) shape = DCAST(BulletShape, p_list[pi++]);
|
||||
|
||||
while (shape != (BulletShape *)NULL) {
|
||||
const TransformState *trans = DCAST(TransformState, p_list[pi++]);
|
||||
@ -790,6 +793,22 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletBodyNode::require_fully_complete
|
||||
// Access: Public, Virtual
|
||||
// Description: Some objects require all of their nested pointers to
|
||||
// have been completed before the objects themselves can
|
||||
// be completed. If this is the case, override this
|
||||
// method to return true, and be careful with circular
|
||||
// references (which would make the object unreadable
|
||||
// from a bam file).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BulletBodyNode::
|
||||
require_fully_complete() const {
|
||||
// We require the shape pointers to be complete before we add them.
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletBodyNode::fillin
|
||||
// Access: Protected
|
||||
|
@ -148,6 +148,7 @@ public:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
virtual bool require_fully_complete() const;
|
||||
|
||||
protected:
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
@ -66,10 +66,17 @@ add_array(const PTA_LVecBase3 &points) {
|
||||
_shape->setUserPointer(this);
|
||||
|
||||
PTA_LVecBase3::const_iterator it;
|
||||
for (it=points.begin(); it!=points.end(); it++) {
|
||||
LVecBase3 v = *it;
|
||||
_shape->addPoint(LVecBase3_to_btVector3(v));
|
||||
|
||||
#if BT_BULLET_VERSION >= 282
|
||||
for (it = points.begin(); it != points.end(); ++it) {
|
||||
_shape->addPoint(LVecBase3_to_btVector3(*it), false);
|
||||
}
|
||||
_shape->recalcLocalAabb();
|
||||
#else
|
||||
for (it = points.begin(); it != points.end(); ++it) {
|
||||
_shape->addPoint(LVecBase3_to_btVector3(*it));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -100,8 +107,97 @@ add_geom(const Geom *geom, const TransformState *ts) {
|
||||
_shape->setUserPointer(this);
|
||||
|
||||
pvector<LPoint3>::const_iterator it;
|
||||
for (it=points.begin(); it!=points.end(); it++) {
|
||||
|
||||
#if BT_BULLET_VERSION >= 282
|
||||
for (it = points.begin(); it != points.end(); ++it) {
|
||||
LVecBase3 v = *it;
|
||||
_shape->addPoint(LVecBase3_to_btVector3(*it), false);
|
||||
}
|
||||
_shape->recalcLocalAabb();
|
||||
#else
|
||||
for (it = points.begin(); it != points.end(); ++it) {
|
||||
LVecBase3 v = *it;
|
||||
_shape->addPoint(LVecBase3_to_btVector3(*it));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletConvexHullShape::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// BulletShape.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletConvexHullShape::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletConvexHullShape::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletConvexHullShape::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
dg.add_stdfloat(get_margin());
|
||||
|
||||
unsigned int num_points = _shape->getNumPoints();
|
||||
dg.add_uint32(num_points);
|
||||
|
||||
const btVector3 *points = _shape->getUnscaledPoints();
|
||||
|
||||
for (unsigned int i = 0; i < num_points; ++i) {
|
||||
LVecBase3 point = btVector3_to_LVecBase3(points[i]);
|
||||
point.write_datagram(dg);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletConvexHullShape::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type BulletShape is encountered
|
||||
// in the Bam file. It should create the BulletShape
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *BulletConvexHullShape::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
BulletConvexHullShape *param = new BulletConvexHullShape;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
param->fillin(scan, manager);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletConvexHullShape::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new BulletShape.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletConvexHullShape::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PN_stdfloat margin = scan.get_stdfloat();
|
||||
unsigned int num_points = scan.get_uint32();
|
||||
|
||||
#if BT_BULLET_VERSION >= 282
|
||||
for (unsigned int i = 0; i < num_points; ++i) {
|
||||
LVecBase3 point;
|
||||
point.read_datagram(scan);
|
||||
_shape->addPoint(LVecBase3_to_btVector3(point), false);
|
||||
}
|
||||
_shape->recalcLocalAabb();
|
||||
#else
|
||||
for (unsigned int i = 0; i < num_points; ++i) {
|
||||
LVecBase3 point;
|
||||
point.read_datagram(scan);
|
||||
_shape->addPoint(LVecBase3_to_btVector3(point));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDABULLET BulletConvexHullShape : public BulletShape {
|
||||
|
||||
PUBLISHED:
|
||||
BulletConvexHullShape();
|
||||
INLINE BulletConvexHullShape(const BulletConvexHullShape ©);
|
||||
@ -47,7 +46,14 @@ public:
|
||||
private:
|
||||
btConvexHullShape *_shape;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -463,3 +463,70 @@ drawSphere(btScalar radius, const btTransform &transform, const btVector3 &color
|
||||
drawArc(center, zoffs, xoffs, radius, radius, 0, SIMD_2_PI, color, false, 10.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletDebugNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// BulletDebugNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletDebugNode::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletDebugNode::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletDebugNode::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
// Don't upcall to GeomNode since we're not interested in storing
|
||||
// the actual debug Geoms in the .bam file.
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
|
||||
dg.add_bool(_wireframe);
|
||||
dg.add_bool(_constraints);
|
||||
dg.add_bool(_bounds);
|
||||
dg.add_bool(_drawer._normals);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletDebugNode::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of this type is encountered
|
||||
// in the Bam file. It should create the rigid body
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *BulletDebugNode::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
BulletDebugNode *param = new BulletDebugNode;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
param->fillin(scan, manager);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletDebugNode::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new BulletDebugNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletDebugNode::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
// Don't upcall to GeomNode since we're not interested in storing
|
||||
// the actual debug Geoms in the .bam file.
|
||||
PandaNode::fillin(scan, manager);
|
||||
|
||||
_wireframe = scan.get_bool();
|
||||
_constraints = scan.get_bool();
|
||||
_bounds = scan.get_bool();
|
||||
_drawer._normals = scan.get_bool();
|
||||
}
|
||||
|
@ -101,7 +101,14 @@ private:
|
||||
|
||||
friend class BulletWorld;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -213,3 +213,125 @@ write(ostream &out, int indent_level) const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMesh::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// BulletTriangleMesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMesh::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMesh::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMesh::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
dg.add_stdfloat(get_welding_distance());
|
||||
|
||||
// In case we ever want to represent more than 1 indexed mesh.
|
||||
dg.add_int32(1);
|
||||
|
||||
btIndexedMesh &mesh = _mesh->getIndexedMeshArray()[0];
|
||||
dg.add_int32(mesh.m_numVertices);
|
||||
dg.add_int32(mesh.m_numTriangles);
|
||||
|
||||
// In case we want to use this to distinguish 16-bit vs 32-bit indices.
|
||||
dg.add_bool(true);
|
||||
|
||||
// Add the vertices.
|
||||
const unsigned char *vptr = mesh.m_vertexBase;
|
||||
nassertv(vptr != NULL || mesh.m_numVertices == 0);
|
||||
|
||||
for (int i = 0; i < mesh.m_numVertices; ++i) {
|
||||
const btVector3 &vertex = *((btVector3 *)vptr);
|
||||
dg.add_stdfloat(vertex.getX());
|
||||
dg.add_stdfloat(vertex.getY());
|
||||
dg.add_stdfloat(vertex.getZ());
|
||||
vptr += mesh.m_vertexStride;
|
||||
}
|
||||
|
||||
// Now add the triangle indices.
|
||||
const unsigned char *iptr = mesh.m_triangleIndexBase;
|
||||
nassertv(iptr != NULL || mesh.m_numTriangles == 0);
|
||||
|
||||
if (_mesh->getUse32bitIndices()) {
|
||||
for (int i = 0; i < mesh.m_numTriangles; ++i) {
|
||||
int *triangle = (int *)iptr;
|
||||
dg.add_int32(triangle[0]);
|
||||
dg.add_int32(triangle[1]);
|
||||
dg.add_int32(triangle[2]);
|
||||
iptr += mesh.m_triangleIndexStride;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < mesh.m_numTriangles; ++i) {
|
||||
short int *triangle = (short int *)iptr;
|
||||
dg.add_int32(triangle[0]);
|
||||
dg.add_int32(triangle[1]);
|
||||
dg.add_int32(triangle[2]);
|
||||
iptr += mesh.m_triangleIndexStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMesh::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type BulletShape is encountered
|
||||
// in the Bam file. It should create the BulletShape
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *BulletTriangleMesh::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
BulletTriangleMesh *param = new BulletTriangleMesh;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
param->fillin(scan, manager);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMesh::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new BulletTriangleMesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMesh::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
set_welding_distance(scan.get_stdfloat());
|
||||
|
||||
nassertv(scan.get_int32() == 1);
|
||||
int num_vertices = scan.get_int32();
|
||||
int num_triangles = scan.get_int32();
|
||||
nassertv(scan.get_bool() == true);
|
||||
|
||||
// Read and add the vertices.
|
||||
_mesh->preallocateVertices(num_vertices);
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
PN_stdfloat x = scan.get_stdfloat();
|
||||
PN_stdfloat y = scan.get_stdfloat();
|
||||
PN_stdfloat z = scan.get_stdfloat();
|
||||
_mesh->findOrAddVertex(btVector3(x, y, z), false);
|
||||
}
|
||||
|
||||
// Now read and add the indices.
|
||||
int num_indices = num_triangles * 3;
|
||||
_mesh->preallocateIndices(num_indices);
|
||||
for (int i = 0; i < num_indices; ++i) {
|
||||
_mesh->addIndex(scan.get_int32());
|
||||
}
|
||||
|
||||
// Since we manually added the vertices individually, we have to
|
||||
// update the triangle count appropriately.
|
||||
_mesh->getIndexedMeshArray()[0].m_numTriangles = num_triangles;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "bullet_includes.h"
|
||||
#include "bullet_utils.h"
|
||||
|
||||
#include "typedReferenceCount.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "nodePath.h"
|
||||
#include "luse.h"
|
||||
#include "geom.h"
|
||||
@ -31,7 +31,7 @@
|
||||
// Class : BulletTriangleMesh
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDABULLET BulletTriangleMesh : public TypedReferenceCount {
|
||||
class EXPCL_PANDABULLET BulletTriangleMesh : public TypedWritableReferenceCount {
|
||||
|
||||
PUBLISHED:
|
||||
BulletTriangleMesh();
|
||||
@ -63,15 +63,22 @@ public:
|
||||
private:
|
||||
btTriangleMesh *_mesh;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
TypedWritableReferenceCount::init_type();
|
||||
register_type(_type_handle, "BulletTriangleMesh",
|
||||
TypedReferenceCount::get_class_type());
|
||||
TypedWritableReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
@ -21,6 +21,21 @@
|
||||
|
||||
TypeHandle BulletTriangleMeshShape::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::Constructor
|
||||
// Access: Private
|
||||
// Description: Only used by make_from_bam.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletTriangleMeshShape::
|
||||
BulletTriangleMeshShape() :
|
||||
_mesh(NULL),
|
||||
_gimpact_shape(NULL),
|
||||
_bvh_shape(NULL),
|
||||
_dynamic(false),
|
||||
_compress(false),
|
||||
_bvh(false) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::Constructor
|
||||
// Access: Published
|
||||
@ -28,7 +43,10 @@ TypeHandle BulletTriangleMeshShape::_type_handle;
|
||||
// if 'dynamic' is set to FALSE.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletTriangleMeshShape::
|
||||
BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, bool bvh) {
|
||||
BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, bool bvh) :
|
||||
_dynamic(dynamic),
|
||||
_compress(compress),
|
||||
_bvh(bvh) {
|
||||
|
||||
// Assert that mesh is not NULL
|
||||
if (!mesh) {
|
||||
@ -101,3 +119,100 @@ refit_tree(const LPoint3 &aabb_min, const LPoint3 &aabb_max) {
|
||||
LVecBase3_to_btVector3(aabb_max));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// BulletTriangleMeshShape.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMeshShape::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMeshShape::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
dg.add_stdfloat(get_margin());
|
||||
|
||||
manager->write_pointer(dg, _mesh);
|
||||
|
||||
dg.add_bool(_dynamic);
|
||||
if (!_dynamic) {
|
||||
dg.add_bool(_compress);
|
||||
dg.add_bool(_bvh);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BulletTriangleMeshShape::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = BulletShape::complete_pointers(p_list, manager);
|
||||
|
||||
_mesh = DCAST(BulletTriangleMesh, p_list[pi++]);
|
||||
|
||||
btTriangleMesh *mesh_ptr = _mesh->ptr();
|
||||
nassertr(mesh_ptr != NULL, pi);
|
||||
|
||||
if (_dynamic) {
|
||||
_gimpact_shape = new btGImpactMeshShape(mesh_ptr);
|
||||
_gimpact_shape->updateBound();
|
||||
_gimpact_shape->setUserPointer(this);
|
||||
} else {
|
||||
_bvh_shape = new btBvhTriangleMeshShape(mesh_ptr, _compress, _bvh);
|
||||
_bvh_shape->setUserPointer(this);
|
||||
}
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type BulletShape is encountered
|
||||
// in the Bam file. It should create the BulletShape
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *BulletTriangleMeshShape::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
BulletTriangleMeshShape *param = new BulletTriangleMeshShape;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
param->fillin(scan, manager);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletTriangleMeshShape::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new BulletTriangleMeshShape.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletTriangleMeshShape::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PN_stdfloat margin = scan.get_stdfloat();
|
||||
|
||||
manager->read_pointer(scan);
|
||||
|
||||
_dynamic = scan.get_bool();
|
||||
if (!_dynamic) {
|
||||
_compress = scan.get_bool();
|
||||
_bvh = scan.get_bool();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ class BulletTriangleMesh;
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDABULLET BulletTriangleMeshShape : public BulletShape {
|
||||
private:
|
||||
INLINE BulletTriangleMeshShape();
|
||||
|
||||
PUBLISHED:
|
||||
BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress=true, bool bvh=true);
|
||||
@ -50,7 +52,20 @@ private:
|
||||
|
||||
PT(BulletTriangleMesh) _mesh;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool _dynamic : 1;
|
||||
bool _compress : 1;
|
||||
bool _bvh : 1;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -184,9 +184,13 @@ init_libbullet() {
|
||||
|
||||
// Register factory functions for constructing objects from .bam files
|
||||
BulletBoxShape::register_with_read_factory();
|
||||
BulletConvexHullShape::register_with_read_factory();
|
||||
BulletDebugNode::register_with_read_factory();
|
||||
BulletPlaneShape::register_with_read_factory();
|
||||
BulletRigidBodyNode::register_with_read_factory();
|
||||
BulletSphereShape::register_with_read_factory();
|
||||
BulletTriangleMesh::register_with_read_factory();
|
||||
BulletTriangleMeshShape::register_with_read_factory();
|
||||
|
||||
// Custom contact callbacks
|
||||
gContactAddedCallback = contact_added_callback;
|
||||
|
@ -397,6 +397,22 @@ get_max_cube_map_dimension() const {
|
||||
return _max_cube_map_dimension;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_buffer_texture_size
|
||||
// Access: Published
|
||||
// Description: Returns the largest possible buffer texture size,
|
||||
// or -1 if there is no particular limit. Returns 0
|
||||
// if cube map textures are not supported.
|
||||
//
|
||||
// The value returned may not be meaningful until after
|
||||
// the graphics context has been fully created (e.g. the
|
||||
// window has been opened).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GraphicsStateGuardian::
|
||||
get_max_buffer_texture_size() const {
|
||||
return _max_buffer_texture_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_texture_combine
|
||||
// Access: Published
|
||||
@ -469,6 +485,16 @@ get_supports_cube_map() const {
|
||||
return _supports_cube_map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_buffer_texture
|
||||
// Access: Published
|
||||
// Description: Returns true if this GSG can render buffer textures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_buffer_texture() const {
|
||||
return _supports_buffer_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supports_tex_non_pow2
|
||||
// Access: Published
|
||||
|
@ -185,6 +185,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
_max_3d_texture_dimension = 0;
|
||||
_max_2d_texture_array_layers = 0;
|
||||
_max_cube_map_dimension = 0;
|
||||
_max_buffer_texture_size = 0;
|
||||
|
||||
// Assume we don't support these fairly advanced texture combiner
|
||||
// modes.
|
||||
@ -195,6 +196,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
||||
_supports_3d_texture = false;
|
||||
_supports_2d_texture_array = false;
|
||||
_supports_cube_map = false;
|
||||
_supports_buffer_texture = false;
|
||||
_supports_tex_non_pow2 = false;
|
||||
_supports_texture_srgb = false;
|
||||
_supports_compressed_texture = false;
|
||||
|
@ -121,6 +121,7 @@ PUBLISHED:
|
||||
INLINE int get_max_3d_texture_dimension() const;
|
||||
INLINE int get_max_2d_texture_array_layers() const; //z axis
|
||||
INLINE int get_max_cube_map_dimension() const;
|
||||
INLINE int get_max_buffer_texture_size() const;
|
||||
|
||||
INLINE bool get_supports_texture_combine() const;
|
||||
INLINE bool get_supports_texture_saved_result() const;
|
||||
@ -129,6 +130,7 @@ PUBLISHED:
|
||||
INLINE bool get_supports_3d_texture() const;
|
||||
INLINE bool get_supports_2d_texture_array() const;
|
||||
INLINE bool get_supports_cube_map() const;
|
||||
INLINE bool get_supports_buffer_texture() const;
|
||||
INLINE bool get_supports_tex_non_pow2() const;
|
||||
INLINE bool get_supports_texture_srgb() const;
|
||||
|
||||
@ -476,6 +478,7 @@ protected:
|
||||
int _max_3d_texture_dimension;
|
||||
int _max_2d_texture_array_layers; //on the z axis
|
||||
int _max_cube_map_dimension;
|
||||
int _max_buffer_texture_size;
|
||||
|
||||
bool _supports_texture_combine;
|
||||
bool _supports_texture_saved_result;
|
||||
@ -484,6 +487,7 @@ protected:
|
||||
bool _supports_3d_texture;
|
||||
bool _supports_2d_texture_array;
|
||||
bool _supports_cube_map;
|
||||
bool _supports_buffer_texture;
|
||||
bool _supports_tex_non_pow2;
|
||||
bool _supports_texture_srgb;
|
||||
|
||||
|
@ -854,6 +854,17 @@ reset() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (is_at_least_gl_version(3, 0)) {
|
||||
_glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer");
|
||||
_supports_buffer_texture = true;
|
||||
|
||||
} else if (has_extension("GL_ARB_texture_buffer_object")) {
|
||||
_glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB");
|
||||
_supports_buffer_texture = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
_supports_texture_srgb = false;
|
||||
if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
|
||||
_supports_texture_srgb = true;
|
||||
@ -1941,6 +1952,7 @@ reset() {
|
||||
GLint max_3d_texture_size = 0;
|
||||
GLint max_2d_texture_array_layers = 0;
|
||||
GLint max_cube_map_size = 0;
|
||||
GLint max_buffer_texture_size = 0;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
_max_texture_dimension = max_texture_size;
|
||||
@ -1966,6 +1978,15 @@ reset() {
|
||||
_max_cube_map_dimension = 0;
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_supports_buffer_texture) {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_buffer_texture_size);
|
||||
_max_buffer_texture_size = max_buffer_texture_size;
|
||||
} else {
|
||||
_max_buffer_texture_size = 0;
|
||||
}
|
||||
#endif // !OPENGLES
|
||||
|
||||
GLint max_elements_vertices = 0, max_elements_indices = 0;
|
||||
#ifndef OPENGLES
|
||||
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
|
||||
@ -4510,6 +4531,15 @@ prepare_texture(Texture *tex, int view) {
|
||||
<< "Cube map textures are not supported by this OpenGL driver.\n";
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::TT_buffer_texture:
|
||||
if (!_supports_buffer_texture) {
|
||||
GLCAT.warning()
|
||||
<< "Buffer textures are not supported by this OpenGL driver.\n";
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -7362,27 +7392,35 @@ get_texture_target(Texture::TextureType texture_type) const {
|
||||
return GL_TEXTURE_2D;
|
||||
|
||||
case Texture::TT_3d_texture:
|
||||
if (_supports_3d_texture) {
|
||||
#ifndef OPENGLES_1
|
||||
if (_supports_3d_texture) {
|
||||
return GL_TEXTURE_3D;
|
||||
#endif
|
||||
} else {
|
||||
return GL_NONE;
|
||||
}
|
||||
#endif
|
||||
return GL_NONE;
|
||||
|
||||
case Texture::TT_2d_texture_array:
|
||||
if (_supports_2d_texture_array) {
|
||||
#ifndef OPENGLES
|
||||
if (_supports_2d_texture_array) {
|
||||
return GL_TEXTURE_2D_ARRAY_EXT;
|
||||
#endif
|
||||
} else {
|
||||
return GL_NONE;
|
||||
}
|
||||
#endif
|
||||
return GL_NONE;
|
||||
|
||||
case Texture::TT_cube_map:
|
||||
if (_supports_cube_map) {
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
} else {
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
case Texture::TT_buffer_texture:
|
||||
#ifndef OPENGLES
|
||||
if (_supports_buffer_texture) {
|
||||
return GL_TEXTURE_BUFFER;
|
||||
}
|
||||
#endif
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
GLCAT.error() << "Invalid Texture::TextureType value!\n";
|
||||
@ -10252,6 +10290,12 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
|
||||
// Unsupported target (e.g. 3-d texturing on GL 1.1).
|
||||
return false;
|
||||
}
|
||||
#ifndef OPENGLES
|
||||
if (target == GL_TEXTURE_BUFFER) {
|
||||
// Buffer textures may not receive texture parameters.
|
||||
return false;
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
// Record the active sampler settings.
|
||||
gtc->_active_sampler = sampler;
|
||||
@ -10505,7 +10549,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
|
||||
// If we'll use immutable texture storage, we have to pick a sized
|
||||
// image format.
|
||||
bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage);
|
||||
bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) ||
|
||||
(tex->get_texture_type() == Texture::TT_buffer_texture);
|
||||
|
||||
GLint internal_format = get_internal_image_format(tex, force_sized);
|
||||
GLint external_format = get_external_image_format(tex);
|
||||
@ -10553,6 +10598,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
max_dimension_z = _max_2d_texture_array_layers;
|
||||
break;
|
||||
|
||||
case Texture::TT_buffer_texture:
|
||||
max_dimension_x = _max_buffer_texture_size;
|
||||
max_dimension_y = 1;
|
||||
max_dimension_z = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
max_dimension_x = _max_texture_dimension;
|
||||
max_dimension_y = _max_texture_dimension;
|
||||
@ -10631,6 +10682,13 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
|
||||
GLenum target = get_texture_target(tex->get_texture_type());
|
||||
uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
|
||||
#ifndef OPENGLES
|
||||
if (target == GL_TEXTURE_BUFFER) {
|
||||
// Buffer textures may not have mipmaps.
|
||||
uses_mipmaps = false;
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
bool needs_reload = false;
|
||||
if (!gtc->_has_storage ||
|
||||
gtc->_uses_mipmaps != uses_mipmaps ||
|
||||
@ -10640,6 +10698,12 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
gtc->_depth != depth) {
|
||||
// We need to reload a new GL Texture object.
|
||||
needs_reload = true;
|
||||
|
||||
if (_use_object_labels) {
|
||||
// This seems like a good time to assign a label for the debug messages.
|
||||
const string &name = tex->get_name();
|
||||
_glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_reload && gtc->_immutable) {
|
||||
@ -10648,13 +10712,26 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
glBindTexture(target, gtc->_index);
|
||||
}
|
||||
|
||||
if (needs_reload) {
|
||||
if (_use_object_labels) {
|
||||
// This seems like a good time to assign a label for the debug messages.
|
||||
const string &name = tex->get_name();
|
||||
_glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
|
||||
}
|
||||
#ifndef OPENGLES
|
||||
if (target == GL_TEXTURE_BUFFER) {
|
||||
// Buffer textures don't support mipmappping.
|
||||
gtc->_generate_mipmaps = false;
|
||||
|
||||
if (gtc->_buffer == 0) {
|
||||
// The buffer object wasn't created yet.
|
||||
_glGenBuffers(1, >c->_buffer);
|
||||
_glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
|
||||
_glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
|
||||
needs_reload = true;
|
||||
} else {
|
||||
_glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
|
||||
if (gtc->_internal_format != internal_format) {
|
||||
_glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif // !OPENGLES
|
||||
if (needs_reload) {
|
||||
// Figure out whether mipmaps will be generated by the GPU or by
|
||||
// Panda (or not at all), and how many mipmap levels should be created.
|
||||
gtc->_generate_mipmaps = false;
|
||||
@ -10736,6 +10813,8 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
||||
}
|
||||
|
||||
switch (tex->get_texture_type()) {
|
||||
case Texture::TT_buffer_texture:
|
||||
// Won't get here, but squelch compiler warning
|
||||
case Texture::TT_1d_texture:
|
||||
_glTexStorage1D(target, num_levels, internal_format, width);
|
||||
break;
|
||||
@ -11095,6 +11174,17 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
break;
|
||||
#endif // OPENGLES
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_BUFFER:
|
||||
if (_supports_buffer_texture) {
|
||||
_glBufferSubData(GL_TEXTURE_BUFFER, 0, width, image_ptr);
|
||||
} else {
|
||||
report_my_gl_errors();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif // OPENGLES
|
||||
|
||||
default:
|
||||
if (image_compression == Texture::CM_off) {
|
||||
if (n==0) {
|
||||
@ -11248,6 +11338,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_2D_ARRAY_EXT:
|
||||
if (_supports_2d_texture_array) {
|
||||
@ -11265,7 +11356,19 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif // OPENGLES
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_BUFFER:
|
||||
if (_supports_buffer_texture) {
|
||||
_glBufferData(GL_TEXTURE_BUFFER, width, image_ptr,
|
||||
get_usage(tex->get_usage_hint()));
|
||||
} else {
|
||||
report_my_gl_errors();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif // OPENGLES
|
||||
|
||||
default:
|
||||
if (image_compression == Texture::CM_off) {
|
||||
@ -11396,6 +11499,12 @@ get_texture_memory_size(Texture *tex) {
|
||||
// We need a particular page to get the level parameter from.
|
||||
page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
scale = 6;
|
||||
|
||||
} else if (target == GL_TEXTURE_BUFFER) {
|
||||
// In the case of buffer textures, we provided the size to begin with,
|
||||
// so no point in querying anything. Plus, glGetTexParameter is not even
|
||||
// supported for buffer textures.
|
||||
return tex->get_expected_ram_image_size();
|
||||
}
|
||||
|
||||
GLint minfilter;
|
||||
@ -11431,20 +11540,20 @@ get_texture_memory_size(Texture *tex) {
|
||||
luminance_size, intensity_size;
|
||||
GLint depth_size = 0;
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_RED_SIZE, &red_size);
|
||||
GL_TEXTURE_RED_SIZE, &red_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
GL_TEXTURE_GREEN_SIZE, &green_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
if (_supports_depth_texture) {
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
||||
GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
||||
}
|
||||
|
||||
GLint width = 1, height = 1, depth = 1;
|
||||
|
@ -693,6 +693,10 @@ public:
|
||||
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
|
||||
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
|
||||
|
||||
#ifndef OPENGLES
|
||||
PFNGLTEXBUFFERPROC _glTexBuffer;
|
||||
#endif
|
||||
|
||||
bool _supports_clear_texture;
|
||||
#ifndef OPENGLES
|
||||
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
|
||||
|
@ -602,16 +602,19 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_BUFFER:
|
||||
case GL_UNSIGNED_INT_SAMPLER_1D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||
case GL_SAMPLER_1D_SHADOW:
|
||||
case GL_SAMPLER_1D:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_SAMPLER_BUFFER:
|
||||
#endif // !OPENGLES
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
@ -620,7 +623,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
Shader::ShaderTexSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._name = InternalName::make(param_name);
|
||||
bind._desired_type = Texture::TT_2d_texture_array;
|
||||
bind._desired_type = Texture::TT_2d_texture;
|
||||
bind._stage = texunitno++;
|
||||
if (get_sampler_texture_type(bind._desired_type, param_type)) {
|
||||
_glgsg->_glUniform1i(p, s->_tex_spec.size());
|
||||
@ -761,16 +764,19 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
||||
case GL_IMAGE_3D_EXT:
|
||||
case GL_IMAGE_CUBE_EXT:
|
||||
case GL_IMAGE_2D_ARRAY_EXT:
|
||||
case GL_IMAGE_BUFFER_EXT:
|
||||
case GL_INT_IMAGE_1D_EXT:
|
||||
case GL_INT_IMAGE_2D_EXT:
|
||||
case GL_INT_IMAGE_3D_EXT:
|
||||
case GL_INT_IMAGE_CUBE_EXT:
|
||||
case GL_INT_IMAGE_2D_ARRAY_EXT:
|
||||
case GL_INT_IMAGE_BUFFER_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_1D_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT:
|
||||
case GL_UNSIGNED_INT_IMAGE_BUFFER_EXT:
|
||||
// This won't really change at runtime, so we might as well
|
||||
// bind once and then forget about it.
|
||||
_glgsg->_glUniform1i(p, imgunitno++);
|
||||
@ -1076,6 +1082,18 @@ get_sampler_texture_type(int &out, GLenum param_type) {
|
||||
<< "GLSL shader uses 2D texture array, which is unsupported by the driver.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
case GL_INT_SAMPLER_BUFFER:
|
||||
case GL_UNSIGNED_INT_SAMPLER_BUFFER:
|
||||
case GL_SAMPLER_BUFFER:
|
||||
out = Texture::TT_buffer_texture;
|
||||
if (_glgsg->_supports_buffer_texture) {
|
||||
return true;
|
||||
} else {
|
||||
GLCAT.error()
|
||||
<< "GLSL shader uses buffer texture, which is unsupported by the driver.\n";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
@ -1509,6 +1527,12 @@ disable_shader_texture_bindings() {
|
||||
case Texture::TT_cube_map:
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
break;
|
||||
|
||||
case Texture::TT_buffer_texture:
|
||||
#ifndef OPENGLES
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg,
|
||||
_glgsg = glgsg;
|
||||
|
||||
glGenTextures(1, &_index);
|
||||
_buffer = 0;
|
||||
|
||||
_handle = 0;
|
||||
_has_storage = false;
|
||||
|
@ -34,6 +34,11 @@ CLP(TextureContext)::
|
||||
|
||||
glDeleteTextures(1, &_index);
|
||||
_index = 0;
|
||||
|
||||
if (_buffer != 0) {
|
||||
_glgsg->_glDeleteBuffers(1, &_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -88,6 +93,11 @@ reset_data() {
|
||||
// Free the texture resources.
|
||||
glDeleteTextures(1, &_index);
|
||||
|
||||
if (_buffer != 0) {
|
||||
_glgsg->_glDeleteBuffers(1, &_buffer);
|
||||
_buffer = 0;
|
||||
}
|
||||
|
||||
// We still need a valid index number, though, in case we want to
|
||||
// re-load the texture later.
|
||||
glGenTextures(1, &_index);
|
||||
|
@ -48,6 +48,9 @@ public:
|
||||
// This is the GL "name" of the texture object.
|
||||
GLuint _index;
|
||||
|
||||
// This is only used for buffer textures.
|
||||
GLuint _buffer;
|
||||
|
||||
// This is the bindless "handle" to the texture object.
|
||||
GLuint64 _handle;
|
||||
bool _handle_resident;
|
||||
|
@ -215,6 +215,26 @@ setup_cube_map(int size, ComponentType component_type, Format format) {
|
||||
setup_texture(TT_cube_map, size, size, 6, component_type, format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::setup_buffer_texture
|
||||
// Access: Published
|
||||
// Description: Sets the texture as an empty buffer texture with
|
||||
// the specified size and properties. Follow up
|
||||
// with set_ram_image() or modify_ram_image() to fill
|
||||
// the image data, or use set_clear_color to let the
|
||||
// texture be cleared to a solid color.
|
||||
//
|
||||
// Note that a buffer texture's format needs to match
|
||||
// the component type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Texture::
|
||||
setup_buffer_texture(int size, ComponentType component_type, Format format,
|
||||
GeomEnums::UsageHint usage) {
|
||||
setup_texture(TT_buffer_texture, size, 1, 1, component_type, format);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_usage_hint = usage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::clear_image
|
||||
// Access: Published
|
||||
@ -886,6 +906,18 @@ get_component_type() const {
|
||||
return cdata->_component_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_usage_hint
|
||||
// Access: Published
|
||||
// Description: Returns the usage hint specified for buffer textures,
|
||||
// or UH_unspecified for all other texture types.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomEnums::UsageHint Texture::
|
||||
get_usage_hint() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_wrap_u
|
||||
// Access: Published
|
||||
|
@ -1524,6 +1524,10 @@ write(ostream &out, int indent_level) const {
|
||||
case TT_cube_map:
|
||||
out << "cube map, " << cdata->_x_size << " x " << cdata->_y_size;
|
||||
break;
|
||||
|
||||
case TT_buffer_texture:
|
||||
out << "buffer, " << cdata->_x_size;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cdata->_num_views > 1) {
|
||||
@ -1924,6 +1928,8 @@ format_texture_type(TextureType tt) {
|
||||
return "2d_texture_array";
|
||||
case TT_cube_map:
|
||||
return "cube_map";
|
||||
case TT_buffer_texture:
|
||||
return "buffer_texture";
|
||||
}
|
||||
return "**invalid**";
|
||||
}
|
||||
@ -1946,6 +1952,8 @@ string_texture_type(const string &str) {
|
||||
return TT_2d_texture_array;
|
||||
} else if (cmp_nocase(str, "cube_map") == 0) {
|
||||
return TT_cube_map;
|
||||
} else if (cmp_nocase(str, "buffer_texture") == 0) {
|
||||
return TT_buffer_texture;
|
||||
}
|
||||
|
||||
gobj_cat->error()
|
||||
@ -2673,6 +2681,7 @@ do_read(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
switch (cdata->_texture_type) {
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
case TT_buffer_texture:
|
||||
z_size = 1;
|
||||
break;
|
||||
|
||||
@ -4854,7 +4863,8 @@ do_reconsider_image_properties(CData *cdata, int x_size, int y_size, int num_com
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (cdata->_texture_type == TT_1d_texture) {
|
||||
if (cdata->_texture_type == TT_1d_texture ||
|
||||
cdata->_texture_type == TT_buffer_texture) {
|
||||
nassertr(y_size == 1, false);
|
||||
} else if (cdata->_texture_type == TT_cube_map) {
|
||||
nassertr(x_size == y_size, false);
|
||||
@ -5051,6 +5061,10 @@ do_setup_texture(CData *cdata, Texture::TextureType texture_type,
|
||||
cdata->_default_sampler.set_wrap_v(SamplerState::WM_clamp);
|
||||
cdata->_default_sampler.set_wrap_w(SamplerState::WM_clamp);
|
||||
break;
|
||||
|
||||
case TT_buffer_texture:
|
||||
nassertv(y_size == 1 && z_size == 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (texture_type != TT_2d_texture) {
|
||||
@ -5199,7 +5213,8 @@ do_set_x_size(CData *cdata, int x_size) {
|
||||
void Texture::
|
||||
do_set_y_size(CData *cdata, int y_size) {
|
||||
if (cdata->_y_size != y_size) {
|
||||
nassertv(cdata->_texture_type != Texture::TT_1d_texture || y_size == 1);
|
||||
nassertv((cdata->_texture_type != Texture::TT_buffer_texture &&
|
||||
cdata->_texture_type != Texture::TT_1d_texture) || y_size == 1);
|
||||
cdata->_y_size = y_size;
|
||||
cdata->inc_image_modified();
|
||||
do_clear_ram_image(cdata);
|
||||
@ -7897,6 +7912,10 @@ do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) {
|
||||
me.add_uint8(cdata->_format);
|
||||
me.add_uint8(cdata->_num_components);
|
||||
|
||||
if (cdata->_texture_type == TT_buffer_texture) {
|
||||
me.add_uint8(cdata->_usage_hint);
|
||||
}
|
||||
|
||||
me.add_uint8(cdata->_auto_texture_scale);
|
||||
me.add_uint32(cdata->_orig_file_x_size);
|
||||
me.add_uint32(cdata->_orig_file_y_size);
|
||||
@ -8063,6 +8082,7 @@ make_this_from_bam(const FactoryParams ¶ms) {
|
||||
options.set_auto_texture_scale(auto_texture_scale);
|
||||
|
||||
switch (texture_type) {
|
||||
case TT_buffer_texture:
|
||||
case TT_1d_texture:
|
||||
case TT_2d_texture:
|
||||
if (alpha_filename.empty()) {
|
||||
@ -8124,6 +8144,10 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
|
||||
cdata->_format = (Format)scan.get_uint8();
|
||||
cdata->_num_components = scan.get_uint8();
|
||||
|
||||
if (cdata->_texture_type == TT_buffer_texture) {
|
||||
cdata->_usage_hint = (GeomEnums::UsageHint)scan.get_uint8();
|
||||
}
|
||||
|
||||
cdata->inc_properties_modified();
|
||||
|
||||
cdata->_auto_texture_scale = ATS_unspecified;
|
||||
@ -8304,6 +8328,9 @@ CData() {
|
||||
// check in do_set_format depending on an uninitialized value.
|
||||
_format = F_rgba;
|
||||
|
||||
// Only used for buffer textures.
|
||||
_usage_hint = GeomEnums::UH_unspecified;
|
||||
|
||||
_pad_x_size = 0;
|
||||
_pad_y_size = 0;
|
||||
_pad_z_size = 0;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "samplerState.h"
|
||||
#include "pnmImage.h"
|
||||
#include "colorSpace.h"
|
||||
#include "geomEnums.h"
|
||||
|
||||
class PNMImage;
|
||||
class PfmFile;
|
||||
@ -82,6 +83,7 @@ PUBLISHED:
|
||||
TT_3d_texture,
|
||||
TT_2d_texture_array,
|
||||
TT_cube_map,
|
||||
TT_buffer_texture,
|
||||
};
|
||||
|
||||
enum ComponentType {
|
||||
@ -240,6 +242,8 @@ PUBLISHED:
|
||||
INLINE void setup_2d_texture_array(int z_size = 1);
|
||||
INLINE void setup_2d_texture_array(int x_size, int y_size, int z_size,
|
||||
ComponentType component_type, Format format);
|
||||
INLINE void setup_buffer_texture(int size, ComponentType component_type,
|
||||
Format format, GeomEnums::UsageHint usage);
|
||||
void generate_normalization_cube_map(int size);
|
||||
void generate_alpha_scale_map();
|
||||
|
||||
@ -304,6 +308,7 @@ PUBLISHED:
|
||||
INLINE TextureType get_texture_type() const;
|
||||
INLINE Format get_format() const;
|
||||
INLINE ComponentType get_component_type() const;
|
||||
INLINE GeomEnums::UsageHint get_usage_hint() const;
|
||||
|
||||
INLINE void set_wrap_u(WrapMode wrap);
|
||||
INLINE void set_wrap_v(WrapMode wrap);
|
||||
@ -829,6 +834,7 @@ protected:
|
||||
TextureType _texture_type;
|
||||
Format _format;
|
||||
ComponentType _component_type;
|
||||
GeomEnums::UsageHint _usage_hint;
|
||||
|
||||
bool _loaded_from_image;
|
||||
bool _loaded_from_txo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user