gl_vertex_blend with immediate-mode

This commit is contained in:
David Rose 2005-08-16 01:49:38 +00:00
parent 182e65f9e2
commit b390e64bc8
5 changed files with 448 additions and 2 deletions

View File

@ -360,8 +360,11 @@ reset() {
get_extension_func(GLPREFIX_QUOTED, "WeightPointerARB");
_glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)
get_extension_func(GLPREFIX_QUOTED, "VertexBlendARB");
_glWeightfvARB = (PFNGLWEIGHTFVARBPROC)
get_extension_func(GLPREFIX_QUOTED, "WeightfvARB");
if (_glWeightPointerARB == NULL || _glVertexBlendARB == NULL) {
if (_glWeightPointerARB == NULL || _glVertexBlendARB == NULL ||
_glWeightfvARB == NULL) {
GLCAT.warning()
<< "Vertex blending advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
_supports_vertex_blend = false;
@ -385,8 +388,12 @@ reset() {
get_extension_func(GLPREFIX_QUOTED, "CurrentPaletteMatrixARB");
_glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)
get_extension_func(GLPREFIX_QUOTED, "MatrixIndexPointerARB");
_glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)
get_extension_func(GLPREFIX_QUOTED, "MatrixIndexuivARB");
if (_glCurrentPaletteMatrixARB == NULL || _glMatrixIndexPointerARB == NULL) {
if (_glCurrentPaletteMatrixARB == NULL ||
_glMatrixIndexPointerARB == NULL ||
_glMatrixIndexuivARB == NULL) {
GLCAT.warning()
<< "Matrix palette advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
_supports_matrix_palette = false;
@ -1345,6 +1352,20 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
}
_last_max_stage_index = max_stage_index;
if (_supports_vertex_blend) {
if (hardware_animation) {
// Issue the weights and/or transform indices for vertex blending.
_sender.add_vector_column(_vertex_data, InternalName::get_transform_weight(),
_glWeightfvARB);
if (animation.get_indexed_transforms()) {
// Issue the matrix palette indices.
_sender.add_vector_uint_column(_vertex_data, InternalName::get_transform_index(),
_glMatrixIndexuivARB);
}
}
}
// We must add vertex last, because glVertex3f() is the key
// function call that actually issues the vertex.
_sender.add_column(_vertex_data, InternalName::get_vertex(),

View File

@ -337,10 +337,12 @@ public:
bool _supports_vertex_blend;
PFNGLWEIGHTPOINTERARBPROC _glWeightPointerARB;
PFNGLVERTEXBLENDARBPROC _glVertexBlendARB;
PFNGLWEIGHTFVARBPROC _glWeightfvARB;
bool _supports_matrix_palette;
PFNGLCURRENTPALETTEMATRIXARBPROC _glCurrentPaletteMatrixARB;
PFNGLMATRIXINDEXPOINTERARBPROC _glMatrixIndexPointerARB;
PFNGLMATRIXINDEXUIVARBPROC _glMatrixIndexuivARB;
bool _supports_draw_range_elements;
PFNGLDRAWRANGEELEMENTSPROC _glDrawRangeElements;

View File

@ -155,3 +155,99 @@ TexcoordSender4f(GeomVertexReader *reader, TexcoordFunc4f *func,
_stage_index(stage_index)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender1f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender1f::
VectorSender1f(GeomVertexReader *reader, VectorFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender2f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender2f::
VectorSender2f(GeomVertexReader *reader, VectorFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender3f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender3f::
VectorSender3f(GeomVertexReader *reader, VectorFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender4f::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender4f::
VectorSender4f(GeomVertexReader *reader, VectorFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender1ui::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender1ui::
VectorSender1ui(GeomVertexReader *reader, VectorUintFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender2ui::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender2ui::
VectorSender2ui(GeomVertexReader *reader, VectorUintFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender3ui::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender3ui::
VectorSender3ui(GeomVertexReader *reader, VectorUintFunc *func) :
ComponentSender(reader),
_func(func)
{
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender4ui::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(ImmediateModeSender)::VectorSender4ui::
VectorSender4ui(GeomVertexReader *reader, VectorUintFunc *func) :
ComponentSender(reader),
_func(func)
{
}

View File

@ -190,6 +190,115 @@ add_texcoord_column(const GeomVertexData *vertex_data,
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::add_vector_column
// Access: Public
// Description: Creates a new ComponentSender for the named data
// column, if it exists in the vertex data, and adds it
// to the list of senders for this object.
//
// This works like add_column(), but it specifically
// handles a function that accepts as its first
// parameter the size (number of components) of the
// floating-point vector, followed by the address of the
// vector.
//
// The return value is true if the column is added,
// false if it is not for some reason (for instance, the
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
VectorFunc *func) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
case 1:
sender = new VectorSender1f(reader, func);
break;
case 2:
sender = new VectorSender2f(reader, func);
break;
case 3:
sender = new VectorSender3f(reader, func);
break;
case 4:
sender = new VectorSender4f(reader, func);
break;
}
if (sender != (ComponentSender *)NULL) {
// Ok, we've got a valid sender; add it to the list.
_senders.push_back(sender);
return true;
} else {
// We didn't get a valid sender; clean up and return.
delete reader;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::add_vector_uint_column
// Access: Public
// Description: Creates a new ComponentSender for the named data
// column, if it exists in the vertex data, and adds it
// to the list of senders for this object.
//
// This works like add_vector_column(), but handles a
// function that receives a vector of unsigned ints.
//
// The return value is true if the column is added,
// false if it is not for some reason (for instance, the
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_vector_uint_column(const GeomVertexData *vertex_data,
const InternalName *name, VectorUintFunc *func) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
case 1:
sender = new VectorSender1ui(reader, func);
break;
case 2:
sender = new VectorSender2ui(reader, func);
break;
case 3:
sender = new VectorSender3ui(reader, func);
break;
case 4:
sender = new VectorSender4ui(reader, func);
break;
}
if (sender != (ComponentSender *)NULL) {
// Ok, we've got a valid sender; add it to the list.
_senders.push_back(sender);
return true;
} else {
// We didn't get a valid sender; clean up and return.
delete reader;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::add_sender
// Access: Public
@ -360,3 +469,150 @@ issue_vertex() {
(*_func)(GL_TEXTURE0 + _stage_index, d[0], d[1], d[2], d[3]);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender1f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender1f::
issue_vertex() {
float d = _reader->get_data1f();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(1, &d);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender2f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender2f::
issue_vertex() {
const LVecBase2f &d = _reader->get_data2f();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(2, d.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender3f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender3f::
issue_vertex() {
const LVecBase3f &d = _reader->get_data3f();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(3, d.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender4f::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender4f::
issue_vertex() {
const LVecBase4f &d = _reader->get_data4f();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(4, d.get_data());
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender1ui::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender1ui::
issue_vertex() {
int d = _reader->get_data1i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d << "\n";
}
#endif // NDEBUG
(*_func)(1, (const unsigned int *)&d);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender2ui::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender2ui::
issue_vertex() {
const int *d = _reader->get_data2i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d[0] << " "
<< d[1] << "\n";
}
#endif // NDEBUG
(*_func)(2, (const unsigned int *)d);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender3ui::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender3ui::
issue_vertex() {
const int *d = _reader->get_data3i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d[0] << " "
<< d[1] << " " << d[2] << "\n";
}
#endif // NDEBUG
(*_func)(3, (const unsigned int *)d);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(ImmediateModeSender)::VectorSender4ui::issue_vertex
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender4ui::
issue_vertex() {
const int *d = _reader->get_data4i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
<< *_reader->get_column()->get_name() << ": " << d[0] << " "
<< d[1] << " " << d[2] << " " << d[3] << "\n";
}
#endif // NDEBUG
(*_func)(4, (const unsigned int *)d);
}

View File

@ -53,6 +53,8 @@ public:
typedef void APIENTRY TexcoordFunc2f(GLenum texture, GLfloat a, GLfloat b);
typedef void APIENTRY TexcoordFunc3f(GLenum texture, GLfloat a, GLfloat b, GLfloat c);
typedef void APIENTRY TexcoordFunc4f(GLenum texture, GLfloat a, GLfloat b, GLfloat c, GLfloat d);
typedef void APIENTRY VectorFunc(GLint, const GLfloat *);
typedef void APIENTRY VectorUintFunc(GLint, const GLuint *);
bool add_column(const GeomVertexData *vertex_data, const InternalName *name,
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f);
@ -61,6 +63,11 @@ public:
TexcoordFunc1f *func1f, TexcoordFunc2f *func2f,
TexcoordFunc3f *func3f, TexcoordFunc4f *func4f);
bool add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
VectorFunc *func);
bool add_vector_uint_column(const GeomVertexData *vertex_data, const InternalName *name,
VectorUintFunc *func);
void add_sender(ComponentSender *sender);
public:
@ -147,6 +154,70 @@ public:
int _stage_index;
};
class VectorSender1f : public ComponentSender {
public:
INLINE VectorSender1f(GeomVertexReader *reader, VectorFunc *func);
virtual void issue_vertex();
private:
VectorFunc *_func;
};
class VectorSender2f : public ComponentSender {
public:
INLINE VectorSender2f(GeomVertexReader *reader, VectorFunc *func);
virtual void issue_vertex();
private:
VectorFunc *_func;
};
class VectorSender3f : public ComponentSender {
public:
INLINE VectorSender3f(GeomVertexReader *reader, VectorFunc *func);
virtual void issue_vertex();
private:
VectorFunc *_func;
};
class VectorSender4f : public ComponentSender {
public:
INLINE VectorSender4f(GeomVertexReader *reader, VectorFunc *func);
virtual void issue_vertex();
private:
VectorFunc *_func;
};
class VectorSender1ui : public ComponentSender {
public:
INLINE VectorSender1ui(GeomVertexReader *reader, VectorUintFunc *func);
virtual void issue_vertex();
private:
VectorUintFunc *_func;
};
class VectorSender2ui : public ComponentSender {
public:
INLINE VectorSender2ui(GeomVertexReader *reader, VectorUintFunc *func);
virtual void issue_vertex();
private:
VectorUintFunc *_func;
};
class VectorSender3ui : public ComponentSender {
public:
INLINE VectorSender3ui(GeomVertexReader *reader, VectorUintFunc *func);
virtual void issue_vertex();
private:
VectorUintFunc *_func;
};
class VectorSender4ui : public ComponentSender {
public:
INLINE VectorSender4ui(GeomVertexReader *reader, VectorUintFunc *func);
virtual void issue_vertex();
private:
VectorUintFunc *_func;
};
private:
typedef pvector<ComponentSender *> ComponentSenders;
ComponentSenders _senders;