    

 ## On this page

  

 

 # Test002

 Last update: 16.07.2025 

 /// &lt;script src="./ansys251/nexus/viewer-loader.js"&gt;&lt;/script&gt; /// ///

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.

/\*

 \* 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::AVZ;

 

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)

{

 <a id="_a0" name="_a0"></a>[GLTFWriter::GLTF](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml) *gltf = GLTFWriter::GLTF::Create("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

 <a id="_a1" name="_a1"></a>[GLTFWriter::Texture](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_texture.xhtml) *rainbowGradientTexture = GLTFWriter::Texture::Create(gltf, GLTFWriter::Texture::TF_RGB, (unsigned int)colors.size() / 3, &amp;colors[0], false);

 

 // SCENE

 <a id="_a2" name="_a2"></a>[GLTFWriter::Scene](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_scene.xhtml) *scene = GLTFWriter::Scene::Create(gltf, "Testscene", "m", 1.0F, GLTFWriter::Scene::BT_TB, 0.42F, 0.55F, 0.871F, 1, 1, 1);

 if (!scene) {

 GLTFWriter::GLTF::Destroy(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);

 GLTFWriter::Utils::ComputeVertexNormals3(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

 <a id="_a3" name="_a3"></a>[GLTFWriter::Buffer](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_buffer.xhtml) *buffer = GLTFWriter::Buffer::Create(gltf);

 

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

 if (!node || !scene-&gt;<a id="a5" name="a5"></a>[AppendMesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_scene.xhtml#a76e34d4c05fe34dde0fcc4913ad63981)(node)) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

 // MESH NODE

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

 if (!facesNode || !node-&gt;<a id="a6" name="a6"></a>[AppendChild](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_node.xhtml#a86b91dc1bac027fd7a8e59f4d5f0ea05)(facesNode)) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

 // MESH

 <a id="_a7" name="_a7"></a>[GLTFWriter::Mesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_mesh.xhtml) *mesh = GLTFWriter::Mesh::Create(gltf);

 if (!mesh || !facesNode-&gt;<a id="a8" name="a8"></a>[AppendMesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_node.xhtml#a68c9eec5fe03405e52b3558a62f8faec)(mesh)) {

 GLTFWriter::GLTF::Destroy(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");

 <a id="_a9" name="_a9"></a>[GLTFWriter::Shader](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_shader.xhtml) *vertexShader = GLTFWriter::Shader::Create(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](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_shader.xhtml) *fragmentShader = GLTFWriter::Shader::Create(gltf, fsText.c_str(), 0, 0, (unsigned int)uFragment.size(), &amp;uFragment[0]);

 

 // PROGRAM

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

 

 // TECHNIQUE

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

 if (!technique ||

 // TECHNIQUE PARAMETERS

 !technique-&gt;<a id="a12" name="a12"></a>[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "u\_diffuse", "diffuse", GLTFWriter::Parameter::PT_FLOAT_VEC4, GLTFWriter::Value::Create(gltf, "", 1.0, 1.0, 1.0, 1.0))) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "u\_light0Position", "light0Position", GLTFWriter::Parameter::PT_FLOAT_VEC3, GLTFWriter::Value::Create(gltf, "", 0.0, 0.0, 1.0))) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "u\_light1Ambient", "light1Ambient", GLTFWriter::Parameter::PT_FLOAT_VEC3, GLTFWriter::Value::Create(gltf, "", 0.0, 0.0, 0.0))) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::CreateModelViewMatrix(gltf, "u\_modelViewMatrix")) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::CreateProjectionMatrix(gltf, "u\_projectionMatrix")) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::CreateNormalMatrix(gltf, "u\_normalMatrix")) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "u\_texture0", "texture0", GLTFWriter::Parameter::PT_SAMPLER_2D)) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "a\_position", "POSITION", GLTFWriter::Parameter::PT_FLOAT_VEC3)) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "a\_normal", "NORMAL", GLTFWriter::Parameter::PT_FLOAT_VEC3)) ||

 !technique-&gt;[AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)(GLTFWriter::Parameter::Create(gltf, "a\_texCoord0", "TEXCOORD0", GLTFWriter::Parameter::PT_FLOAT)) ||

 // TECHNIQUE STATES

 !technique-&gt;<a id="a13" name="a13"></a>[AppendState](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#a8b2b0766157324d5a2093a3fca36379f)(GLTFWriter::State::Create(gltf, GLTFWriter::State::ST_BLENDENABLE, 1)) ||

 !technique-&gt;[AppendState](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#a8b2b0766157324d5a2093a3fca36379f)(GLTFWriter::State::Create(gltf, GLTFWriter::State::ST_DEPTHTESTENABLE, 1))) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

 // MATERIAL

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

 if (!material ||

 // MATERIAL UNIFORM VALUES

 !material-&gt;<a id="a15" name="a15"></a>[AppendValue](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_material.xhtml#a2f8a41e41af7d9b8cd498506f6510dd7)(GLTFWriter::Value::Create(gltf, "diffuse", 1.0, 1.0, 1.0, 1.0)) ||

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

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

 !material-&gt;[AppendValue](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_material.xhtml#a2f8a41e41af7d9b8cd498506f6510dd7)(GLTFWriter::Value::Create(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](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_material.xhtml#a2f8a41e41af7d9b8cd498506f6510dd7)(GLTFWriter::Value::Create(gltf, "solidColor", 1.0, 0.0, 1.0, 1.0))) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

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

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

 if (!repack) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 for (unsigned int i = 0; i &lt; repack-&gt;<a id="a17" name="a17"></a>[NumPacks](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a69a383562c62ca71c8a785c96f773fb3)(); ++i) {

 const float *packedData;

 unsigned int numAttributes = repack-&gt;<a id="a18" name="a18"></a>[NumAttributes](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a43a74d90484a85856103c33969eb7107)(i);

 

 // POSITION ATTRIBUTE

 packedData = repack-&gt;<a id="a19" name="a19"></a>[ConstructRepackAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a1487b86e5090019cf7565e144fe11e4f)(&amp;triangles[0], 3, &amp;vertices[0], i);

 <a id="_a20" name="_a20"></a>[GLTFWriter::Attribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_attribute.xhtml) *vertex = GLTFWriter::Attribute::Create(gltf, "POSITION", GLTFWriter::Attribute::AT_FLOAT_VEC3, numAttributes, packedData, buffer);

 

 // TEXCOORD ATTRIBUTE

 packedData = repack-&gt;[ConstructRepackAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a1487b86e5090019cf7565e144fe11e4f)(&amp;triangles[0], 1, &amp;textureCoords[0], i);

 [GLTFWriter::Attribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_attribute.xhtml) *texture = GLTFWriter::Attribute::Create(gltf, "TEXCOORD0", GLTFWriter::Attribute::AT_FLOAT, numAttributes, packedData, buffer);

 

 // NORMAL ATTRIBUTE

 packedData = repack-&gt;[ConstructRepackAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a1487b86e5090019cf7565e144fe11e4f)(&amp;triangles[0], 3, &amp;vertexNormals[0], i);

 [GLTFWriter::Attribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_attribute.xhtml) *normal = GLTFWriter::Attribute::Create(gltf, "NORMAL", GLTFWriter::Attribute::AT_FLOAT_VEC3, numAttributes, packedData, buffer);

 

 // INDICES

 unsigned int numIndices = 3U * repack-&gt;<a id="a21" name="a21"></a>[NumElements](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a50e2eaf986369c115fe9cae008187cc0)(i);

 const unsigned short *packedIndex = repack-&gt;<a id="a22" name="a22"></a>[ConstructRepackIndex](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ab3bd7bca7382f17a0c08e144b67d22f2)(&amp;triangles[0], i);

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

 if (!index) {

 GLTFWriter::Utils::Repack::Destroy(repack);

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

 // PRIMITIVE

 <a id="_a24" name="_a24"></a>[GLTFWriter::Primitive](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml) *primitive = GLTFWriter::Primitive::Create(gltf, GLTFWriter::Primitive::PT_TRIANGLES, material, index);

 if (!primitive ||

 !primitive-&gt;<a id="a25" name="a25"></a>[AppendAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml#ac4144b4cc35eec9c11b07cc7352d209e)(vertex) ||

 !primitive-&gt;[AppendAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml#ac4144b4cc35eec9c11b07cc7352d209e)(normal) ||

 !primitive-&gt;[AppendAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml#ac4144b4cc35eec9c11b07cc7352d209e)(texture) ||

 !mesh-&gt;<a id="a26" name="a26"></a>[AppendPrimitive](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_mesh.xhtml#afb99ec25e2eebb4390c17f8770e4c23b)(primitive)) {

 GLTFWriter::Utils::Repack::Destroy(repack);

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 }

 

 GLTFWriter::Utils::Repack::Destroy(repack);

 }

 

 if (!gltf-&gt;<a id="a27" name="a27"></a>[Write](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a0bf3a4ec615dc8810776dd82a65eba91)()) {

 GLTFWriter::GLTF::Destroy(gltf);

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

 }

 

 [GLTFWriter::GLTF::GLTFError](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a5b8141dc8536bc10d1a72996ad6f98b4) error = gltf-&gt;<a id="a28" name="a28"></a>[GetError](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a63295f8f31619517e94cf27d3a8b9ea8)();

 

 GLTFWriter::GLTF::Destroy(gltf);

 

 if (error != GLTFWriter::GLTF::GLTF_ERROR_NONE)

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

}

[ANSYS::AVZ::GLTFWriter::Attribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_attribute.xhtml)

Attributes define the per element index values for elements defined by Index.

**Definition** [GLTFAttribute.h:32](_g_l_t_f_attribute_8h_source.xhtml#l00031)



[ANSYS::AVZ::GLTFWriter::Buffer](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_buffer.xhtml)

Buffers define files that are used to contain attribute and index data.

**Definition** [GLTFBuffer.h:36](_g_l_t_f_buffer_8h_source.xhtml#l00035)



[ANSYS::AVZ::GLTFWriter::GLTF](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml)

This is the main class of the GLTFWriter.

**Definition** [GLTFGLTF.h:32](_g_l_t_f_g_l_t_f_8h_source.xhtml#l00031)



[ANSYS::AVZ::GLTFWriter::GLTF::Write](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a0bf3a4ec615dc8810776dd82a65eba91)

virtual bool Write(bool formatJSON=false)=0



[ANSYS::AVZ::GLTFWriter::GLTF::GLTFError](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a5b8141dc8536bc10d1a72996ad6f98b4)

GLTFError

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



[ANSYS::AVZ::GLTFWriter::GLTF::GetError](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_g_l_t_f.xhtml#a63295f8f31619517e94cf27d3a8b9ea8)

virtual GLTFError GetError()=0



[ANSYS::AVZ::GLTFWriter::Index](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_index.xhtml)

Indexes define elements within primitives.

**Definition** [GLTFIndex.h:29](_g_l_t_f_index_8h_source.xhtml#l00028)



[ANSYS::AVZ::GLTFWriter::Material](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_material.xhtml)

Materials describe how primitives are rendered.

**Definition** [GLTFMaterial.h:30](_g_l_t_f_material_8h_source.xhtml#l00029)



[ANSYS::AVZ::GLTFWriter::Material::AppendValue](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_material.xhtml#a2f8a41e41af7d9b8cd498506f6510dd7)

virtual bool AppendValue(Value *value)=0



[ANSYS::AVZ::GLTFWriter::Mesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_mesh.xhtml)

Meshes define the renderable objects that can be added to a node.

**Definition** [GLTFMesh.h:104](_g_l_t_f_mesh_8h_source.xhtml#l00103)



[ANSYS::AVZ::GLTFWriter::Mesh::AppendPrimitive](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_mesh.xhtml#afb99ec25e2eebb4390c17f8770e4c23b)

virtual bool AppendPrimitive(Primitive *primitive)=0



[ANSYS::AVZ::GLTFWriter::Node](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_node.xhtml)

Nodes are the GLTFWriter class that contain the data that is defined in the GLTF file.

**Definition** [GLTFNode.h:31](_g_l_t_f_node_8h_source.xhtml#l00030)



[ANSYS::AVZ::GLTFWriter::Node::AppendMesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_node.xhtml#a68c9eec5fe03405e52b3558a62f8faec)

virtual bool AppendMesh(Mesh *mesh)=0



[ANSYS::AVZ::GLTFWriter::Node::AppendChild](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_node.xhtml#a86b91dc1bac027fd7a8e59f4d5f0ea05)

virtual bool AppendChild(Node *node)=0



[ANSYS::AVZ::GLTFWriter::Primitive](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml)

Primitives are the renderable parts of meshes.

**Definition** [GLTFMesh.h:30](_g_l_t_f_mesh_8h_source.xhtml#l00029)



[ANSYS::AVZ::GLTFWriter::Primitive::AppendAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_primitive.xhtml#ac4144b4cc35eec9c11b07cc7352d209e)

virtual bool AppendAttribute(Attribute *attribute)=0



[ANSYS::AVZ::GLTFWriter::Program](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_program.xhtml)

Programs are the GLSL executable code for rendering the primitives.

**Definition** [GLTFProgram.h:28](_g_l_t_f_program_8h_source.xhtml#l00027)



[ANSYS::AVZ::GLTFWriter::Scene](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_scene.xhtml)

Scenes are the GLTFWriter class that create the view of the data that is defined in the GLTF file.

**Definition** [GLTFScene.h:29](_g_l_t_f_scene_8h_source.xhtml#l00028)



[ANSYS::AVZ::GLTFWriter::Scene::AppendMesh](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_scene.xhtml#a76e34d4c05fe34dde0fcc4913ad63981)

virtual bool AppendMesh(Node *mesh)=0



[ANSYS::AVZ::GLTFWriter::Shader](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_shader.xhtml)

Shaders are the GLSL executable code for vertex and fragment.

**Definition** [GLTFShader.h:26](_g_l_t_f_shader_8h_source.xhtml#l00025)



[ANSYS::AVZ::GLTFWriter::Technique](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml)

Techniques performs the rendering of primitives.

**Definition** [GLTFTechnique.h:240](_g_l_t_f_technique_8h_source.xhtml#l00239)



[ANSYS::AVZ::GLTFWriter::Technique::AppendState](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#a8b2b0766157324d5a2093a3fca36379f)

virtual bool AppendState(State *state)=0



[ANSYS::AVZ::GLTFWriter::Technique::AppendParameter](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_technique.xhtml#ae55c184b6165d5f1ea88e3db34522ba9)

virtual bool AppendParameter(Parameter *parameter)=0



[ANSYS::AVZ::GLTFWriter::Texture](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_texture.xhtml)

Textures are images that can be used to color a primitive.

**Definition** [GLTFTexture.h:28](_g_l_t_f_texture_8h_source.xhtml#l00027)



[ANSYS::AVZ::GLTFWriter::Utils::Repack](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml)

Manages repacking of indices from unsigned int type to unsigned short type. This only works for POINT...

**Definition** [GLTFUtils.h:106](_g_l_t_f_utils_8h_source.xhtml#l00105)



[ANSYS::AVZ::GLTFWriter::Utils::Repack::ConstructRepackAttribute](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a1487b86e5090019cf7565e144fe11e4f)

virtual const int * ConstructRepackAttribute(const unsigned int *indices, unsigned int attributeSize, const int *attributeData, unsigned int packNum)=0



[ANSYS::AVZ::GLTFWriter::Utils::Repack::NumAttributes](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a43a74d90484a85856103c33969eb7107)

virtual unsigned int NumAttributes(unsigned int packNum) const =0



[ANSYS::AVZ::GLTFWriter::Utils::Repack::NumElements](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a50e2eaf986369c115fe9cae008187cc0)

virtual unsigned int NumElements(unsigned int packNum) const =0



[ANSYS::AVZ::GLTFWriter::Utils::Repack::NumPacks](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#a69a383562c62ca71c8a785c96f773fb3)

virtual unsigned int NumPacks() const =0



[ANSYS::AVZ::GLTFWriter::Utils::Repack::ConstructRepackIndex](class_a_n_s_y_s_1_1_a_v_z_1_1_g_l_t_f_writer_1_1_utils_1_1_repack.xhtml#ab3bd7bca7382f17a0c08e144b67d22f2)

virtual const unsigned short * ConstructRepackIndex(const unsigned int *indices, unsigned int packNum)=0