# vtkScalarBarActor in WebAssembly

**URL:** https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078
**Category:** Web
**Created:** [January 28, 2021, 4:29pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078 "2021-01-28T16:29:29Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [January 28, 2021, 4:29pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/1 "2021-01-28T16:29:30Z")

</div>

I am having an issue using vtkScalarBarActor in WebAssembly. The code works correctly in C++ desktop VTK, but I get the following error when running it in WebAssembly in a browser:

> WebGL: INVALID\_ENUM: texParameter: invalid texture target

Here is the code:

```
vtkSmartPointer<vtkLookupTable> lookuptable = vtkSmartPointer<vtkLookupTable>::New();

lookuptable->SetNumberOfTableValues(256);
lookuptable->SetTableRange(minlev, maxlev);
lookuptable->SetRampToLinear();
lookuptable->SetScaleToLinear();
lookuptable->GlobalWarningDisplayOff();
lookuptable->Build();

int annotind = 0;

for (int tblid = 0; tblid < cols.size(); tblid++)
{
	// Set the ref bin colors

	double r, g, b, a;

	r = cols[tblid].r / 255.0;
	g = cols[tblid].g / 255.0;
	b = cols[tblid].b / 255.0;
	a = cols[tblid].a / 255.0;
	
	lookuptable->SetTableValue(tblid, r, g, b, a);
	
}

vtkSmartPointer<vtkScalarBarActor> scalarBar = vtkSmartPointer<vtkScalarBarActor>::New();
scalarBar->SetMaximumNumberOfColors(256);
scalarBar->SetLookupTable(lookuptable);
scalarBar->SetHeight(0.05);
scalarBar->SetWidth(1.0);
scalarBar->GetPositionCoordinate()->SetValue(0, 0);
scalarBar->GetPosition2Coordinate()->SetValue(1.0, .10);
scalarBar->SetOrientationToHorizontal();
scalarBar->SetNumberOfLabels(20);
scalarBar->SetLabelFormat("%.0f");
scalarBar->SetMaximumWidthInPixels(1000);
scalarBar->SetMaximumHeightInPixels(60);
scalarBar->SetTitle("Units: dBZ");
scalarBar->VisibilityOn();

m_renderer->AddActor(scalarBar);

```

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [January 28, 2021, 4:49pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/2 "2021-01-28T16:49:31Z")

</div>

@ken-martin

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [January 28, 2021, 8:43pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/3 "2021-01-28T20:43:22Z")

</div>

I am trying to debug the issue and it appears vtkScalarBarActor is calling bindTexture with a target value of 0. All of the other calls to this function from my program are passing a value of 3553 (gl.TEXTURE\_2D) for a target.

---

<div class="post-metadata">

### Author: ![Tom\_Boltman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tom_boltman/32/2920_2.png) [@Tom\_Boltman](https://discourse.vtk.org/u/Tom_Boltman)
#### Post date: [January 29, 2021, 4:07pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/6 "2021-01-29T16:07:47Z")

</div>

I have done. Sorry

---

<div class="post-metadata">

### Author: ![Tom\_Boltman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tom_boltman/32/2920_2.png) [@Tom\_Boltman](https://discourse.vtk.org/u/Tom_Boltman)
#### Post date: [January 29, 2021, 4:21pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/8 "2021-01-29T16:21:04Z")

</div>

If it’s okay. I want to share my project with you.  
It’s for implementing vtk features to React js project.  
Are you interested?

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [January 29, 2021, 4:23pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/9 "2021-01-29T16:23:20Z")

</div>

@ken-martin Here is a screenshot of the breakpoint and the values of the parameters to bindTexture:

![image](https://discourse.vtk.org/uploads/default/original/2X/f/fcaa4142eeb4cfe3b519f593f3588bb50a2a16a5.png)

Here is the stack trace at that breakpoint:

> \_glBindTexture (SwisRadar.js:10994)  
> \_\_ZN16vtkTextureObject8ActivateEv (SwisRadar.wasm:0xa5654)  
> \_\_ZN25vtkOpenGLPolyDataMapper2D13RenderOverlayEP11vtkViewportP10vtkActor2D (SwisRadar.wasm:0x69c73)  
> \_\_ZN10vtkActor2D13RenderOverlayEP11vtkViewport (SwisRadar.wasm:0x127ecc)  
> \_\_ZN17vtkScalarBarActor13RenderOverlayEP11vtkViewport (SwisRadar.wasm:0xc2ea1)  
> \_\_ZN17vtkOpenGLRenderer14UpdateGeometryEP24vtkFrameBufferObjectBase (SwisRadar.wasm:0x7a93c)  
> \_\_ZN17vtkOpenGLRenderer12DeviceRenderEv (SwisRadar.wasm:0x7818f)  
> \_\_ZN11vtkRenderer6RenderEv (SwisRadar.wasm:0x153fdc)  
> \_\_ZN21vtkRendererCollection6RenderEv (SwisRadar.wasm:0x156e82)  
> \_\_ZN15vtkRenderWindow14DoStereoRenderEv (SwisRadar.wasm:0x14f1cf)  
> \_\_ZN15vtkRenderWindow6RenderEv (SwisRadar.wasm:0x14e7dd)  
> \_\_ZN21vtkOpenGLRenderWindow6RenderEv (SwisRadar.wasm:0x7303c)  
> \_\_ZN25vtkRenderWindowInteractor6RenderEv (SwisRadar.wasm:0x1504b2)  
> \_\_ZN18SwisVtkRadarWindow6renderEv (SwisRadar.wasm:0x17477)  
> \_\_ZN18SwisVtkRadarWindow11GotoNextCueEv (SwisRadar.wasm:0x180db)  
> \_\_ZN18SwisVtkRadarWindow15DownloadSuccessENSt3\_\_26vectorIcNS0\_9allocatorIcEEEEi (SwisRadar.wasm:0x17f27)  
> \_\_Z17downloadSucceededP18emscripten\_fetch\_t (SwisRadar.wasm:0x165ba)  
> dynCall\_vi (SwisRadar.wasm:0x540be3)  
> Module.dynCall\_vi (SwisRadar.js:13437)  
> reportSuccess (SwisRadar.js:10865)  
> xhr.onload (SwisRadar.js:10670)  
> load (async)  
> \_\_emscripten\_fetch\_xhr (SwisRadar.js:10642)  
> performUncachedXhr (SwisRadar.js:10885)  
> getRequest.onsuccess (SwisRadar.js:10793)  
> IndexedDB (async)  
> \_\_emscripten\_fetch\_load\_cached\_data (SwisRadar.js:10771)  
> \_emscripten\_start\_fetch (SwisRadar.js:10911)  
> \_emscripten\_fetch (SwisRadar.wasm:0x51f22d)  
> \_\_ZN18SwisVtkRadarWindow10AddProductENSt3\_\_212basic\_stringIcNS0\_11char\_traitsIcEENS0\_9allocatorIcEEEEi (SwisRadar.wasm:0x1814d)  
> \_addRadarCue (SwisRadar.wasm:0x15612)  
> Module.\_addRadarCue (SwisRadar.js:12819)  
> ccall (SwisRadar.js:795)  
> (anonymous) (SwisRadar.js:814)  
> DequeRadar1 (SwisRadarPage.js:247)  
> setTimeout (async)  
> success (SwisRadarPage.js:174)  
> c (jquery.min.js:2)  
> fireWith (jquery.min.js:2)  
> l (jquery.min.js:2)  
> (anonymous) (jquery.min.js:2)  
> load (async)  
> send (jquery.min.js:2)  
> ajax (jquery.min.js:2)  
> createRadar1 (SwisRadarPage.js:151)  
> createRadar (SwisRadarPage.js:130)  
> createScene (SwisRadarPage.js:111)  
> onclick (SwisRadar.aspx:89)

---

<div class="post-metadata">

### Author: ![Tom\_Boltman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tom_boltman/32/2920_2.png) [@Tom\_Boltman](https://discourse.vtk.org/u/Tom_Boltman)
#### Post date: [January 29, 2021, 4:43pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/11 "2021-01-29T16:43:29Z")

</div>

@Donny_Zimmerman  
No problem. Thanks anyway.

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [January 29, 2021, 9:54pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/12 "2021-01-29T21:54:14Z")

</div>

Here is the PrintSelf of the vtkTextureObject that is failing:

> WrapS: Repeat  
> WrapT: Repeat  
> WrapR: Repeat  
> MinificationFilter: Nearest  
> MagnificationFilter: Nearest  
> MinLOD: -1000  
> MaxLOD: 1000  
> BaseLevel: 0  
> MaxLevel: 0  
> DepthTextureCompare: 0  
> DepthTextureCompareFunction: Lequal  
> GenerateMipmap: 0  
> Debug: Off  
> Modified Time: 239314  
> Reference Count: 1  
> Registered Events: (none)  
> Width: 0  
> Height: 0  
> Depth: 0  
> Components: 0  
> Handle: 0  
> Target: unknown value: 0x0  
> NumberOfDimensions: 0  
> Format: 0  
> InternalFormat: 0  
> Type: 0

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [January 29, 2021, 10:13pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/13 "2021-01-29T22:13:49Z")

</div>

Here is the vtkOpenGLPolyDataMapper2D PrintSelf:

> Debug: Off  
> Modified Time: 78110  
> Reference Count: 3  
> Registered Events: (none)  
> Executive: 0x1d30ce8  
> ErrorCode: No error information  
> Information: 0x1d30050  
> AbortExecute: Off  
> Progress: 0  
> Progress Text: (None)  
> TimeToDraw: 0  
> ClippingPlanes: (none)  
> Lookup Table:  
> Debug: Off  
> Modified Time: 78110  
> Reference Count: 1  
> Registered Events: (none)  
> Alpha: 1  
> VectorMode: Component  
> VectorComponent: 0  
> VectorSize: -1  
> IndexedLookup: OFF  
> AnnotatedValues: 0 entries.  
> TableRange: (0, 1)  
> Scale: Linear  
> HueRange: (0, 0.66667)  
> SaturationRange: (1, 1)  
> ValueRange: (1, 1)  
> AlphaRange: (1, 1)  
> NanColor: (0.5, 0, 0, 1)  
> BelowRangeColor: (0, 0, 0, 1)  
> UseBelowRangeColor: OFF  
> AboveRangeColor: (1, 1, 1, 1)  
> UseAboveRangeColor: OFF  
> NumberOfTableValues: 256  
> NumberOfColors: 256  
> Ramp: SCurve  
> InsertTime: 0  
> BuildTime: 78115  
> Table:  
> Debug: Off  
> Modified Time: 78113  
> Reference Count: 1  
> Registered Events: (none)  
> Name: (none)  
> Data type: unsigned char  
> Size: 1040  
> MaxId: 1023  
> NumberOfComponents: 4  
> Information: 0  
> Name: (none)  
> Number Of Components: 4  
> Number Of Tuples: 256  
> Size: 1040  
> MaxId: 1023  
> LookupTable: (none)  
> Scalar Visibility: On  
> Scalar Mode: Default  
> Scalar Range: (0, 1)  
> UseLookupTableScalarRange: 0  
> Color Mode: Default  
> No Transform Coordinate  
> Transform Coordinate use double: False

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [February 3, 2021, 5:34pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/14 "2021-02-03T17:34:16Z")

</div>

@ken-martin

I think the issue is because TextureBuffers are not supported in OpenGL ES.

Here is the VTK code for vtkTextureObject starting at line 1126. There is an #ifdef checking for ES on line 898:

> // Description:  
> // Create a texture buffer basically a 1D texture that can be  
> // very large for passing data into the fragment shader  
> bool vtkTextureObject::CreateTextureBuffer(  
> unsigned int numValues, int numComps, int dataType, vtkOpenGLBufferObject\* bo)  
> {  
> assert(this-\>Context);  
> vtkErrorMacro(“TextureBuffers not supported in OpenGL ES”);  
> // TODO: implement 1D and Texture buffers using 2D textures  
> return false;  
> }
> 
> #endif // not ES 2.0 or 3.0

I have no idea how to implement the TODO as mentioned in the above code. Any idea when this will be implemented or a workaround?

Thanks!

---

<div class="post-metadata">

### Author: ![ken-martin](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ken-martin/32/884_2.png) [@ken-martin](https://discourse.vtk.org/u/ken-martin)
#### Post date: [February 3, 2021, 5:43pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/15 "2021-02-03T17:43:31Z")

</div>

I know of no plans to implement it in the future, we will eventually move away from OpenGL so at some point it will be legacy. But if someone implements it I’d be happy to review the topic etc. of course.

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [February 3, 2021, 5:58pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/16 "2021-02-03T17:58:56Z")

</div>

Thanks @ken-martin . Is it a requirement for the vtkScalarActor to use textures. I was thinking it could just use geometry and shading to accomplish rendering. I will dig a little deeper to see if I can disable using textures for this actor. I am using the vtkLegendBoxActor in the same project and it is rendering correctly so I would think a scalar bar could be implemented.

If you are moving away from OpenGL, what will the new backend be using? Does this mean using VTK in WebAssembly will not be possible?

Thanks!

---

<div class="post-metadata">

### Author: ![ken-martin](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ken-martin/32/884_2.png) [@ken-martin](https://discourse.vtk.org/u/ken-martin)
#### Post date: [February 3, 2021, 6:02pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/17 "2021-02-03T18:02:09Z")

</div>

We are thinking vulkan or Dawn. If we go with Dawn then web assembly should work as I believe dawn converts properly.

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [February 3, 2021, 10:41pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/18 "2021-02-03T22:41:54Z")

</div>

I solved my immediate issue by modifying the vtkScalarBarActor code by setting point scalars instead of cell scalars on the scalar bar polydata object. This works in this instance, but anytime you use a vtkPolyDataActor2D with cell scalars it will fail when using WebAssembly. Hope this helps someone else in the future. I am just not good enough to re-implement texture buffers in OpenGL ES.

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [February 12, 2021, 3:59pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/19 "2021-02-12T15:59:42Z")

</div>

If everyone agrees, can someone push the following changes to the vtkScalarBarActor source code. I just did #ifndef GL\_ES\_VERSION\_3\_0 checks so it will work with WebAssembly. I just don’t have the setup to push changes right now. The only change is in the function ConfigureScalarBar. Below is the complete code for that function.

> void vtkScalarBarActor::ConfigureScalarBar()  
> {  
> vtkScalarsToColors\* lut = this-\>LookupTable;  
> const double\* range = lut-\>GetRange();  
> this-\>P-\>NumColors =  
> lut-\>GetIndexedLookup() ? lut-\>GetNumberOfAnnotatedValues() : this-\>MaximumNumberOfColors;  
> this-\>P-\>NumSwatches = this-\>P-\>NumColors + (this-\>DrawNanAnnotation ? 1 : 0);  
> int numPts = 2 \* (this-\>P-\>NumColors + 1) + (this-\>DrawNanAnnotation ? 4 : 0);
> 
> this-\>P-\>NumSwatches = this-\>P-\>NumColors + (this-\>DrawBelowRangeSwatch ? 1 : 0);  
> numPts += (this-\>DrawBelowRangeSwatch ? 4 : 0);
> 
> this-\>P-\>SwatchPts = vtkPoints::New();  
> this-\>P-\>SwatchPts-\>SetNumberOfPoints(numPts);  
> this-\>P-\>Polys = vtkCellArray::New();  
> this-\>P-\>Polys-\>AllocateEstimate(this-\>P-\>NumSwatches, 4);  
> this-\>P-\>SwatchColors = vtkUnsignedCharArray::New();
> 
> unsigned int nComponents = ((this-\>UseOpacity) ? 4 : 3);  
> this-\>P-\>SwatchColors-\>SetNumberOfComponents(nComponents);
> 
> // 1D textures are not supported in ES 2.0 or 3.0  
> #ifndef GL\_ES\_VERSION\_3\_0  
> this-\>P-\>SwatchColors-\>SetNumberOfTuples(this-\>P-\>NumSwatches);  
> #else  
> this-\>P-\>SwatchColors-\>SetNumberOfTuples(numPts);  
> #endif
> 
> this-\>ScalarBarActor-\>SetProperty(this-\>GetProperty());  
> this-\>ScalarBar-\>Initialize();  
> this-\>ScalarBar-\>SetPoints(this-\>P-\>SwatchPts);  
> this-\>ScalarBar-\>SetPolys(this-\>P-\>Polys);
> 
> // 1D textures are not supported in ES 2.0 or 3.0  
> #ifndef GL\_ES\_VERSION\_3\_0   
> this-\>ScalarBar-\>GetCellData()-\>SetScalars(this-\>P-\>SwatchColors);   
> #else  
> this-\>ScalarBar-\>GetPointData()-\>SetScalars(this-\>P-\>SwatchColors);  
> #endif
> 
> this-\>P-\>SwatchPts-\>Delete();  
> this-\>P-\>Polys-\>Delete();  
> this-\>P-\>SwatchColors-\>Delete();
> 
> double delta = static\_cast(this-\>P-\>ScalarBarBox.Size[1]) / this-\>P-\>NumColors;  
> double x[3];  
> x[2] = 0.;  
> for (int i = 0; i \< numPts / 2 - (this-\>DrawNanAnnotation ? 2 : 0) - (this-\>DrawBelowRangeSwatch ? 2 : 0); ++i)  
> {  
> x[this-\>P-\>TL[0]] = this-\>P-\>ScalarBarBox.Posn[this-\>P-\>TL[0]];  
> x[this-\>P-\>TL[1]] = this-\>P-\>ScalarBarBox.Posn[this-\>P-\>TL[1]] + i \* delta;  
> this-\>P-\>SwatchPts-\>SetPoint(2 \* i, x);
> 
> ```
> x[this->P->TL[0]] = this->P->ScalarBarBox.Posn[this->P->TL[0]] + this->P->ScalarBarBox.Size[0];
> this->P->SwatchPts->SetPoint(2 * i + 1, x);
> 
> ```
> 
> }
> 
> // polygons & cell colors  
> unsigned char\* rgb;  
> double rgba[4];  
> vtkIdType ptIds[4];  
> for (int i = 0; i \< this-\>P-\>NumColors; ++i)  
> {  
> ptIds[0] = 2 \* i;  
> ptIds[1] = ptIds[0] + 1;  
> ptIds[2] = ptIds[1] + 2;  
> ptIds[3] = ptIds[0] + 2;  
> this-\>P-\>Polys-\>InsertNextCell(4, ptIds);
> 
> ```
> double rgbval;
> if (this->LookupTable->UsingLogScale())
> {
> rgbval = log10(range[0]) + i * (log10(range[1]) - log10(range[0])) / this->P->NumColors;
> rgbval = pow(10.0, rgbval);
> }
> else
> {
> rgbval = range[0] + (range[1] - range[0]) * (i / static_cast<double>(this->P->NumColors));
> }
> lut->GetColor(rgbval, rgba);
> rgba[3] = lut->GetOpacity(rgbval);
> 
> // write into array directly
> 
> ```
> 
> // 1D textures are not supported in ES 2.0 or 3.0  
> #ifndef GL\_ES\_VERSION\_3\_0  
> rgb = this-\>P-\>SwatchColors-\>GetPointer(nComponents \* i);  
> rgb[0] = static\_cast(rgba[0] \* 255.);  
> rgb[1] = static\_cast(rgba[1] \* 255.);  
> rgb[2] = static\_cast(rgba[2] \* 255.);  
> if (this-\>P-\>SwatchColors-\>GetNumberOfComponents() \> 3)  
> {  
> rgb[3] = static\_cast(this-\>UseOpacity ? rgba[3] \* 255. : 255.);  
> }
> 
> #else
> 
> ```
> rgb = this->P->SwatchColors->GetPointer(nComponents * (i * 2));
> rgb[0] = static_cast<unsigned char>(rgba[0] * 255.);
> rgb[1] = static_cast<unsigned char>(rgba[1] * 255.);
> rgb[2] = static_cast<unsigned char>(rgba[2] * 255.);
> if (this->P->SwatchColors->GetNumberOfComponents() > 3)
> {
> rgb[3] = static_cast<unsigned char>(this->UseOpacity ? rgba[3] * 255. : 255.);
> }
> 
> rgb = this->P->SwatchColors->GetPointer(nComponents * (i * 2 + 1));
> rgb[0] = static_cast<unsigned char>(rgba[0] * 255.);
> rgb[1] = static_cast<unsigned char>(rgba[1] * 255.);
> rgb[2] = static_cast<unsigned char>(rgba[2] * 255.);
> if (this->P->SwatchColors->GetNumberOfComponents() > 3)
> {
> rgb[3] = static_cast<unsigned char>(this->UseOpacity ? rgba[3] * 255. : 255.);
> }
> 
> ```
> 
> #endif
> 
> }
> 
> // Set up a texture actor as an alternative to the 1-quad-per-color  
> // scalar bar polydata.  
> vtkPoints\* texturePoints = vtkPoints::New();  
> texturePoints-\>SetNumberOfPoints(4);  
> this-\>TexturePolyData-\>SetPoints(texturePoints);  
> texturePoints-\>SetPoint(0, 0.0, 0.0, 0.0);
> 
> double p1[2], p2[2];  
> p1[0] = this-\>P-\>ScalarBarBox.Posn[0];  
> p1[1] = this-\>P-\>ScalarBarBox.Posn[1];  
> p2[0] = p1[0] + this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[0]];  
> p2[1] = p1[1] + this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[1]];
> 
> texturePoints-\>SetPoint(0, p1[0], p1[1], 0.0);  
> texturePoints-\>SetPoint(1, p2[0], p1[1], 0.0);  
> texturePoints-\>SetPoint(2, p2[0], p2[1], 0.0);  
> texturePoints-\>SetPoint(3, p1[0], p2[1], 0.0);  
> texturePoints-\>Delete();
> 
> double barWidth = this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[0]];  
> double barHeight = this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[1]];  
> vtkDataArray\* tc = this-\>TexturePolyData-\>GetPointData()-\>GetTCoords();  
> tc-\>SetTuple2(1, barWidth / this-\>TextureGridWidth, 0.0);  
> tc-\>SetTuple2(2, barWidth / this-\>TextureGridWidth, barHeight / this-\>TextureGridWidth);  
> tc-\>SetTuple2(3, 0.0, barHeight / this-\>TextureGridWidth);  
> }

