void arrowLocatorOverride::draw(
	const MHWRender::MDrawContext& context,
	const MUserData* data)
{
	MAngle rotationAngle;

	float color [3] ={ 0.0f, 1.0f, 0.0f } ;

	// data
	MStatus status;
	MHWRender::MStateManager* stateMgr = context.getStateManager();
	const arrowLocatorData* locatorData =
		dynamic_cast<const arrowLocatorData*>(data);
	if (!stateMgr || !locatorData) return;

	if ( locatorData )
		rotationAngle = locatorData->rotateAngle;

	// matrices
	const MMatrix transform =
		context.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status);
	if (status != MStatus::kSuccess) return;
	const MMatrix projection =
		context.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status);
	if (status != MStatus::kSuccess) return;

	// get renderer
	MHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ;
	if ( !theRenderer )
		return ;
	if ( theRenderer->drawAPIIsOpenGL () ) {
		
		glPushAttrib(GL_CURRENT_BIT);
		glColor4fv(color);

		glPushMatrix();
		glRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0);
		glBegin( GL_LINE_STRIP);
		glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);
		glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);
		glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);
		glEnd();

		glBegin( GL_LINE_STRIP );
		glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);
		glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);
		glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);
		glEnd();
		glPopMatrix();

	}
}
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;
}
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;
}
void UsdMayaGLHdRenderer::RenderVp2(
    const RequestDataArray &requests,
    const MHWRender::MDrawContext& context,
    UsdImagingGLRenderParams params) const
{
    using namespace MHWRender;

    MStatus status;
    MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer();
    if (!theRenderer) return;

    MHWRender::MStateManager* stateMgr = context.getStateManager();
    if (!stateMgr) return;

    const int displayStyle = context.getDisplayStyle();
    if (displayStyle == 0) return;

    if (displayStyle & MDrawContext::kXray) {
        // Viewport 2.0 will call draw() twice when drawing transparent objects
        // (X-Ray mode). We skip the first draw() call.
        const MRasterizerState* rasterState = stateMgr->getRasterizerState();
        if (rasterState && rasterState->desc().cullMode == MRasterizerState::kCullFront) {
            return;
        }
    }

    if (!theRenderer->drawAPIIsOpenGL()) return;


    glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT);

    const MMatrix worldView =
        context.getMatrix(MHWRender::MDrawContext::kWorldViewMtx, &status);
    GfMatrix4d modelViewMatrix(worldView.matrix);

    const MMatrix projection =
        context.getMatrix(MHWRender::MDrawContext::kProjectionMtx, &status);
    GfMatrix4d projectionMatrix(projection.matrix);

    // get root matrix
    MMatrix root = context.getMatrix(MHWRender::MDrawContext::kWorldMtx, &status);
    GfMatrix4d rootMatrix(root.matrix);

    // Extract camera settings from maya view
    int viewX, viewY, viewWidth, viewHeight;
    context.getViewportDimensions(viewX, viewY, viewWidth, viewHeight);

    GfVec4d viewport(viewX, viewY, viewWidth, viewHeight);

    M3dView::DisplayStyle viewDisplayStyle = displayStyle & MDrawContext::kWireFrame ?
        M3dView::kWireFrame : M3dView::kGouraudShaded;

    if(viewDisplayStyle == M3dView::kGouraudShaded)
    {
        px_vp20Utils::setupLightingGL(context);
        glEnable(GL_LIGHTING);
    }

    _renderer->SetCameraState(modelViewMatrix, projectionMatrix, viewport);

    _renderer->SetLightingStateFromOpenGL();


    TF_FOR_ALL(it, requests) {
        RequestData request = *it;
        if(viewDisplayStyle == M3dView::kWireFrame && request.drawRequest.displayStyle() == M3dView::kGouraudShaded) {
            request.drawRequest.setDisplayStyle(viewDisplayStyle);
        }

        switch(request.drawRequest.token()) {
        case UsdMayaGLHdRenderer::DRAW_WIREFRAME:
        case UsdMayaGLHdRenderer::DRAW_POINTS: {

            params.drawMode = request.drawRequest.token() == 
                UsdMayaGLHdRenderer::DRAW_WIREFRAME ? 
                    UsdImagingGLDrawMode::DRAW_WIREFRAME :
                    UsdImagingGLDrawMode::DRAW_POINTS;
            params.enableLighting = false;
            params.cullStyle = UsdImagingGLCullStyle::CULL_STYLE_NOTHING;

            params.overrideColor = request.fWireframeColor;

            // Get and render usdPrim
            _renderer->Render(_renderedPrim, params);

            break;
        }
        case UsdMayaGLHdRenderer::DRAW_SHADED_FLAT:
        case UsdMayaGLHdRenderer::DRAW_SHADED_SMOOTH: {


            params.drawMode = ((request.drawRequest.token() == 
                    UsdMayaGLHdRenderer::DRAW_SHADED_FLAT) ?
                        UsdImagingGLDrawMode::DRAW_GEOM_FLAT : 
                        UsdImagingGLDrawMode::DRAW_GEOM_SMOOTH);
            params.enableLighting = true;
            params.cullStyle = 
                UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED;

            _renderer->Render(_renderedPrim, params);


            break;
        }
        case UsdMayaGLHdRenderer::DRAW_BOUNDING_BOX: {
            px_vp20Utils::RenderBoundingBox(request.bounds,
                                            request.fWireframeColor,
                                            worldView,
                                            projection);
            break;
        }
        }
    }