    

 ## On this page

  

 

 # Test002

 Last update: 16.07.2025 

Textured sphere with custom shaders and legends.

This example creates a banded texture with 5 bands of color, and uses this texture to color a spherical object and to color several legends.

No camera is created or added to the scene. This causes the ANSYSViewer to use the min and max values of the POSITION attribute to create a viewing transformation that encompasses the entire scene. The min and max values are not provided for the POSITION attribute, using the SetMinMax method, so the range of the POSITION is automatically calculated by the GLTFWriter API.

The texture coordinates for the sphere range from the minimum Z value, -0.5, to the maximum Z value, 0.5. This range is used for the legends that are created with the identical texture as the sphere. The legends then correctly show the colors on the sphere, and agree with the tooltip.

This example uses a non-default or custom shader. This shows the steps involved to connect the material to the technique and to the shader program.

This example also shows the usage of the Repack class. This is how a single large mesh with unsigned integer indices and be converted into multiple sub-meshes with unsigned short indices. &lt;script src="/ansys/nexus/viewer-loader.js"&gt;&lt;/script&gt;

/\*

 \* COPYRIGHT ANSYS, ALL RIGHTS RESERVED

 \*

 \* @author Glenn Wettlaufer

 \* @version $Revision$4

 \* @date $Date$

 \* $Id$

 \*/

\#include &lt;vector&gt;

\#include &lt;cmath&gt;

\#include &lt;sstream&gt;

\#ifdef \_WIN32

\#include &lt;codecvt&gt;

\#endif

 

\#include "GLTFWriter.h"

\#include "test.h"

 

using namespace ANSYS::Nexus;

 

namespace {

\#ifdef \_WIN32

 std::string 

 ConvertToUtf8String(const std::wstring&amp; wstr)

 {

 std::wstring_convert&lt;std::codecvt_utf8&lt;wchar_t&gt;&gt; myconv;

 return myconv.to_bytes(wstr);

 }

\#endif

};

 

// Lighted sphere with custom shaders

TESTFUNC(CustomShaders)