Thanks!

---

<div class="post-metadata">

### Author: ![ken-martin](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ken-martin/32/884_2.png) [@ken-martin](https://discourse.vtk.org/u/ken-martin)
#### Post date: [February 23, 2021, 2:18pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/20 "2021-02-23T14:18:21Z")

</div>

Hmm, the trick is that class is not part of any of the OpenGL libraries in VTK. It is a API generic class. So I’m not sure how it will get the value of the definition. It must be working for you somehow but I’m not seeing where it could get that definition. Normally it is provided by gl.h but that is not included here.

So what I am thinking is that the way to do this is to add an ivar like UsePointData, that defaults to false but can be turned on. For your code you would set it to true and then it would use your new code paths. Does that work for you?

---

<div class="post-metadata">

### Author: ![Donny\_Zimmerman](https://discourse.vtk.org/user_avatar/discourse.vtk.org/donny_zimmerman/32/301_2.png) [@Donny\_Zimmerman](https://discourse.vtk.org/u/Donny_Zimmerman)
#### Post date: [February 23, 2021, 3:06pm UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/21 "2021-02-23T15:06:52Z")

</div>

@ken-martin That is funny because that is exactly how I got my code to work. I just thought maybe I should stick with the same #defines used in the vtkTextureObject. Below is the function as I used it:

