void Hd_TestDriver::SetRepr(HdReprSelector const &reprSelector) { _reprSelector = reprSelector; if (_geomAndGuidePass) { TfTokenVector renderTags; renderTags.push_back(HdTokens->geometry); renderTags.push_back(HdTokens->guide); HdRprimCollection col = HdRprimCollection( HdTokens->geometry, _reprSelector); col.SetRenderTags(renderTags); _geomAndGuidePass->SetRprimCollection(col); } if (_geomPass) { TfTokenVector renderTags; renderTags.push_back(HdTokens->geometry); HdRprimCollection col = HdRprimCollection( HdTokens->geometry, _reprSelector); col.SetRenderTags(renderTags); _geomPass->SetRprimCollection(col); } }
HdRenderPassSharedPtr const & Hd_TestDriver::GetRenderPass(bool withGuides) { if (withGuides) { if (!_geomAndGuidePass) { TfTokenVector renderTags; renderTags.push_back(HdTokens->geometry); renderTags.push_back(HdTokens->guide); HdRprimCollection col = HdRprimCollection( HdTokens->geometry, _reprSelector); col.SetRenderTags(renderTags); _geomAndGuidePass = HdRenderPassSharedPtr( new Hd_UnitTestNullRenderPass(&_sceneDelegate->GetRenderIndex(), col)); } return _geomAndGuidePass; } else { if (!_geomPass) { TfTokenVector renderTags; renderTags.push_back(HdTokens->geometry); HdRprimCollection col = HdRprimCollection( HdTokens->geometry, _reprSelector); col.SetRenderTags(renderTags); _geomPass = HdRenderPassSharedPtr( new Hd_UnitTestNullRenderPass(&_sceneDelegate->GetRenderIndex(), col)); } return _geomPass; } }
void My_TestGLDrawing::InitTest() { _renderIndex = HdRenderIndex::New(&_renderDelegate); TF_VERIFY(_renderIndex != nullptr); _delegate.reset(new Hdx_UnitTestDelegate(_renderIndex)); // prepare render task SdfPath renderSetupTask("/renderSetupTask"); SdfPath renderTask("/renderTask"); SdfPath selectionTask("/selectionTask"); _delegate->AddRenderSetupTask(renderSetupTask); _delegate->AddRenderTask(renderTask); _delegate->AddSelectionTask(selectionTask); // render task parameters. VtValue vParam = _delegate->GetTaskParam(renderSetupTask, HdTokens->params); HdxRenderTaskParams param = vParam.Get<HdxRenderTaskParams>(); param.enableLighting = true; // use default lighting _delegate->SetTaskParam(renderSetupTask, HdTokens->params, VtValue(param)); _delegate->SetTaskParam(renderTask, HdTokens->collection, VtValue(HdRprimCollection(HdTokens->geometry, HdReprSelector(HdReprTokens->hull)))); HdxSelectionTaskParams selParam; selParam.enableSelection = true; selParam.selectionColor = GfVec4f(1, 1, 0, 1); selParam.locateColor = GfVec4f(1, 0, 1, 1); _delegate->SetTaskParam(selectionTask, HdTokens->params, VtValue(selParam)); // prepare scene _InitScene(); SetCameraTranslate(GfVec3f(0, 0, -20)); // picking related init _pickablesCol = HdRprimCollection(_tokens->pickables, HdReprSelector(HdReprTokens->hull)); _marquee.InitGLResources(); _picker.InitIntersector(_renderIndex); _SetPickParams(); // We have to unfortunately explictly add collections besides 'geometry' // See HdRenderIndex constructor. _delegate->GetRenderIndex().GetChangeTracker().AddCollection(_tokens->pickables); // XXX: Setup a VAO, the current drawing engine will not yet do this. glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindVertexArray(0); }
// _renderPass's collection is populated after build time, during Sync(). HdxDrawTargetRenderPass::HdxDrawTargetRenderPass(HdRenderIndex *index) : _renderPass(index, HdRprimCollection()) , _drawTargetRenderPassState(nullptr) , _drawTarget() , _drawTargetContext() , _collectionObjectVersion(0) { }
// UsdImaging_TestDriver void UsdImaging_TestDriver::_Init(UsdStageRefPtr const& usdStage, TfToken const &collectionName, TfToken const &reprName, TfTokenVector const &renderTags) { _renderIndex = HdRenderIndex::New(&_renderDelegate); TF_VERIFY(_renderIndex != nullptr); _delegate = new UsdImagingDelegate(_renderIndex, SdfPath::AbsoluteRootPath()); _stage = usdStage; _delegate->Populate(_stage->GetPseudoRoot()); HdRprimCollection col = HdRprimCollection(collectionName, reprName); col.SetRenderTags(renderTags); _geometryPass = HdRenderPassSharedPtr(new HdSt_RenderPass(_renderIndex, col)); _renderPassState = HdRenderPassStateSharedPtr(new HdRenderPassState()); }
/* virtual */ void HdxLight::Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); TF_UNUSED(renderParam); SdfPath const &id = GetID(); if (!TF_VERIFY(sceneDelegate != nullptr)) { return; } // HdxLight communicates to the scene graph and caches all interesting // values within this class. // later on Get() is called from TaskState (RenderPass) to perform // aggregation/pre-computation, in order to make the shader execution // efficient. HdDirtyBits bits = *dirtyBits; // Change tracking // Transform if (bits & DirtyTransform) { VtValue transform = sceneDelegate->Get(id, HdxLightTokens->transform); if (transform.IsHolding<GfMatrix4d>()) { _params[HdxLightTokens->transform] = transform; } else { _params[HdxLightTokens->transform] = GfMatrix4d(1); } } // Lighting Params if (bits & DirtyParams) { _params[HdxLightTokens->params] = sceneDelegate->Get(id, HdxLightTokens->params); } // Shadow Params if (bits & DirtyShadowParams) { _params[HdxLightTokens->shadowParams] = sceneDelegate->Get(id, HdxLightTokens->shadowParams); } // Shadow Collection if (bits & DirtyCollection) { VtValue vtShadowCollection = sceneDelegate->Get(id, HdxLightTokens->shadowCollection); // Optional if (vtShadowCollection.IsHolding<HdRprimCollection>()) { HdRprimCollection newCollection = vtShadowCollection.UncheckedGet<HdRprimCollection>(); if (_params[HdxLightTokens->shadowCollection] != newCollection) { _params[HdxLightTokens->shadowCollection] = newCollection; HdChangeTracker& changeTracker = sceneDelegate->GetRenderIndex().GetChangeTracker(); changeTracker.MarkCollectionDirty(newCollection.GetName()); } } else { _params[HdxLightTokens->shadowCollection] = HdRprimCollection(); } } *dirtyBits = Clean; }
/* virtual */ void HdStLight::Sync(HdSceneDelegate *sceneDelegate, HdRenderParam *renderParam, HdDirtyBits *dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); TF_UNUSED(renderParam); SdfPath const &id = GetId(); if (!TF_VERIFY(sceneDelegate != nullptr)) { return; } // HdStLight communicates to the scene graph and caches all interesting // values within this class. Later on Get() is called from // TaskState (RenderPass) to perform aggregation/pre-computation, // in order to make the shader execution efficient. // Change tracking HdDirtyBits bits = *dirtyBits; // Transform if (bits & DirtyTransform) { VtValue transform = sceneDelegate->Get(id, HdLightTokens->transform); if (transform.IsHolding<GfMatrix4d>()) { _params[HdLightTokens->transform] = transform; } else { _params[HdLightTokens->transform] = GfMatrix4d(1); } } // Lighting Params if (bits & DirtyParams) { // If it is an area light we will extract the parameters and convert // them to a gl friendly representation. if (_lightType == HdPrimTypeTokens->simpleLight) { _params[HdLightTokens->params] = sceneDelegate->Get(id, HdLightTokens->params); } else { _params[HdLightTokens->params] = _ApproximateAreaLight(id, sceneDelegate); } } // Shadow Params if (bits & DirtyShadowParams) { _params[HdLightTokens->shadowParams] = sceneDelegate->Get(id, HdLightTokens->shadowParams); } // Shadow Collection if (bits & DirtyCollection) { VtValue vtShadowCollection = sceneDelegate->Get(id, HdLightTokens->shadowCollection); // Optional if (vtShadowCollection.IsHolding<HdRprimCollection>()) { HdRprimCollection newCollection = vtShadowCollection.UncheckedGet<HdRprimCollection>(); if (_params[HdLightTokens->shadowCollection] != newCollection) { _params[HdLightTokens->shadowCollection] = newCollection; HdChangeTracker& changeTracker = sceneDelegate->GetRenderIndex().GetChangeTracker(); changeTracker.MarkCollectionDirty(newCollection.GetName()); } } else { _params[HdLightTokens->shadowCollection] = HdRprimCollection(); } } *dirtyBits = Clean; }
static void CameraAndLightTest() { HdStRenderDelegate renderDelegate; std::unique_ptr<HdRenderIndex> index(HdRenderIndex::New(&renderDelegate)); TF_VERIFY(index); std::unique_ptr<Hdx_UnitTestDelegate> delegate( new Hdx_UnitTestDelegate(index.get())); HdChangeTracker& tracker = index->GetChangeTracker(); HdPerfLog& perfLog = HdPerfLog::GetInstance(); perfLog.Enable(); HdRprimCollection collection(HdTokens->geometry, HdTokens->hull); HdRenderPassStateSharedPtr renderPassState(new HdRenderPassState()); HdRenderPassSharedPtr renderPass( new HdSt_RenderPass(index.get(), collection)); HdEngine engine; HdTaskSharedPtr drawTask = boost::make_shared<Hd_TestTask>(renderPass, renderPassState); HdTaskSharedPtrVector tasks = { drawTask }; GfMatrix4d tx(1.0f); tx.SetRow(3, GfVec4f(5, 0, 5, 1.0)); SdfPath cube("geometry"); delegate->AddCube(cube, tx); SdfPath camera("camera"); SdfPath light("light"); delegate->AddCamera(camera); delegate->AddLight(light, GlfSimpleLight()); delegate->SetLight(light, HdStLightTokens->shadowCollection, VtValue(HdRprimCollection(HdTokens->geometry, HdTokens->hull))); engine.Execute(*index, tasks); VERIFY_PERF_COUNT(HdPerfTokens->rebuildBatches, 1); // Update camera matrix delegate->SetCamera(camera, GfMatrix4d(2), GfMatrix4d(2)); tracker.MarkSprimDirty(camera, HdStCamera::DirtyViewMatrix); tracker.MarkSprimDirty(camera, HdStCamera::DirtyProjMatrix); engine.Execute(*index, tasks); // batch should not be rebuilt VERIFY_PERF_COUNT(HdPerfTokens->rebuildBatches, 1); // Update shadow collection delegate->SetLight(light, HdStLightTokens->shadowCollection, VtValue(HdRprimCollection(HdTokens->geometry, HdTokens->refined))); tracker.MarkSprimDirty(light, HdStLight::DirtyCollection); engine.Execute(*index, tasks); // batch rebuilt VERIFY_PERF_COUNT(HdPerfTokens->rebuildBatches, 2); // Update shadow collection again with the same data delegate->SetLight(light, HdStLightTokens->shadowCollection, VtValue(HdRprimCollection(HdTokens->geometry, HdTokens->refined))); tracker.MarkSprimDirty(light, HdStLight::DirtyCollection); engine.Execute(*index, tasks); // batch should not be rebuilt VERIFY_PERF_COUNT(HdPerfTokens->rebuildBatches, 2); }
void HdxShadowTask::Sync(HdSceneDelegate* delegate, HdTaskContext* ctx, HdDirtyBits* dirtyBits) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); GLF_GROUP_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } GlfSimpleLightVector const glfLights = lightingContext->GetLights(); GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); HdRenderIndex &renderIndex = delegate->GetRenderIndex(); const bool dirtyParams = (*dirtyBits) & HdChangeTracker::DirtyParams; if (dirtyParams) { // Extract the new shadow task params from exec if (!_GetTaskParams(delegate, &_params)) { return; } } if (!renderIndex.IsSprimTypeSupported(HdPrimTypeTokens->simpleLight)) { return; } // Iterate through all lights and for those that have shadows enabled // and ensure we have enough passes to render the shadows. size_t passCount = 0; for (size_t lightId = 0; lightId < glfLights.size(); lightId++) { const HdStLight* light = static_cast<const HdStLight*>( renderIndex.GetSprim(HdPrimTypeTokens->simpleLight, glfLights[lightId].GetID())); if (!glfLights[lightId].HasShadow()) { continue; } // It is possible the light is nullptr for area lights converted to // simple lights, however they should not have shadows enabled. TF_VERIFY(light); // Extract the collection from the HD light VtValue vtShadowCollection = light->Get(HdLightTokens->shadowCollection); const HdRprimCollection &col = vtShadowCollection.IsHolding<HdRprimCollection>() ? vtShadowCollection.Get<HdRprimCollection>() : HdRprimCollection(); // Creates or reuses a pass with the right geometry that will be // used during Execute phase to draw the shadow maps. if (passCount < _passes.size()) { // Note here that we may want to sort the passes by collection // to invalidate fewer passes if the collections match already. // SetRprimCollection checks for identity changes on the collection // and no-ops in that case. _passes[passCount]->SetRprimCollection(col); } else { // Create a new pass if we didn't have enough already, HdRenderPassSharedPtr p = boost::make_shared<HdSt_RenderPass> (&renderIndex, col); _passes.push_back(p); } passCount++; } // Shrink down to fit to conserve resources // We may want hysteresis here if we find the count goes up and down // frequently. if (_passes.size() > passCount) { _passes.resize(passCount); } // Shrink down to fit to conserve resources if (_renderPassStates.size() > _passes.size()) { _renderPassStates.resize(_passes.size()); } // Ensure all passes have the right params set. if (dirtyParams) { TF_FOR_ALL(it, _renderPassStates) { _UpdateDirtyParams(*it, _params); } }
void My_TestGLDrawing::InitTest() { _renderIndex = HdRenderIndex::New(&_renderDelegate); TF_VERIFY(_renderIndex != nullptr); _delegate = new Hdx_UnitTestDelegate(_renderIndex); _delegate->SetRefineLevel(_refineLevel); // prepare render task SdfPath renderSetupTask("/renderSetupTask"); SdfPath renderTask("/renderTask"); _delegate->AddRenderSetupTask(renderSetupTask); _delegate->AddRenderTask(renderTask); // render task parameters. HdxRenderTaskParams param = _delegate->GetTaskParam( renderSetupTask, HdTokens->params).Get<HdxRenderTaskParams>(); param.enableLighting = true; // use default lighting _delegate->SetTaskParam(renderSetupTask, HdTokens->params, VtValue(param)); _delegate->SetTaskParam(renderTask, HdTokens->collection, VtValue(HdRprimCollection(HdTokens->geometry, _reprName))); // prepare scene // To ensure that the non-aggregated element index returned via picking, // we need to have at least two cubes with uniform colors. GfVec4f red(1,0,0,1), green(0,1,0,1), blue(0,0,1,1), yellow(1,1,0,1), magenta(1,0,1,1), cyan(0,1,1,1), white(1,1,1,1), black(0,0,0,1); GfVec4f faceColors[] = { red, green, blue, yellow, magenta, cyan}; VtValue faceColor = VtValue(_BuildArray(&faceColors[0], sizeof(faceColors)/sizeof(faceColors[0]))); GfVec4f vertColors[] = { white, blue, green, yellow, black, blue, magenta, red}; VtValue vertColor = VtValue(_BuildArray(&vertColors[0], sizeof(vertColors)/sizeof(vertColors[0]))); _delegate->AddCube(SdfPath("/cube0"), _GetTranslate( 5, 0, 5), /*guide=*/false, /*instancerId=*/SdfPath(), /*scheme=*/PxOsdOpenSubdivTokens->catmark, /*color=*/faceColor, /*colorInterpolation=*/Hdx_UnitTestDelegate::UNIFORM); _delegate->AddCube(SdfPath("/cube1"), _GetTranslate(-5, 0, 5), /*guide=*/false, /*instancerId=*/SdfPath(), /*scheme=*/PxOsdOpenSubdivTokens->catmark, /*color=*/faceColor, /*colorInterpolation=*/Hdx_UnitTestDelegate::UNIFORM); _delegate->AddCube(SdfPath("/cube2"), _GetTranslate(-5, 0,-5)); _delegate->AddCube(SdfPath("/cube3"), _GetTranslate( 5, 0,-5), /*guide=*/false, /*instancerId=*/SdfPath(), /*scheme=*/PxOsdOpenSubdivTokens->catmark, /*color=*/vertColor, /*colorInterpolation=*/Hdx_UnitTestDelegate::VERTEX); { _delegate->AddInstancer(SdfPath("/instancerTop")); _delegate->AddCube(SdfPath("/protoTop"), GfMatrix4d(1), false, SdfPath("/instancerTop")); std::vector<SdfPath> prototypes; prototypes.push_back(SdfPath("/protoTop")); VtVec3fArray scale(3); VtVec4fArray rotate(3); VtVec3fArray translate(3); VtIntArray prototypeIndex(3); scale[0] = GfVec3f(1); rotate[0] = GfVec4f(0); translate[0] = GfVec3f(3, 0, 2); prototypeIndex[0] = 0; scale[1] = GfVec3f(1); rotate[1] = GfVec4f(0); translate[1] = GfVec3f(0, 0, 2); prototypeIndex[1] = 0; scale[2] = GfVec3f(1); rotate[2] = GfVec4f(0); translate[2] = GfVec3f(-3, 0, 2); prototypeIndex[2] = 0; _delegate->SetInstancerProperties(SdfPath("/instancerTop"), prototypeIndex, scale, rotate, translate); } { _delegate->AddInstancer(SdfPath("/instancerBottom")); _delegate->AddCube(SdfPath("/protoBottom"), GfMatrix4d(1), false, SdfPath("/instancerBottom")); std::vector<SdfPath> prototypes; prototypes.push_back(SdfPath("/protoBottom")); VtVec3fArray scale(3); VtVec4fArray rotate(3); VtVec3fArray translate(3); VtIntArray prototypeIndex(3); scale[0] = GfVec3f(1); rotate[0] = GfVec4f(0); translate[0] = GfVec3f(3, 0, -2); prototypeIndex[0] = 0; scale[1] = GfVec3f(1); rotate[1] = GfVec4f(0); translate[1] = GfVec3f(0, 0, -2); prototypeIndex[1] = 0; scale[2] = GfVec3f(1); rotate[2] = GfVec4f(0); translate[2] = GfVec3f(-3, 0, -2); prototypeIndex[2] = 0; _delegate->SetInstancerProperties(SdfPath("/instancerBottom"), prototypeIndex, scale, rotate, translate); } SetCameraTranslate(GfVec3f(0, 0, -20)); // XXX: Setup a VAO, the current drawing engine will not yet do this. glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindVertexArray(0); }
void HdxShadowTask::_Sync(HdTaskContext* ctx) { HD_TRACE_FUNCTION(); HF_MALLOC_TAG_FUNCTION(); // Extract the lighting context information from the task context GlfSimpleLightingContextRefPtr lightingContext; if (!_GetTaskContextData(ctx, HdxTokens->lightingContext, &lightingContext)) { return; } GlfSimpleShadowArrayRefPtr const shadows = lightingContext->GetShadows(); _TaskDirtyState dirtyState; _GetTaskDirtyState(HdTokens->geometry, &dirtyState); // Check if the collection version has changed, if so, it means // that we should extract the new collections // from the lights in the render index, and then recreate the passes // required to render the shadow maps const bool collectionChanged = (_collectionVersion != dirtyState.collectionVersion); if ((dirtyState.bits & HdChangeTracker::DirtyParams) || collectionChanged) { _collectionVersion = dirtyState.collectionVersion; // Extract the new shadow task params from exec HdxShadowTaskParams params; if (!_GetSceneDelegateValue(HdTokens->params, ¶ms)) { return; } _depthBiasEnable = params.depthBiasEnable; _depthBiasConstantFactor = params.depthBiasConstantFactor; _depthBiasSlopeFactor = params.depthBiasSlopeFactor; _depthFunc = params.depthFunc; // XXX TODO: What to do about complexity? // We can now use the light information now // and create a pass for each _passes.clear(); _renderPassStates.clear(); HdSceneDelegate* delegate = GetDelegate(); const HdRenderIndex &renderIndex = delegate->GetRenderIndex(); // Extract the HD lights used to render the scene from the // task context, we will use them to find out what // lights are dirty and if we need to update the // collection for shadows mapping // XXX: This is inefficient, need to be optimized SdfPathVector sprimPaths = renderIndex.GetSprimSubtree( HdPrimTypeTokens->light, SdfPath::AbsoluteRootPath()); SdfPathVector lightPaths = HdxSimpleLightTask::ComputeIncludedLights( sprimPaths, params.lightIncludePaths, params.lightExcludePaths); HdxLightPtrConstVector lights; TF_FOR_ALL (it, lightPaths) { const HdxLight *light = static_cast<const HdxLight *>( renderIndex.GetSprim( HdPrimTypeTokens->light, *it)); if (light != nullptr) { lights.push_back(light); } } GlfSimpleLightVector const glfLights = lightingContext->GetLights(); TF_VERIFY(lights.size() == glfLights.size()); // Iterate through all lights and for those that have // shadows enabled we will extract the colection from // the render index and create a pass that during execution // it will be used for generating each shadowmap for (size_t lightId = 0; lightId < glfLights.size(); lightId++) { if (!glfLights[lightId].HasShadow()) { continue; } // Extract the collection from the HD light VtValue vtShadowCollection = lights[lightId]->Get(HdxLightTokens->shadowCollection); const HdRprimCollection &col = vtShadowCollection.IsHolding<HdRprimCollection>() ? vtShadowCollection.Get<HdRprimCollection>() : HdRprimCollection(); // Creates a pass with the right geometry that will be // use during Execute phase to draw the maps HdRenderPassSharedPtr p = boost::make_shared<HdRenderPass> (&delegate->GetRenderIndex(), col); HdRenderPassShaderSharedPtr renderPassShadowShader (new HdRenderPassShader(HdxPackageRenderPassShadowShader())); HdRenderPassStateSharedPtr renderPassState (new HdRenderPassState(renderPassShadowShader)); // Update the rest of the renderpass state parameters for this pass renderPassState->SetOverrideColor(params.overrideColor); renderPassState->SetWireframeColor(params.wireframeColor); renderPassState->SetLightingEnabled(false); // XXX : This can be removed when Hydra has support for // transparent objects. renderPassState->SetAlphaThreshold(1.0 /* params.alphaThreshold */); renderPassState->SetTessLevel(params.tessLevel); renderPassState->SetDrawingRange(params.drawingRange); renderPassState->SetCullStyle(params.cullStyle); _passes.push_back(p); _renderPassStates.push_back(renderPassState); } }
void My_TestGLDrawing::InitTest() { _renderIndex = HdRenderIndex::New(&_renderDelegate); TF_VERIFY(_renderIndex != nullptr); _delegate = new Hdx_UnitTestDelegate(_renderIndex); _delegate->SetRefineLevel(_refineLevel); // prepare render task SdfPath renderSetupTask("/renderSetupTask"); SdfPath renderTask("/renderTask"); _delegate->AddRenderSetupTask(renderSetupTask); _delegate->AddRenderTask(renderTask); // render task parameters. HdxRenderTaskParams param = _delegate->GetTaskParam( renderSetupTask, HdTokens->params).Get<HdxRenderTaskParams>(); param.enableLighting = true; // use default lighting _delegate->SetTaskParam(renderSetupTask, HdTokens->params, VtValue(param)); _delegate->SetTaskParam(renderTask, HdTokens->collection, VtValue(HdRprimCollection(HdTokens->geometry, _reprName))); // prepare scene _delegate->AddCube(SdfPath("/cube0"), _GetTranslate( 5, 0, 5)); _delegate->AddCube(SdfPath("/cube1"), _GetTranslate(-5, 0, 5)); _delegate->AddCube(SdfPath("/cube2"), _GetTranslate(-5, 0,-5)); _delegate->AddCube(SdfPath("/cube3"), _GetTranslate( 5, 0,-5)); { _delegate->AddInstancer(SdfPath("/instancerTop")); _delegate->AddCube(SdfPath("/protoTop"), GfMatrix4d(1), false, SdfPath("/instancerTop")); std::vector<SdfPath> prototypes; prototypes.push_back(SdfPath("/protoTop")); VtVec3fArray scale(3); VtVec4fArray rotate(3); VtVec3fArray translate(3); VtIntArray prototypeIndex(3); scale[0] = GfVec3f(1); rotate[0] = GfVec4f(0); translate[0] = GfVec3f(3, 0, 2); prototypeIndex[0] = 0; scale[1] = GfVec3f(1); rotate[1] = GfVec4f(0); translate[1] = GfVec3f(0, 0, 2); prototypeIndex[1] = 0; scale[2] = GfVec3f(1); rotate[2] = GfVec4f(0); translate[2] = GfVec3f(-3, 0, 2); prototypeIndex[2] = 0; _delegate->SetInstancerProperties(SdfPath("/instancerTop"), prototypeIndex, scale, rotate, translate); } { _delegate->AddInstancer(SdfPath("/instancerBottom")); _delegate->AddCube(SdfPath("/protoBottom"), GfMatrix4d(1), false, SdfPath("/instancerBottom")); std::vector<SdfPath> prototypes; prototypes.push_back(SdfPath("/protoBottom")); VtVec3fArray scale(3); VtVec4fArray rotate(3); VtVec3fArray translate(3); VtIntArray prototypeIndex(3); scale[0] = GfVec3f(1); rotate[0] = GfVec4f(0); translate[0] = GfVec3f(3, 0, -2); prototypeIndex[0] = 0; scale[1] = GfVec3f(1); rotate[1] = GfVec4f(0); translate[1] = GfVec3f(0, 0, -2); prototypeIndex[1] = 0; scale[2] = GfVec3f(1); rotate[2] = GfVec4f(0); translate[2] = GfVec3f(-3, 0, -2); prototypeIndex[2] = 0; _delegate->SetInstancerProperties(SdfPath("/instancerBottom"), prototypeIndex, scale, rotate, translate); } SetCameraTranslate(GfVec3f(0, 0, -20)); // XXX: Setup a VAO, the current drawing engine will not yet do this. glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindVertexArray(0); }