C++学习(三零九)osg::VertexArrayState的作用

Posted hankern

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习(三零九)osg::VertexArrayState的作用相关的知识,希望对你有一定的参考价值。

它有很多顶点属性派发器VertexAttribArrayDispatch,负责将顶点属性的数据从cpu派发到gpu。

1、创建

1.1VertexArrayState的创建

当前窗体处于渲染状态时进行创建。

1.2VertexArrayDispatch的创建

VertexArrayState创建完成后,紧接着就会创建2VertexArrayDispatch派发器。

2、使用

主要是完成数据上传操作,也就是调用glVertexAttribPointer。工作路径是Geometry->VertexArrayState->VertexAttribArrayDispatch。

osg/VertexArrayState 
class OSG_EXPORT VertexArrayState : public osg::Referenced
{
        struct ArrayDispatch : public osg::Referenced
        {
            ArrayDispatch():
                array(0),
                modifiedCount(0xffffffff),
                active(false) {}

            virtual bool isVertexAttribDispatch() const { return false; }

            virtual const char* className() const = 0; // { return "ArrayDispatch"; }

            virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;

            virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;

            virtual void enable_and_dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;

            virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;

            virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;

            virtual void dispatch(osg::State& /*state*/, GLint /*size*/, GLenum /*type*/, GLsizei /*stride*/, const GLvoid * /*ptr*/, GLboolean /*normalized*/) {} // = 0;

            virtual void disable(osg::State& /*state*/) {} // = 0;

            const osg::Array*   array;
            unsigned int        modifiedCount;
            bool                active;
        };
        osg::ref_ptr<ArrayDispatch>     _vertexArray;
        osg::ref_ptr<ArrayDispatch>     _normalArray;
        osg::ref_ptr<ArrayDispatch>     _colorArray;
        osg::ref_ptr<ArrayDispatch>     _secondaryColorArray;
        osg::ref_ptr<ArrayDispatch>     _fogCoordArray;
};
osg/VertexArrayState.cpp
struct VertexAttribArrayDispatch : public VertexArrayState::ArrayDispatch
{
    VertexAttribArrayDispatch(unsigned int in_unit) : unit(in_unit) {}

    virtual const char* className() const { return "VertexAttribArrayDispatch"; }

    virtual bool isVertexAttribDispatch() const { return true; }

    inline void callVertexAttribPointer(GLExtensions* ext, const osg::Array* new_array, const GLvoid * ptr)
    {
        if (new_array->getPreserveDataType())
        {
            if (new_array->getDataType()==GL_FLOAT)
                ext->glVertexAttribPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), new_array->getNormalize(), 0, ptr);
            else if (new_array->getDataType()==GL_DOUBLE)
                ext->glVertexAttribLPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), 0, ptr);
            else
                ext->glVertexAttribIPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), 0, ptr);
        }
        else
        {
            ext->glVertexAttribPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), new_array->getNormalize(), 0, ptr);
        }
    }

    virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
    {
        GLExtensions* ext = state.get<GLExtensions>();

        ext->glEnableVertexAttribArray( unit );
        callVertexAttribPointer(ext, new_array, new_array->getDataPointer());
    }

    virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
    {
        GLExtensions* ext = state.get<GLExtensions>();

        ext->glEnableVertexAttribArray( unit );
        callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
    }

    virtual void enable_and_dispatch(osg::State& state, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized)
    {
        GLExtensions* ext = state.get<GLExtensions>();
 
        ext->glEnableVertexAttribArray( unit );
        ext->glVertexAttribPointer(static_cast<GLuint>(unit), size, type, normalized, stride, ptr);
    }

    virtual void dispatch(osg::State& state, const osg::Array* new_array)
    {
        GLExtensions* ext = state.get<GLExtensions>();
        callVertexAttribPointer(ext, new_array, new_array->getDataPointer());
    }

    virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
    {
        GLExtensions* ext = state.get<GLExtensions>();
        callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
    }

    virtual void disable(osg::State& state)
    {
        GLExtensions* ext = state.get<GLExtensions>();
        ext->glDisableVertexAttribArray( unit );
    }

    unsigned int unit;
};

以上是关于C++学习(三零九)osg::VertexArrayState的作用的主要内容,如果未能解决你的问题,请参考以下文章

C++学习(三零一)吹气球效应

C++学习(三零七)AttributeDispatchers详解

C++学习(三零二)知识图谱中的几种关系

C++学习(三零五)osg开启 关闭光照效果

C++学习(三零四)osg材质Material使用

C++学习(四三零)如何查看libtool的执行过程