> void vtkScalarBarActor::ConfigureScalarBar()  
> {  
> vtkScalarsToColors\* lut = this-\>LookupTable;  
> const double\* range = lut-\>GetRange();  
> this-\>P-\>NumColors =  
> lut-\>GetIndexedLookup() ? lut-\>GetNumberOfAnnotatedValues() : this-\>MaximumNumberOfColors;  
> this-\>P-\>NumSwatches = this-\>P-\>NumColors + (this-\>DrawNanAnnotation ? 1 : 0);  
> int numPts = 2 \* (this-\>P-\>NumColors + 1) + (this-\>DrawNanAnnotation ? 4 : 0);
> 
> this-\>P-\>NumSwatches = this-\>P-\>NumColors + (this-\>DrawBelowRangeSwatch ? 1 : 0);  
> numPts += (this-\>DrawBelowRangeSwatch ? 4 : 0);
> 
> this-\>P-\>SwatchPts = vtkPoints::New();  
> this-\>P-\>SwatchPts-\>SetNumberOfPoints(numPts);  
> this-\>P-\>Polys = vtkCellArray::New();  
> this-\>P-\>Polys-\>AllocateEstimate(this-\>P-\>NumSwatches, 4);  
> this-\>P-\>SwatchColors = vtkUnsignedCharArray::New();
> 
> unsigned int nComponents = ((this-\>UseOpacity) ? 4 : 3);  
> this-\>P-\>SwatchColors-\>SetNumberOfComponents(nComponents);  
> if (!this-\>UseColorBarPointScalars)  
> {  
> this-\>P-\>SwatchColors-\>SetNumberOfTuples(this-\>P-\>NumSwatches);  
> }  
> else  
> {  
> this-\>P-\>SwatchColors-\>SetNumberOfTuples(numPts);  
> }
> 
> this-\>ScalarBarActor-\>SetProperty(this-\>GetProperty());  
> this-\>ScalarBar-\>Initialize();  
> this-\>ScalarBar-\>SetPoints(this-\>P-\>SwatchPts);  
> this-\>ScalarBar-\>SetPolys(this-\>P-\>Polys);  
> if (!this-\>UseColorBarPointScalars)  
> {  
> this-\>ScalarBar-\>GetCellData()-\>SetScalars(this-\>P-\>SwatchColors);  
> }  
> else  
> {  
> this-\>ScalarBar-\>GetPointData()-\>SetScalars(this-\>P-\>SwatchColors);  
> }  
> this-\>P-\>SwatchPts-\>Delete();  
> this-\>P-\>Polys-\>Delete();  
> this-\>P-\>SwatchColors-\>Delete();
> 
> double delta = static\_cast(this-\>P-\>ScalarBarBox.Size[1]) / this-\>P-\>NumColors;  
> double x[3];  
> x[2] = 0.;  
> for (int i = 0; i \< numPts / 2 - (this-\>DrawNanAnnotation ? 2 : 0) - (this-\>DrawBelowRangeSwatch ? 2 : 0); ++i)  
> {  
> x[this-\>P-\>TL[0]] = this-\>P-\>ScalarBarBox.Posn[this-\>P-\>TL[0]];  
> x[this-\>P-\>TL[1]] = this-\>P-\>ScalarBarBox.Posn[this-\>P-\>TL[1]] + i \* delta;  
> this-\>P-\>SwatchPts-\>SetPoint(2 \* i, x);
> 
> ```
> x[this->P->TL[0]] = this->P->ScalarBarBox.Posn[this->P->TL[0]] + this->P->ScalarBarBox.Size[0];
> this->P->SwatchPts->SetPoint(2 * i + 1, x);
> 
> ```
> 
> }
> 
> // polygons & cell colors  
> unsigned char\* rgb;  
> double rgba[4];  
> vtkIdType ptIds[4];  
> for (int i = 0; i \< this-\>P-\>NumColors; ++i)  
> {  
> ptIds[0] = 2 \* i;  
> ptIds[1] = ptIds[0] + 1;  
> ptIds[2] = ptIds[1] + 2;  
> ptIds[3] = ptIds[0] + 2;  
> this-\>P-\>Polys-\>InsertNextCell(4, ptIds);
> 
> ```
> double rgbval;
> if (this->LookupTable->UsingLogScale())
> {
> rgbval = log10(range[0]) + i * (log10(range[1]) - log10(range[0])) / this->P->NumColors;
> rgbval = pow(10.0, rgbval);
> }
> else
> {
> rgbval = range[0] + (range[1] - range[0]) * (i / static_cast<double>(this->P->NumColors));
> }
> lut->GetColor(rgbval, rgba);
> rgba[3] = lut->GetOpacity(rgbval);
> 
> // write into array directly
> 
> ```
> 
> if (!this-\>UseColorBarPointScalars)  
> {  
> rgb = this-\>P-\>SwatchColors-\>GetPointer(nComponents \* i);  
> rgb[0] = static\_cast(rgba[0] \* 255.);  
> rgb[1] = static\_cast(rgba[1] \* 255.);  
> rgb[2] = static\_cast(rgba[2] \* 255.);  
> if (this-\>P-\>SwatchColors-\>GetNumberOfComponents() \> 3)  
> {  
> rgb[3] = static\_cast(this-\>UseOpacity ? rgba[3] \* 255. : 255.);  
> }  
> }  
> else  
> {
> 
> ```
> rgb = this->P->SwatchColors->GetPointer(nComponents * (i * 2));
> rgb[0] = static_cast<unsigned char>(rgba[0] * 255.);
> rgb[1] = static_cast<unsigned char>(rgba[1] * 255.);
> rgb[2] = static_cast<unsigned char>(rgba[2] * 255.);
> if (this->P->SwatchColors->GetNumberOfComponents() > 3)
> {
> rgb[3] = static_cast<unsigned char>(this->UseOpacity ? rgba[3] * 255. : 255.);
> }
> 
> rgb = this->P->SwatchColors->GetPointer(nComponents * (i * 2 + 1));
> rgb[0] = static_cast<unsigned char>(rgba[0] * 255.);
> rgb[1] = static_cast<unsigned char>(rgba[1] * 255.);
> rgb[2] = static_cast<unsigned char>(rgba[2] * 255.);
> if (this->P->SwatchColors->GetNumberOfComponents() > 3)
> {
> rgb[3] = static_cast<unsigned char>(this->UseOpacity ? rgba[3] * 255. : 255.);
> }
> 
> ```
> 
> }
> 
> }
> 
> // Set up a texture actor as an alternative to the 1-quad-per-color  
> // scalar bar polydata.  
> vtkPoints\* texturePoints = vtkPoints::New();  
> texturePoints-\>SetNumberOfPoints(4);  
> this-\>TexturePolyData-\>SetPoints(texturePoints);  
> texturePoints-\>SetPoint(0, 0.0, 0.0, 0.0);
> 
> double p1[2], p2[2];  
> p1[0] = this-\>P-\>ScalarBarBox.Posn[0];  
> p1[1] = this-\>P-\>ScalarBarBox.Posn[1];  
> p2[0] = p1[0] + this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[0]];  
> p2[1] = p1[1] + this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[1]];
> 
> texturePoints-\>SetPoint(0, p1[0], p1[1], 0.0);  
> texturePoints-\>SetPoint(1, p2[0], p1[1], 0.0);  
> texturePoints-\>SetPoint(2, p2[0], p2[1], 0.0);  
> texturePoints-\>SetPoint(3, p1[0], p2[1], 0.0);  
> texturePoints-\>Delete();
> 
> double barWidth = this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[0]];  
> double barHeight = this-\>P-\>ScalarBarBox.Size[this-\>P-\>TL[1]];  
> vtkDataArray\* tc = this-\>TexturePolyData-\>GetPointData()-\>GetTCoords();  
> tc-\>SetTuple2(1, barWidth / this-\>TextureGridWidth, 0.0);  
> tc-\>SetTuple2(2, barWidth / this-\>TextureGridWidth, barHeight / this-\>TextureGridWidth);  
> tc-\>SetTuple2(3, 0.0, barHeight / this-\>TextureGridWidth);  
> }