{

 GLTFWriter::GLTF *gltf = <a id="a0" name="a0"></a>[GLTFWriter::GLTF::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#ab7ba6d114c76cb60baf41aa6f13e9494)("MyApp", "1.0", functionName.c_str(), type);

 if (!gltf)

 throw std::runtime_error("Can't create GLTF");

 

 float mn = -0.5; // have to change shader if these values change

 float mx = 0.5;

 float range = mx - mn;

 

 // TEXTURE

 std::vector&lt;unsigned char&gt; colors;

 colors.push_back(0); colors.push_back(0); colors.push_back(255); // blue

 colors.push_back(0); colors.push_back(255); colors.push_back(255); // cyan

 colors.push_back(0); colors.push_back(255); colors.push_back(0); // green

 colors.push_back(255); colors.push_back(255); colors.push_back(0); // yellow

 colors.push_back(255); colors.push_back(0); colors.push_back(0); // red

 GLTFWriter::Texture *rainbowGradientTexture = <a id="a1" name="a1"></a>[GLTFWriter::Texture::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_texture.xhtml#a3d15e0e6ad83cd7d50bb81ce2d0f30c8)(gltf, <a id="a2" name="a2"></a>[GLTFWriter::Texture::TF\_RGB](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_texture.xhtml#aba6db4f52b9f0a1a866bce302b6d8964aaa8ea9a0e6b83932a6a882b1655e8e59), (unsigned int)colors.size() / 3, &amp;colors[0], false);

 

 // SCENE

 GLTFWriter::Scene *scene = <a id="a3" name="a3"></a>[GLTFWriter::Scene::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_scene.xhtml#aac8bcb85d4361abba99053b3c56eb08b)(gltf, "Testscene", "m", 1.0F, <a id="a4" name="a4"></a>[GLTFWriter::Scene::BT\_TB](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_scene.xhtml#ac17baf491cdba3613b0aa39719a3dbd8a0e9df8d9774401657f9d7aad4e18728f), 0.42F, 0.55F, 0.871F, 1, 1, 1);

 if (!scene) {

 <a id="a5" name="a5"></a>[GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create scene");

 }

 

 // generate vertices, normals, and texture coordinates for a ball

 std::vector&lt;float&gt; vertices;

 std::vector&lt;unsigned int&gt; lines;

 std::vector&lt;unsigned int&gt; triangles;

 GLTFWriter::Test::MakeSphere(0, 0, mn + range / 2.0F, range / 2.0F, 64, vertices, lines, triangles);

 const unsigned int numVertices = (unsigned int)vertices.size() / 3;

 const unsigned int numLines = (unsigned int)lines.size() / 2;

 const unsigned int numTriangles = (unsigned int)triangles.size() / 3;

 std::vector&lt;float&gt; vertexNormals(3 * numVertices);

 <a id="a6" name="a6"></a>[GLTFWriter::Utils::ComputeVertexNormals3](namespace_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils.xhtml#a79e0bdf1db7d56a58b428ee308f66bad)(numVertices, &amp;vertices[0], numTriangles, 3, &amp;triangles[0], &amp;vertexNormals[0]);

 std::vector&lt;float&gt; textureCoords(numVertices);

 for (unsigned int i = 0; i &lt; numVertices; ++i)

 textureCoords[i] = vertices[3 * i + 2]; // coordinates go from mn to mx

 

 // NO CAMERA

 

 // NO LIGHTS - they are done in custom shader

 

 // NODE

 {

 // BUFFER - combine attributes into a single buffer

 GLTFWriter::Buffer *buffer = <a id="a7" name="a7"></a>[GLTFWriter::Buffer::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_buffer.xhtml#ab3810e93f82a461a858df95e572b221d)(gltf);

 

 GLTFWriter::Node *node = <a id="a8" name="a8"></a>[GLTFWriter::Node::CreateMesh](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_node.xhtml#a4dd14791b2b9e65c115aa7a9e3f340e8)(gltf, "3D Ball");

 if (!node || !scene-&gt;AppendMesh(node)) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create mesh node");

 }

 

 // MESH NODE

 GLTFWriter::Node *facesNode = [GLTFWriter::Node::CreateMesh](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_node.xhtml#a4dd14791b2b9e65c115aa7a9e3f340e8)(gltf, "Faces");

 if (!facesNode || !node-&gt;AppendChild(facesNode)) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create mesh");

 }

 

 // MESH

 GLTFWriter::Mesh *mesh = <a id="a9" name="a9"></a>[GLTFWriter::Mesh::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_mesh.xhtml#a9f7803b1b1eb72e4005665ca33f42788)(gltf);

 if (!mesh || !facesNode-&gt;AppendMesh(mesh)) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create mesh");

 }

 

 // VERTEX SHADER

 std::ostringstream vsText;

 vsText.precision(6);

 vsText &lt;&lt; std::showpoint;

 vsText &lt;&lt; "precision highp float;\\n";

 vsText &lt;&lt; "uniform mat4 u\_projectionMatrix;\\n";

 vsText &lt;&lt; "uniform mat4 u\_modelViewMatrix;\\n";

 vsText &lt;&lt; "attribute vec3 a\_position;\\n";

 vsText &lt;&lt; "uniform mat3 u\_normalMatrix;\\n";

 vsText &lt;&lt; "attribute vec3 a\_normal;\\n";

 vsText &lt;&lt; "varying vec3 v\_eyePosition;\\n";

 vsText &lt;&lt; "varying vec3 v\_normal;\\n";

 vsText &lt;&lt; "attribute float a\_texCoord0;\\n";

 vsText &lt;&lt; "varying float v\_texCoord0;\\n";

 vsText &lt;&lt; "void main() {\\n";

 vsText &lt;&lt; "vec4 l\_position = vec4(a\_position, 1.0);\\n";

 vsText &lt;&lt; "vec4 l\_eyePosition = u\_modelViewMatrix \* l\_position;\\n";

 vsText &lt;&lt; "v\_eyePosition = l\_eyePosition.xyz / l\_eyePosition.w;\\n";

 vsText &lt;&lt; "v\_normal = u\_normalMatrix \* a\_normal;\\n";

 vsText &lt;&lt; "v\_texCoord0 = (a\_texCoord0 - " &lt;&lt; mn &lt;&lt; ") / " &lt;&lt; range &lt;&lt; ";\\n";

 vsText &lt;&lt; "v\_texCoord0 = clamp(v\_texCoord0, 0.0, 1.0);\\n";

 vsText &lt;&lt; "gl\_Position = u\_projectionMatrix \* l\_eyePosition;\\n";

 vsText &lt;&lt; "}\\n";

 std::vector&lt;const char *&gt; uVertex;

 uVertex.push_back("u\_modelViewMatrix");

 uVertex.push_back("u\_projectionMatrix");

 uVertex.push_back("u\_normalMatrix");

 std::vector&lt;const char *&gt; aVertex;

 aVertex.push_back("a\_position");

 aVertex.push_back("a\_normal");

 aVertex.push_back("a\_texCoord0");

 GLTFWriter::Shader *vertexShader = <a id="a10" name="a10"></a>[GLTFWriter::Shader::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_shader.xhtml#a9ec4a508b3bc996fec2cc27d2b8c3941)(gltf, vsText.str().c_str(), (unsigned int)aVertex.size(), &amp;aVertex[0], (unsigned int)uVertex.size(), &amp;uVertex[0]);

 

 // FRAGMENT SHADER

 std::string fsText(std::string("precision highp float;\\n") +

 "uniform vec4 u\_diffuse;\\n" +

 "uniform vec3 u\_light0Position;\\n" +

 "uniform vec3 u\_light1Ambient;\\n" +

 "uniform sampler2D u\_texture0;\\n" +

 "varying vec3 v\_eyePosition;\\n" +

 "varying vec3 v\_normal;\\n" +

 "varying float v\_texCoord0;\\n" +

 "void main() {\\n" +

 "vec4 l\_color = u\_diffuse;\\n" +

 "vec3 l\_normal = normalize(v\_normal);\\n" +

 "vec2 l\_texCoord = vec2(v\_texCoord0, 0);\\n" +

 "vec4 l\_texelColor = texture2D(u\_texture0, l\_texCoord);\\n" +

 "l\_color \*= l\_texelColor;\\n" +

 "vec3 l\_frontAmbient = u\_light1Ambient \* l\_color.rgb;\\n" +

 "vec3 l\_frontDiffuse = vec3(0.0, 0.0, 0.0);\\n" +

 "vec3 l\_frontSpecular = vec3(0.0, 0.0, 0.0);\\n" +

 "vec3 l\_VP = normalize(u\_light0Position - v\_eyePosition);\\n" +

 "float l\_nDotVP = dot(l\_normal, l\_VP);\\n" +

 "if (!gl\_FrontFacing)\\n" + // two sided lighting

 "l\_nDotVP = -l\_nDotVP;\\n" +

 "if (l\_nDotVP &gt; 0.0) {\\n" + // front faced

 "l\_frontDiffuse += l\_nDotVP \* l\_color.rgb;\\n" +

 "vec3 l\_halfVector = normalize(l\_VP + vec3(0.0, 0.0, 1.0));\\n" + // eye is always looking down Z axis

 "float l\_nDotHV = dot(l\_normal, l\_halfVector);\\n" +

 "if (!gl\_FrontFacing)\\n" + // two sided lighting

 "l\_nDotHV = -l\_nDotHV;\\n"

 "if (l\_nDotHV &gt; 0.0)\\n" + // specular

 "l\_frontSpecular += pow(l\_nDotHV, 100.0) \* vec3(1.0, 1.0, 1.0);\\n" +

 "}\\n" + // front faced

 "l\_color = vec4(l\_frontAmbient + l\_frontDiffuse + l\_frontSpecular, l\_color.a);\\n" +

 "l\_color = clamp(l\_color, 0.0, 1.0);\\n" +

 "gl\_FragColor = l\_color;\\n" +

 "}\\n");

 std::vector&lt;const char *&gt; uFragment;

 uFragment.push_back("u\_diffuse");

 uFragment.push_back("u\_light0Position");

 uFragment.push_back("u\_light1Ambient");

 uFragment.push_back("u\_texture0");

 GLTFWriter::Shader *fragmentShader = [GLTFWriter::Shader::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_shader.xhtml#a9ec4a508b3bc996fec2cc27d2b8c3941)(gltf, fsText.c_str(), 0, 0, (unsigned int)uFragment.size(), &amp;uFragment[0]);

 

 // PROGRAM

 GLTFWriter::Program *program = <a id="a11" name="a11"></a>[GLTFWriter::Program::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_program.xhtml#a9dc2b523ccb97521c72ff12113d8f6f2)(gltf, vertexShader, fragmentShader);

 

 // TECHNIQUE

 GLTFWriter::Technique *technique = <a id="a12" name="a12"></a>[GLTFWriter::Technique::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_technique.xhtml#a13382537cb3622195e7cf0bf33e202c2)(gltf, program);

 if (!technique ||

 // TECHNIQUE PARAMETERS

 !technique-&gt;AppendParameter(<a id="a13" name="a13"></a>[GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "u\_diffuse", "diffuse", <a id="a14" name="a14"></a>[GLTFWriter::Parameter::PT\_FLOAT\_VEC4](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca2ee53691b02a2647b586f8325184aee9), <a id="a15" name="a15"></a>[GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "", 1.0, 1.0, 1.0, 1.0))) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "u\_light0Position", "light0Position", <a id="a16" name="a16"></a>[GLTFWriter::Parameter::PT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca9e032d6885dc8956db47d4de23a046ce), [GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "", 0.0, 0.0, 1.0))) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "u\_light1Ambient", "light1Ambient", [GLTFWriter::Parameter::PT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca9e032d6885dc8956db47d4de23a046ce), [GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "", 0.0, 0.0, 0.0))) ||

 !technique-&gt;AppendParameter(<a id="a17" name="a17"></a>[GLTFWriter::Parameter::CreateModelViewMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a99fedbeb406aa0f9649e8a869ab1d5a8)(gltf, "u\_modelViewMatrix")) ||

 !technique-&gt;AppendParameter(<a id="a18" name="a18"></a>[GLTFWriter::Parameter::CreateProjectionMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a5f525804b21ab8879b277ebc7c3bad6e)(gltf, "u\_projectionMatrix")) ||

 !technique-&gt;AppendParameter(<a id="a19" name="a19"></a>[GLTFWriter::Parameter::CreateNormalMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a6fbdcaa95636611f46551a928402f3cf)(gltf, "u\_normalMatrix")) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "u\_texture0", "texture0", <a id="a20" name="a20"></a>[GLTFWriter::Parameter::PT\_SAMPLER\_2D](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572caae7eac8db24a1df5567994ab2062d468))) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "a\_position", "POSITION", [GLTFWriter::Parameter::PT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca9e032d6885dc8956db47d4de23a046ce))) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "a\_normal", "NORMAL", [GLTFWriter::Parameter::PT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca9e032d6885dc8956db47d4de23a046ce))) ||

 !technique-&gt;AppendParameter([GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)(gltf, "a\_texCoord0", "TEXCOORD0", <a id="a21" name="a21"></a>[GLTFWriter::Parameter::PT\_FLOAT](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca19c98b6589cd105e66bd34418a401781))) ||

 // TECHNIQUE STATES

 !technique-&gt;AppendState(<a id="a22" name="a22"></a>[GLTFWriter::State::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#a8cefd28a7477d1ab51809a51b21b8019)(gltf, <a id="a23" name="a23"></a>[GLTFWriter::State::ST\_BLENDENABLE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#affd67e37265c1883f760fd0c368ba718a333b0ebeb6a896a3b0b973da1f1ce56a), 1)) ||

 !technique-&gt;AppendState([GLTFWriter::State::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#a8cefd28a7477d1ab51809a51b21b8019)(gltf, <a id="a24" name="a24"></a>[GLTFWriter::State::ST\_DEPTHTESTENABLE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#affd67e37265c1883f760fd0c368ba718a5a304a50ef0c9a98124f4c998ec47f3b), 1))) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create technique");

 }

 

 // MATERIAL

 GLTFWriter::Material *material = <a id="a25" name="a25"></a>[GLTFWriter::Material::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_material.xhtml#a683cf8ee4a674e8e7a7b01c97797eecc)(gltf, technique);

 if (!material ||

 // MATERIAL UNIFORM VALUES

 !material-&gt;AppendValue([GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "diffuse", 1.0, 1.0, 1.0, 1.0)) ||

 !material-&gt;AppendValue([GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "light0Position", 100.0, 100.0, 100.0)) ||

 !material-&gt;AppendValue([GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "light1Ambient", 0.3, 0.3, 0.3)) ||

 !material-&gt;AppendValue([GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "texture0", rainbowGradientTexture-&gt;GetID())) ||

 // this is a solid object, that we want to have an interior color so when it is clipped we see the solid interior color

 !material-&gt;AppendValue([GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)(gltf, "solidColor", 1.0, 0.0, 1.0, 1.0))) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create material");

 }

 

 // repack unsigned int indices into multiple sets of unsigned short indices

 GLTFWriter::Utils::Repack *repack = <a id="a26" name="a26"></a>[GLTFWriter::Utils::Repack::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a81856527dc12542540dce2f517b5eec4)(numTriangles, 3, &amp;triangles[0]);

 if (!repack) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create repack");

 }

 for (unsigned int i = 0; i &lt; repack-&gt;NumPacks(); ++i) {

 const float *packedData;

 unsigned int numAttributes = repack-&gt;NumAttributes(i);

 

 // POSITION ATTRIBUTE

 packedData = repack-&gt;ConstructRepackAttribute(&amp;triangles[0], 3, &amp;vertices[0], i);

 GLTFWriter::Attribute *vertex = <a id="a27" name="a27"></a>[GLTFWriter::Attribute::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#a74b97d3bfc2585fe4d67a663a79abfa1)(gltf, "POSITION", <a id="a28" name="a28"></a>[GLTFWriter::Attribute::AT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#aa787c451052ac912fd9af91c4ff54ddba0e6049e71b78dccf0f7f9791abe541c3), numAttributes, packedData, buffer);

 

 // TEXCOORD ATTRIBUTE

 packedData = repack-&gt;ConstructRepackAttribute(&amp;triangles[0], 1, &amp;textureCoords[0], i);

 GLTFWriter::Attribute *texture = [GLTFWriter::Attribute::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#a74b97d3bfc2585fe4d67a663a79abfa1)(gltf, "TEXCOORD0", <a id="a29" name="a29"></a>[GLTFWriter::Attribute::AT\_FLOAT](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#aa787c451052ac912fd9af91c4ff54ddba6d124c894e5bdc043eeebec0f852e857), numAttributes, packedData, buffer);

 

 // NORMAL ATTRIBUTE

 packedData = repack-&gt;ConstructRepackAttribute(&amp;triangles[0], 3, &amp;vertexNormals[0], i);

 GLTFWriter::Attribute *normal = [GLTFWriter::Attribute::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#a74b97d3bfc2585fe4d67a663a79abfa1)(gltf, "NORMAL", [GLTFWriter::Attribute::AT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#aa787c451052ac912fd9af91c4ff54ddba0e6049e71b78dccf0f7f9791abe541c3), numAttributes, packedData, buffer);

 

 // INDICES

 unsigned int numIndices = 3U * repack-&gt;NumElements(i);

 const unsigned short *packedIndex = repack-&gt;ConstructRepackIndex(&amp;triangles[0], i);

 GLTFWriter::Index *index = <a id="a30" name="a30"></a>[GLTFWriter::Index::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_index.xhtml#ab4c4a14b880b4247257672358ad7ccfc)(gltf, numIndices, packedIndex, buffer);

 if (!index) {

 <a id="a31" name="a31"></a>[GLTFWriter::Utils::Repack::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ae380a98f35dd3c7dc8cd3cb87e56e9df)(repack);

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create index");

 }

 

 // PRIMITIVE

 GLTFWriter::Primitive *primitive = <a id="a32" name="a32"></a>[GLTFWriter::Primitive::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_primitive.xhtml#a11dce37f59247e26bd6973ba5d7fefeb)(gltf, <a id="a33" name="a33"></a>[GLTFWriter::Primitive::PT\_TRIANGLES](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_primitive.xhtml#a062b429c87d913e5adda11b381414c6ea85ba263ad510a4b423c5e1452fd5ca7d), material, index);

 if (!primitive ||

 !primitive-&gt;AppendAttribute(vertex) ||

 !primitive-&gt;AppendAttribute(normal) ||

 !primitive-&gt;AppendAttribute(texture) ||

 !mesh-&gt;AppendPrimitive(primitive)) {

 [GLTFWriter::Utils::Repack::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ae380a98f35dd3c7dc8cd3cb87e56e9df)(repack);

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Can't create primitive");

 }

 }

 

 [GLTFWriter::Utils::Repack::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ae380a98f35dd3c7dc8cd3cb87e56e9df)(repack);

 }

 

 if (!gltf-&gt;Write()) {

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 throw std::runtime_error("Error creating file");

 }

 

 <a id="a34" name="a34"></a>[GLTFWriter::GLTF::GLTFError](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#acf83a4d185d959503cb9f3f2c2e9fafe) error = gltf-&gt;GetError();

 

 [GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)(gltf);

 

 if (error != <a id="a35" name="a35"></a>[GLTFWriter::GLTF::GLTF\_ERROR\_NONE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#acf83a4d185d959503cb9f3f2c2e9fafea049c3b804e69ae05c02f4c2dedf4e0ea))

 throw std::runtime_error("Error creating file");

}

[ANSYS::Nexus::GLTFWriter::Attribute::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#a74b97d3bfc2585fe4d67a663a79abfa1)

static Attribute * Create(GLTF *gltf, const char *name, AttributeType type, unsigned int count, const int *data, Buffer *buffer=0)



[ANSYS::Nexus::GLTFWriter::Attribute::AT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#aa787c451052ac912fd9af91c4ff54ddba0e6049e71b78dccf0f7f9791abe541c3)

@ AT_FLOAT_VEC3

3 AT_FLOATs

**Definition:** [GLTFAttribute.h:44](_g_l_t_f_attribute_8h_source.xhtml#l00044)



[ANSYS::Nexus::GLTFWriter::Attribute::AT\_FLOAT](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_attribute.xhtml#aa787c451052ac912fd9af91c4ff54ddba6d124c894e5bdc043eeebec0f852e857)

@ AT_FLOAT

4 byte float

**Definition:** [GLTFAttribute.h:42](_g_l_t_f_attribute_8h_source.xhtml#l00042)



[ANSYS::Nexus::GLTFWriter::Buffer::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_buffer.xhtml#ab3810e93f82a461a858df95e572b221d)

static Buffer * Create(GLTF *gltf)



[ANSYS::Nexus::GLTFWriter::GLTF::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a586171eb8e873e909db02a7eb4d80f5c)

static void Destroy(GLTF *gltf)



[ANSYS::Nexus::GLTFWriter::GLTF::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#ab7ba6d114c76cb60baf41aa6f13e9494)

static GLTF * Create(const char *application, const char *applicationVersion, const char *filePath, OutputType fileType=OT_AVZ)



[ANSYS::Nexus::GLTFWriter::GLTF::GLTFError](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#acf83a4d185d959503cb9f3f2c2e9fafe)

GLTFError

**Definition:** [GLTFGLTF.h:35](_g_l_t_f_g_l_t_f_8h_source.xhtml#l00035)



[ANSYS::Nexus::GLTFWriter::GLTF::GLTF\_ERROR\_NONE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#acf83a4d185d959503cb9f3f2c2e9fafea049c3b804e69ae05c02f4c2dedf4e0ea)

@ GLTF_ERROR_NONE

No Error.

**Definition:** [GLTFGLTF.h:36](_g_l_t_f_g_l_t_f_8h_source.xhtml#l00036)



[ANSYS::Nexus::GLTFWriter::Index::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_index.xhtml#ab4c4a14b880b4247257672358ad7ccfc)

static Index * Create(GLTF *gltf, unsigned int count, const unsigned short *indices, Buffer *buffer=0)



[ANSYS::Nexus::GLTFWriter::Material::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_material.xhtml#a683cf8ee4a674e8e7a7b01c97797eecc)

static Material * Create(GLTF *gltf, Technique *technique)



[ANSYS::Nexus::GLTFWriter::Mesh::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_mesh.xhtml#a9f7803b1b1eb72e4005665ca33f42788)

static Mesh * Create(GLTF *gltf)



[ANSYS::Nexus::GLTFWriter::Node::CreateMesh](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_node.xhtml#a4dd14791b2b9e65c115aa7a9e3f340e8)

static Node * CreateMesh(GLTF *gltf, const char *name=0, bool visible=true, const double *matrix=0)



[ANSYS::Nexus::GLTFWriter::Parameter::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a568c2372d0ded24328122d9f87234695)

static Parameter * Create(GLTF *gltf, const char *shaderName, const char *externalName, ParameterType type, const Value *defaultValue=0)



[ANSYS::Nexus::GLTFWriter::Parameter::CreateProjectionMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a5f525804b21ab8879b277ebc7c3bad6e)

static Parameter * CreateProjectionMatrix(GLTF *gltf, const char *shaderName)



[ANSYS::Nexus::GLTFWriter::Parameter::CreateNormalMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a6fbdcaa95636611f46551a928402f3cf)

static Parameter * CreateNormalMatrix(GLTF *gltf, const char *shaderName)



[ANSYS::Nexus::GLTFWriter::Parameter::PT\_FLOAT](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca19c98b6589cd105e66bd34418a401781)

@ PT_FLOAT

4 byte float

**Definition:** [GLTFTechnique.h:40](_g_l_t_f_technique_8h_source.xhtml#l00040)



[ANSYS::Nexus::GLTFWriter::Parameter::PT\_FLOAT\_VEC4](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca2ee53691b02a2647b586f8325184aee9)

@ PT_FLOAT_VEC4

4 PT_FLOAT's

**Definition:** [GLTFTechnique.h:43](_g_l_t_f_technique_8h_source.xhtml#l00043)



[ANSYS::Nexus::GLTFWriter::Parameter::PT\_FLOAT\_VEC3](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572ca9e032d6885dc8956db47d4de23a046ce)

@ PT_FLOAT_VEC3

3 PT_FLOAT's

**Definition:** [GLTFTechnique.h:42](_g_l_t_f_technique_8h_source.xhtml#l00042)



[ANSYS::Nexus::GLTFWriter::Parameter::PT\_SAMPLER\_2D](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a93b92cf730f9530cef13458f0b12572caae7eac8db24a1df5567994ab2062d468)

@ PT_SAMPLER_2D

2D Texture

**Definition:** [GLTFTechnique.h:54](_g_l_t_f_technique_8h_source.xhtml#l00055)



[ANSYS::Nexus::GLTFWriter::Parameter::CreateModelViewMatrix](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_parameter.xhtml#a99fedbeb406aa0f9649e8a869ab1d5a8)

static Parameter * CreateModelViewMatrix(GLTF *gltf, const char *shaderName)



[ANSYS::Nexus::GLTFWriter::Primitive::PT\_TRIANGLES](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_primitive.xhtml#a062b429c87d913e5adda11b381414c6ea85ba263ad510a4b423c5e1452fd5ca7d)

@ PT_TRIANGLES

Treats each triplet of vertices as an independent triangle.

**Definition:** [GLTFMesh.h:39](_g_l_t_f_mesh_8h_source.xhtml#l00039)



[ANSYS::Nexus::GLTFWriter::Primitive::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_primitive.xhtml#a11dce37f59247e26bd6973ba5d7fefeb)

static Primitive * Create(GLTF *gltf, PrimitiveType type, Material *material, Index *indices=0, bool isPickable=true)



[ANSYS::Nexus::GLTFWriter::Program::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_program.xhtml#a9dc2b523ccb97521c72ff12113d8f6f2)

static Program * Create(GLTF *gltf, Shader *vertexShader, Shader *fragmentShader)



[ANSYS::Nexus::GLTFWriter::Scene::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_scene.xhtml#aac8bcb85d4361abba99053b3c56eb08b)

static Scene * Create(GLTF *gltf, const char *name=0, const char *units=0, float scale=1, Scene::BackgroundType backgroundType=Scene::BT_NONE, float r1=0, float g1=0, float b1=0, float r2=0, float g2=0, float b2=0)



[ANSYS::Nexus::GLTFWriter::Scene::BT\_TB](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_scene.xhtml#ac17baf491cdba3613b0aa39719a3dbd8a0e9df8d9774401657f9d7aad4e18728f)

@ BT_TB

Make gradient from color 1 top to color 2 bottom.

**Definition:** [GLTFScene.h:36](_g_l_t_f_scene_8h_source.xhtml#l00036)



[ANSYS::Nexus::GLTFWriter::Shader::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_shader.xhtml#a9ec4a508b3bc996fec2cc27d2b8c3941)

static Shader * Create(GLTF *gltf, const char *shaderText, unsigned int numAttributes, const char **attributes, unsigned int numUniforms, const char **uniforms)



[ANSYS::Nexus::GLTFWriter::State::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#a8cefd28a7477d1ab51809a51b21b8019)

static State * Create(GLTF *gltf, StateType type, double v1, double v2=0, double v3=0, double v4=0)



[ANSYS::Nexus::GLTFWriter::State::ST\_BLENDENABLE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#affd67e37265c1883f760fd0c368ba718a333b0ebeb6a896a3b0b973da1f1ce56a)

@ ST_BLENDENABLE

Enables blending of fragment colors. Possible values are:

**Definition:** [GLTFTechnique.h:166](_g_l_t_f_technique_8h_source.xhtml#l00166)



[ANSYS::Nexus::GLTFWriter::State::ST\_DEPTHTESTENABLE](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_state.xhtml#affd67e37265c1883f760fd0c368ba718a5a304a50ef0c9a98124f4c998ec47f3b)

@ ST_DEPTHTESTENABLE

Enables testing of depth buffer. Possible values are:

**Definition:** [GLTFTechnique.h:186](_g_l_t_f_technique_8h_source.xhtml#l00186)



[ANSYS::Nexus::GLTFWriter::Technique::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_technique.xhtml#a13382537cb3622195e7cf0bf33e202c2)

static Technique * Create(GLTF *gltf, Program *program=0, bool is2D=false)



[ANSYS::Nexus::GLTFWriter::Texture::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_texture.xhtml#a3d15e0e6ad83cd7d50bb81ce2d0f30c8)

static Texture * Create(GLTF *gltf, TextureFormat format, TextureTarget target, Sampler *sampler, Image *image)



[ANSYS::Nexus::GLTFWriter::Texture::TF\_RGB](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_texture.xhtml#aba6db4f52b9f0a1a866bce302b6d8964aaa8ea9a0e6b83932a6a882b1655e8e59)

@ TF_RGB

3 unsigned chars per pixel.

**Definition:** [GLTFTexture.h:34](_g_l_t_f_texture_8h_source.xhtml#l00034)



[ANSYS::Nexus::GLTFWriter::Utils::Repack::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a81856527dc12542540dce2f517b5eec4)

static Repack * Create(unsigned int elementCount, unsigned int elementSize, const unsigned int *indices)



[ANSYS::Nexus::GLTFWriter::Utils::Repack::Destroy](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ae380a98f35dd3c7dc8cd3cb87e56e9df)

static void Destroy(Repack *packer)



[ANSYS::Nexus::GLTFWriter::Value::Create](class_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_value.xhtml#aee78dae95614f843f10d5e19f9d55d61)

static Value * Create(GLTF *gltf, const char *name, const Value *value=0)



[ANSYS::Nexus::GLTFWriter::Utils::ComputeVertexNormals3](namespace_a_n_s_y_s_1_1_nexus_1_1_g_l_t_f_writer_1_1_utils.xhtml#a79e0bdf1db7d56a58b428ee308f66bad)

void ComputeVertexNormals3(const unsigned int numVertices, const float *vertices, const unsigned int numElements, const unsigned int elementSize, const unsigned short *indices, float *normals)