gl_vertex_blend with immediate-mode
This commit is contained in:
parent
182e65f9e2
commit
b390e64bc8
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue