bool
OpenSubdivShaderOverride::draw(MHWRender::MDrawContext &context, const MHWRender::MRenderItemList &renderItemList) const
{
	using namespace MHWRender;
    {
        MHWRender::MStateManager *stateMgr = context.getStateManager();
        static const MDepthStencilState * depthState = NULL;
        if (!depthState) {
            MDepthStencilStateDesc desc;
            depthState = stateMgr->acquireDepthStencilState(desc);
        }
        static const MBlendState *blendState = NULL;
        if (!blendState) {
            MBlendStateDesc desc;

            for(int i = 0; i < (desc.independentBlendEnable ? MHWRender::MBlendState::kMaxTargets : 1); ++i) 
            {    
                desc.targetBlends[i].blendEnable = false;
            }
            blendState = stateMgr->acquireBlendState(desc);
        }

        stateMgr->setDepthStencilState(depthState);
        stateMgr->setBlendState(blendState);
    }

    for(int i=0; i< renderItemList.length(); i++){
        const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i);
        OsdMeshData *data = (OsdMeshData*)(renderItem->customData());
        if (data == NULL) {
            return false;
        }
        
        data->populateIfNeeded(_shader->getLevel(), _shader->getScheme(), _shader->getKernel());

        const MHWRender::MVertexBuffer *position = NULL, *normal = NULL;
        {
            const MHWRender::MGeometry *geometry = renderItem->geometry();
            for(int i = 0; i < geometry->vertexBufferCount(); i++){
                const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i);
                const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor();
                if (vdesc.name() == "osdPosition")
                    position = vb;
                if (vdesc.name() == "osdNormal")
                    normal = vb;
            }
        }

        float diffuse[4] = {1, 1, 1, 1};
        float ambient[4] = {0.1f, 0.1f, 0.1f, 0.1f};
        float specular[4] = {1, 1, 1, 1};
        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);

        glPushAttrib(GL_POLYGON_BIT);
        glPushAttrib(GL_ENABLE_BIT);

        if (_shader->isWireframe()) {
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            glDisable(GL_LIGHTING);
            glDisable(GL_LIGHT0);
        } else {
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            glEnable(GL_LIGHTING);
            glEnable(GL_LIGHT0);
        }

        // draw meshdata
        data->prepare();

        data->updateGeometry(position, normal);

        data->draw();

        glPopAttrib();
        glPopAttrib();
    }
    return true;
}
bool
OpenSubdivPtexShaderOverride::draw(
    MHWRender::MDrawContext &context,
    const MHWRender::MRenderItemList &renderItemList) const
{
    {
        MHWRender::MStateManager *stateMgr = context.getStateManager();
        static const MDepthStencilState * depthState = NULL;
        if (!depthState) {
            MDepthStencilStateDesc desc;
            depthState = stateMgr->acquireDepthStencilState(desc);
        }
        static const MBlendState *blendState = NULL;
        if (!blendState) {
            MBlendStateDesc desc;

            int ntargets = desc.independentBlendEnable ?
                MHWRender::MBlendState::kMaxTargets : 1;

            for (int i = 0; i < ntargets; ++i) {
                desc.targetBlends[i].blendEnable = false;
            }
            blendState = stateMgr->acquireBlendState(desc);
        }

        stateMgr->setDepthStencilState(depthState);
        stateMgr->setBlendState(blendState);
    }

    for (int i = 0; i < renderItemList.length(); i++) 
    {
        const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i);
        OsdPtexMeshData *data =
            static_cast<OsdPtexMeshData*>(renderItem->customData());
        if (data == NULL) {
            return false;
        }

        // pass attribute values into osdPtexMeshData
        data->rebuildHbrMeshIfNeeded(_shader);

        const MHWRender::MVertexBuffer *position = NULL, *normal = NULL;
        {
            const MHWRender::MGeometry *geometry = renderItem->geometry();
            for (int i = 0; i < geometry->vertexBufferCount(); i++) {
                const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i);
                const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor();

                if (vdesc.name() == "osdPosition")
                    position = vb;
                else if (vdesc.name() == "osdNormal")
                    normal = vb;
            }
        }

        // draw meshdata
        data->prepare();

        data->updateGeometry(position, normal);

        _shader->draw(context, data);
    }

    return true;
}
//
// #### Override draw method.  
//
// Setup draw state and call osdMeshData methods to setup 
// and refine geometry.  Call to shader to do actual drawing.
//
bool
OpenSubdivShaderOverride::draw(
    MHWRender::MDrawContext &context,
    const MHWRender::MRenderItemList &renderItemList) const
{
    {
        MHWRender::MStateManager *stateMgr = context.getStateManager();
        static const MDepthStencilState * depthState = NULL;
        if (!depthState) {
            MDepthStencilStateDesc desc;
            depthState = stateMgr->acquireDepthStencilState(desc);
        }
        static const MBlendState *blendState = NULL;
        if (!blendState) {
            MBlendStateDesc desc;

            int ntargets = desc.independentBlendEnable ?
                MHWRender::MBlendState::kMaxTargets : 1;

            for (int i = 0; i < ntargets; ++i) {
                desc.targetBlends[i].blendEnable = false;
            }
            blendState = stateMgr->acquireBlendState(desc);
        }

        stateMgr->setDepthStencilState(depthState);
        stateMgr->setBlendState(blendState);
    }

    for (int i = 0; i < renderItemList.length(); i++) 
    {
        const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i);
        OsdMeshData *data =
            static_cast<OsdMeshData*>(renderItem->customData());
        if (data == NULL) {
            return false;
        }

        // If attributes or topology have changed which affect 
        // the HBR mesh it will be regenerated here.
        data->rebuildHbrMeshIfNeeded(_shader);

        const MHWRender::MVertexBuffer *position = NULL;
        {
            const MHWRender::MGeometry *geometry = renderItem->geometry();
            for (int i = 0; i < geometry->vertexBufferCount(); i++) {
                const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i);
                const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor();

                if (vdesc.name() == "osdPosition")
                    position = vb;
            }
        }

        // If HBR mesh was regenerated, rebuild FAR mesh factory
        // and recreate OSD draw context
        data->prepare();

        // Refine geometry
        data->updateGeometry(position);

        // Draw patches
        _shader->draw(context, data);
    }

    return true;
}