Here is what I added to the header file:

> //@{  
> /\*\*
> 
> - Set to true to use point scalars on the scalar bar polydata.
> - If set to false the scalar bar polydata will use cell scalars.
> - For use in WebGL and OPENGL ES this must be set to true.
> - [Default: off]  
> \*/  
> vtkSetMacro(UseColorBarPointScalars, vtkTypeBool);  
> vtkGetMacro(UseColorBarPointScalars, vtkTypeBool);  
> vtkBooleanMacro(UseColorBarPointScalars, vtkTypeBool);  
> //@}

Thanks!

---

<div class="post-metadata">

### Author: ![aji](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/a/bbe5ce/32.png) [@aji](https://discourse.vtk.org/u/aji)
#### Post date: [September 11, 2022, 6:13am UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/22 "2022-09-11T06:13:28Z")

</div>

> [@Donny\_Zimmerman](#):
>
> rgb[0] = static\_cast(rgba[0] \* 255.);  
> rgb[1] = static\_cast(rgba[1] \* 255.);  
> rgb[2] = static\_cast(rgba[2] \* 255.);

Thanks a lot. It worked. However in your code at some places static cast syntax is incorrect.

---

<div class="post-metadata">

### Author: ![jaswantp](https://discourse.vtk.org/user_avatar/discourse.vtk.org/jaswantp/32/10046_2.png) [@jaswantp](https://discourse.vtk.org/u/jaswantp)
#### Post date: [February 28, 2023, 8:03am UTC](https://discourse.vtk.org/t/vtkscalarbaractor-in-webassembly/5078/23 "2023-02-28T08:03:09Z")

</div>

While the proposed solution is a good workaround, this issue has been resolved in VTK. `vtkScalarBarActor` relied on OpenGL implementation of `vtkPolyDataMapper2D` which targets desktop GL contexts but left out WebGL2 based contexts.

[`vtkOpenGLES30PolyDataMapper2D`](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/OpenGL2/vtkOpenGLES30PolyDataMapper2D.h) provides a GLES 3.0 (hence WebGL2) compatible implementation. `vtkScalarBarActor`, and by extension, all 2D actors with 2D polydata mappers will work out of the box in webassembly without external workarounds.
