15bd8deadSopenharmony_ciName 25bd8deadSopenharmony_ci 35bd8deadSopenharmony_ci MESAX_texture_stack 45bd8deadSopenharmony_ci 55bd8deadSopenharmony_ciName Strings 65bd8deadSopenharmony_ci 75bd8deadSopenharmony_ci GL_MESAX_texture_stack 85bd8deadSopenharmony_ci 95bd8deadSopenharmony_ciContact 105bd8deadSopenharmony_ci 115bd8deadSopenharmony_ci Ian Romanick, IBM (idr 'at' us.ibm.com) 125bd8deadSopenharmony_ci 135bd8deadSopenharmony_ciIP Status 145bd8deadSopenharmony_ci 155bd8deadSopenharmony_ci No known IP issues. 165bd8deadSopenharmony_ci 175bd8deadSopenharmony_ciStatus 185bd8deadSopenharmony_ci 195bd8deadSopenharmony_ci TBD 205bd8deadSopenharmony_ci 215bd8deadSopenharmony_ciVersion 225bd8deadSopenharmony_ci 235bd8deadSopenharmony_ci $Date: 2005/12/12$ $Revision: 0.3$ 245bd8deadSopenharmony_ci 255bd8deadSopenharmony_ciNumber 265bd8deadSopenharmony_ci 275bd8deadSopenharmony_ci 318 285bd8deadSopenharmony_ci 295bd8deadSopenharmony_ciDependencies 305bd8deadSopenharmony_ci 315bd8deadSopenharmony_ci OpenGL 1.2 or GL_EXT_texture3D is required. 325bd8deadSopenharmony_ci 335bd8deadSopenharmony_ci Support for ARB_fragment_program is assumed, but not required. 345bd8deadSopenharmony_ci 355bd8deadSopenharmony_ci Support for ARB_fragment_program_shadow is assumed, but not required. 365bd8deadSopenharmony_ci 375bd8deadSopenharmony_ci Support for EXT_framebuffer_object is assumed, but not required. 385bd8deadSopenharmony_ci 395bd8deadSopenharmony_ci Written based on the wording of the OpenGL 2.0 specification and 405bd8deadSopenharmony_ci ARB_fragment_program_shadow but not dependent on them. 415bd8deadSopenharmony_ci 425bd8deadSopenharmony_ciOverview 435bd8deadSopenharmony_ci 445bd8deadSopenharmony_ci There are a number of circumstances where an application may wish to 455bd8deadSopenharmony_ci blend two textures out of a larger set of textures. Moreover, in some 465bd8deadSopenharmony_ci cases the selected textures may vary on a per-fragment basis within 475bd8deadSopenharmony_ci a polygon. Several examples include: 485bd8deadSopenharmony_ci 495bd8deadSopenharmony_ci 1. High dynamic range textures. The application stores several 505bd8deadSopenharmony_ci different "exposures" of an image as different textures. On a 515bd8deadSopenharmony_ci per-fragment basis, the application selects which exposures are 525bd8deadSopenharmony_ci used. 535bd8deadSopenharmony_ci 545bd8deadSopenharmony_ci 2. A terrain engine where the altitude of a point determines the 555bd8deadSopenharmony_ci texture applied to it. If the transition is from beach sand to 565bd8deadSopenharmony_ci grass to rocks to snow, the application will store each texture 575bd8deadSopenharmony_ci in a different texture map, and dynamically select which two 585bd8deadSopenharmony_ci textures to blend at run-time. 595bd8deadSopenharmony_ci 605bd8deadSopenharmony_ci 3. Storing short video clips in textures. Each depth slice is a 615bd8deadSopenharmony_ci single frame of video. 625bd8deadSopenharmony_ci 635bd8deadSopenharmony_ci Several solutions to this problem have been proposed, but they either 645bd8deadSopenharmony_ci involve using a separate texture unit for each texture map or using 3D 655bd8deadSopenharmony_ci textures without mipmaps. Both of these options have major drawbacks. 665bd8deadSopenharmony_ci 675bd8deadSopenharmony_ci This extension provides a third alternative that eliminates the major 685bd8deadSopenharmony_ci drawbacks of both previous methods. A new texture target, 695bd8deadSopenharmony_ci TEXTURE_2D_STACK, is added that functions identically to TEXTURE_3D in 705bd8deadSopenharmony_ci all aspects except the sizes of the non-base level images. In 715bd8deadSopenharmony_ci traditional 3D texturing, the size of the N+1 LOD is half the size 725bd8deadSopenharmony_ci of the N LOD in all three dimensions. For the TEXTURE_2D_STACK target, 735bd8deadSopenharmony_ci the height and width of the N+1 LOD is halved, but the depth is the 745bd8deadSopenharmony_ci same for all levels of detail. The texture then becomes a "stack" of 755bd8deadSopenharmony_ci 2D textures. The per-fragment texel is selected by the R texture 765bd8deadSopenharmony_ci coordinate. 775bd8deadSopenharmony_ci 785bd8deadSopenharmony_ci References: 795bd8deadSopenharmony_ci 805bd8deadSopenharmony_ci http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=011557 815bd8deadSopenharmony_ci http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=000516 825bd8deadSopenharmony_ci http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=011903 835bd8deadSopenharmony_ci http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm 845bd8deadSopenharmony_ci 855bd8deadSopenharmony_ciIssues 865bd8deadSopenharmony_ci 875bd8deadSopenharmony_ci (1) Is "texture stack" a good name for this functionality? 885bd8deadSopenharmony_ci 895bd8deadSopenharmony_ci NO. However, I can't think of anything else that is better. 905bd8deadSopenharmony_ci 915bd8deadSopenharmony_ci (2) Should the R texture coordinate be treated as normalized or 925bd8deadSopenharmony_ci un-normalized? If it were un-normalized, floor(R) could be thought 935bd8deadSopenharmony_ci of as a direct index into the texture stack. This may be more 945bd8deadSopenharmony_ci convenient for applications. 955bd8deadSopenharmony_ci 965bd8deadSopenharmony_ci RESOLVED. All texture coordinates are normalized. The issue of 975bd8deadSopenharmony_ci un-normalized texture coordinates has been discussed in the ARB 985bd8deadSopenharmony_ci before and should be left for a layered extension. 995bd8deadSopenharmony_ci 1005bd8deadSopenharmony_ci (3) How does LOD selection work for stacked textures? 1015bd8deadSopenharmony_ci 1025bd8deadSopenharmony_ci RESOLVED. For 2D texture stacks the R coordinate is ignored, and 1035bd8deadSopenharmony_ci the LOD selection equations for 2D textures are used. For 1D 1045bd8deadSopenharmony_ci texture stacks the T coordinate is ignored, and the LOD selection 1055bd8deadSopenharmony_ci equations for 1D textures are used. The expected usage is in a 1065bd8deadSopenharmony_ci fragment program with an explicit LOD selection. 1075bd8deadSopenharmony_ci 1085bd8deadSopenharmony_ci (4) What is the maximum size of a 2D texture stack? Is it the same 1095bd8deadSopenharmony_ci as for a 3D texture, or should a new query be added? How about for 1D 1105bd8deadSopenharmony_ci texture stacks? 1115bd8deadSopenharmony_ci 1125bd8deadSopenharmony_ci UNRESOLVED. 1135bd8deadSopenharmony_ci 1145bd8deadSopenharmony_ci (5) How are texture stacks exposed in GLSL? 1155bd8deadSopenharmony_ci 1165bd8deadSopenharmony_ci RESOLVED. For now, they're not exposed at all. Mesa doesn't 1175bd8deadSopenharmony_ci currently support GLSL, so it's somewhat moot. 1185bd8deadSopenharmony_ci 1195bd8deadSopenharmony_ci When this extension is converted to MESA, EXT, or ARB, it is 1205bd8deadSopenharmony_ci expected that an additional samplers (e.g., sampler1DStack and 1215bd8deadSopenharmony_ci sampler2DStack) and texture lookup functions (e.g., texture1DStack and 1225bd8deadSopenharmony_ci texture2Dstack) will be added. 1235bd8deadSopenharmony_ci 1245bd8deadSopenharmony_ci (6) Should a 1D texture stack also be exposed? 1255bd8deadSopenharmony_ci 1265bd8deadSopenharmony_ci RESOLVED. For orthogonality, yes. 1275bd8deadSopenharmony_ci 1285bd8deadSopenharmony_ci (7) How are stacked textures attached to framebuffer objects? 1295bd8deadSopenharmony_ci 1305bd8deadSopenharmony_ci SEMI-RESOLVED. Slices of TEXTURE_2D_STACK textures are attached in 1315bd8deadSopenharmony_ci the same manner as slices of traditional 3D textures. 1325bd8deadSopenharmony_ci 1335bd8deadSopenharmony_ci TEXTURE_1D_STACK textures are a bit more tricky. This could be 1345bd8deadSopenharmony_ci handled one of two ways. The entire texture could be attached using 1355bd8deadSopenharmony_ci FramebufferTexture2DEXT, or a new function could be created that 1365bd8deadSopenharmony_ci would allow the attachment of a single 1D slice of the texture. The 1375bd8deadSopenharmony_ci spec currently uses the former, but the later may be more logical. 1385bd8deadSopenharmony_ci 1395bd8deadSopenharmony_ciNew Procedures and Functions 1405bd8deadSopenharmony_ci 1415bd8deadSopenharmony_ci None 1425bd8deadSopenharmony_ci 1435bd8deadSopenharmony_ciNew Tokens 1445bd8deadSopenharmony_ci 1455bd8deadSopenharmony_ci Accepted by the <cap> parameter of Enable, Disable, and IsEnabled, by 1465bd8deadSopenharmony_ci the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and 1475bd8deadSopenharmony_ci GetDoublev, and by the <target> parameter of TexImage3D, GetTexImage, 1485bd8deadSopenharmony_ci GetTexLevelParameteriv, GetTexLevelParameterfv, GetTexParameteriv, and 1495bd8deadSopenharmony_ci GetTexParameterfv: 1505bd8deadSopenharmony_ci 1515bd8deadSopenharmony_ci TEXTURE_1D_STACK_MESAX 0x8759 1525bd8deadSopenharmony_ci TEXTURE_2D_STACK_MESAX 0x875A 1535bd8deadSopenharmony_ci 1545bd8deadSopenharmony_ci Accepted by the <target> parameter of TexImage3D, 1555bd8deadSopenharmony_ci GetTexLevelParameteriv, and GetTexLevelParameterfv: 1565bd8deadSopenharmony_ci 1575bd8deadSopenharmony_ci PROXY_TEXTURE_1D_STACK_MESAX 0x875B 1585bd8deadSopenharmony_ci PROXY_TEXTURE_2D_STACK_MESAX 0x875C 1595bd8deadSopenharmony_ci 1605bd8deadSopenharmony_ci Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, 1615bd8deadSopenharmony_ci GetFloatv, and GetDoublev 1625bd8deadSopenharmony_ci 1635bd8deadSopenharmony_ci TEXTURE_1D_STACK_BINDING_MESAX 0x875D 1645bd8deadSopenharmony_ci TEXTURE_2D_STACK_BINDING_MESAX 0x875E 1655bd8deadSopenharmony_ci 1665bd8deadSopenharmony_ci Accepted by the <textarget> parameter of FramebufferTexture2DEXT: 1675bd8deadSopenharmony_ci 1685bd8deadSopenharmony_ci TEXTURE_1D_STACK_MESAX 1695bd8deadSopenharmony_ci 1705bd8deadSopenharmony_ci Accepted by the <textarget> parameter of FramebufferTexture3DEXT: 1715bd8deadSopenharmony_ci 1725bd8deadSopenharmony_ci TEXTURE_2D_STACK_MESAX 1735bd8deadSopenharmony_ci 1745bd8deadSopenharmony_ciAdditions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) 1755bd8deadSopenharmony_ci 1765bd8deadSopenharmony_ci None 1775bd8deadSopenharmony_ci 1785bd8deadSopenharmony_ciAdditions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) 1795bd8deadSopenharmony_ci 1805bd8deadSopenharmony_ci -- Section 3.8.8 "Texture Minification" in the section "Scale Factor and Level of Detail" 1815bd8deadSopenharmony_ci 1825bd8deadSopenharmony_ci Change the first paragraph (page 172) to say: 1835bd8deadSopenharmony_ci 1845bd8deadSopenharmony_ci "Let s(x,y) be the function that associates an s texture coordinate 1855bd8deadSopenharmony_ci with each set of window coordinates (x,y) that lie within a primitive; 1865bd8deadSopenharmony_ci define t(x,y) and r(x,y) analogously. Let u(x,y) = w_t * s(x,y), 1875bd8deadSopenharmony_ci v(x,y) = h_t * t(x,y), and w(x,y) = d_t * r(x,y), where w_t, h_t, 1885bd8deadSopenharmony_ci and d_t are as defined by equations 3.15, 3.16, and 3.17 with 1895bd8deadSopenharmony_ci w_s, h_s, and d_s equal to the width, height, and depth of the 1905bd8deadSopenharmony_ci image array whose level is level_base. For a one-dimensional 1915bd8deadSopenharmony_ci texture, define v(x,y) = 0 and w(x,y) = 0; for a two-dimensional 1925bd8deadSopenharmony_ci texture or a 2D texture stack, define w(x,y) = 0..." 1935bd8deadSopenharmony_ci 1945bd8deadSopenharmony_ci -- Section 3.8.8 "Texture Minification" in the section "Mipmapping" 1955bd8deadSopenharmony_ci 1965bd8deadSopenharmony_ci After the first paragraph (page 175) add: 1975bd8deadSopenharmony_ci 1985bd8deadSopenharmony_ci "For TEXTURE_2D_STACK_MESAX textures, d_b is always treated as 1995bd8deadSopenharmony_ci zero, regardless of the actual value, when performing mipmap 2005bd8deadSopenharmony_ci calculations." 2015bd8deadSopenharmony_ci 2025bd8deadSopenharmony_ci -- Section 3.8.15 "Texture Application" 2035bd8deadSopenharmony_ci 2045bd8deadSopenharmony_ci Change the first paragraph (page 189) to say: 2055bd8deadSopenharmony_ci 2065bd8deadSopenharmony_ci "Texturing is enabled or disabled using the generic Enable and Disable 2075bd8deadSopenharmony_ci commands, respectively, with the symbolic constants TEXTURE_1D, 2085bd8deadSopenharmony_ci TEXTURE_2D, TEXTURE_3D, TEXTURE_CUBE_MAP, TEXTURE_1D_STACK_MESAX, or 2095bd8deadSopenharmony_ci TEXTURE_2D_STACK_MESAX to enable one-, two-, three-dimensional, cube 2105bd8deadSopenharmony_ci map, or 2D texture stack texture, respectively. If both two- and 2115bd8deadSopenharmony_ci one-dimensional textures are enabled, the two-dimensional texture is 2125bd8deadSopenharmony_ci used. If the three-dimensional and either of the two- or one- 2135bd8deadSopenharmony_ci dimensional textures is enabled, the three-dimensional texture is 2145bd8deadSopenharmony_ci used. If the cube map texture and any of the three-, two-, or one- 2155bd8deadSopenharmony_ci dimensional textures is enabled, then cube map texturing is used. If 2165bd8deadSopenharmony_ci 1D texture stack is enabled and any of cube map, three-, two-, or 2175bd8deadSopenharmony_ci one-dimensional textures is enabled, 2D texture stack texturing is 2185bd8deadSopenharmony_ci used. If 2D texture stack is enabled and any of cube map, three-, 2195bd8deadSopenharmony_ci two-, one-dimensional textures or 1D texture stack is enabled, 2D 2205bd8deadSopenharmony_ci texture stack texturing is used..." 2215bd8deadSopenharmony_ci 2225bd8deadSopenharmony_ci -- Section 3.11.2 of ARB_fragment_program (Fragment Program Grammar and Restrictions): 2235bd8deadSopenharmony_ci 2245bd8deadSopenharmony_ci (mostly add to existing grammar rules) 2255bd8deadSopenharmony_ci 2265bd8deadSopenharmony_ci <optionName> ::= "MESAX_texture_stack" 2275bd8deadSopenharmony_ci 2285bd8deadSopenharmony_ci <texTarget> ::= "1D" 2295bd8deadSopenharmony_ci | "2D" 2305bd8deadSopenharmony_ci | "3D" 2315bd8deadSopenharmony_ci | "CUBE" 2325bd8deadSopenharmony_ci | "RECT" 2335bd8deadSopenharmony_ci | "1D_STACK" 2345bd8deadSopenharmony_ci | "2D_STACK" 2355bd8deadSopenharmony_ci 2365bd8deadSopenharmony_ci -- Add Section 3.11.4.5.4 Texture Stack Option 2375bd8deadSopenharmony_ci 2385bd8deadSopenharmony_ci "If a fragment program specifies the "MESAX_texture_stack" program 2395bd8deadSopenharmony_ci option, the <texTarget> rule is modified to add the texture targets 2405bd8deadSopenharmony_ci 1D_STACK and 2D_STACK (See Section 3.11.2)." 2415bd8deadSopenharmony_ci 2425bd8deadSopenharmony_ci -- Modify Section 3.11.6 Fragment Program Texture Instruction Set 2435bd8deadSopenharmony_ci 2445bd8deadSopenharmony_ci (replace 1st and 2nd paragraphs with the following paragraphs) 2455bd8deadSopenharmony_ci 2465bd8deadSopenharmony_ci "The first three texture instructions described below specify the 2475bd8deadSopenharmony_ci mapping of 4-tuple input vectors to 4-tuple output vectors. 2485bd8deadSopenharmony_ci The sampling of the texture works as described in section 3.8, 2495bd8deadSopenharmony_ci except that texture environments and texture functions are not 2505bd8deadSopenharmony_ci applicable, and the texture enables hierarchy is replaced by explicit 2515bd8deadSopenharmony_ci references to the desired texture target (i.e., 1D, 2D, 3D, cube map, 2525bd8deadSopenharmony_ci rectangle, 1D_STACK, 2D_STACK). These texture instructions specify 2535bd8deadSopenharmony_ci how the 4-tuple is mapped into the coordinates used for sampling. The 2545bd8deadSopenharmony_ci following function is used to describe the texture sampling in the 2555bd8deadSopenharmony_ci descriptions below: 2565bd8deadSopenharmony_ci 2575bd8deadSopenharmony_ci vec4 TextureSample(float s, float t, float r, float lodBias, 2585bd8deadSopenharmony_ci int texImageUnit, enum texTarget); 2595bd8deadSopenharmony_ci 2605bd8deadSopenharmony_ci Note that not all three texture coordinates, s, t, and r, are 2615bd8deadSopenharmony_ci used by all texture targets. In particular, 1D texture targets only 2625bd8deadSopenharmony_ci use the s component. 2D, RECT (non-power-of-two), and 1D_STACK texture 2635bd8deadSopenharmony_ci targets only use the s and t components. SHADOW1D texture 2645bd8deadSopenharmony_ci targets only use the s and r components. The descriptions of the 2655bd8deadSopenharmony_ci texture instructions below supply all three components, as would 2665bd8deadSopenharmony_ci be the case with CUBE, 3D, 2D_STACK, SHADOW2D, and SHADOWRECT targets." 2675bd8deadSopenharmony_ci 2685bd8deadSopenharmony_ciAdditions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations) 2695bd8deadSopenharmony_ci 2705bd8deadSopenharmony_ci -- 4.4.2.3 Attaching Texture Images to a Framebuffer 2715bd8deadSopenharmony_ci 2725bd8deadSopenharmony_ci Change the sixth paragraph to say: 2735bd8deadSopenharmony_ci 2745bd8deadSopenharmony_ci "If <textarget> is TEXTURE_RECTANGLE_ARB, then <level> must be zero. 2755bd8deadSopenharmony_ci If <textarget> is TEXTURE_3D or TEXTURE_2D_STACK , then <level> must 2765bd8deadSopenharmony_ci be greater than or equal to zero and less than or equal to log base 2 2775bd8deadSopenharmony_ci of MAX_3D_TEXTURE_SIZE..." 2785bd8deadSopenharmony_ci 2795bd8deadSopenharmony_ci Change the ninth paragraph to say: 2805bd8deadSopenharmony_ci 2815bd8deadSopenharmony_ci "For FramebufferTexture2DEXT, if <texture> is not zero, then 2825bd8deadSopenharmony_ci <textarget> must be one of: TEXTURE_2D, TEXTURE_1D_STACK, 2835bd8deadSopenharmony_ci TEXTURE_RECTANGLE_ARB, TEXTURE_CUBE_MAP_POSITIVE_X, 2845bd8deadSopenharmony_ci TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, 2855bd8deadSopenharmony_ci TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_Y, or 2865bd8deadSopenharmony_ci TEXTURE_CUBE_MAP_NEGATIVE_Z." 2875bd8deadSopenharmony_ci 2885bd8deadSopenharmony_ci Change the tenth paragraph to say: 2895bd8deadSopenharmony_ci 2905bd8deadSopenharmony_ci "For FramebufferTexture3DEXT, if <texture> is not zero, then 2915bd8deadSopenharmony_ci <textarget> must be TEXTURE_3D or TEXTURE_2D_STACK." 2925bd8deadSopenharmony_ci 2935bd8deadSopenharmony_ciAdditions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) 2945bd8deadSopenharmony_ci 2955bd8deadSopenharmony_ci None 2965bd8deadSopenharmony_ci 2975bd8deadSopenharmony_ciAdditions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) 2985bd8deadSopenharmony_ci 2995bd8deadSopenharmony_ci None 3005bd8deadSopenharmony_ci 3015bd8deadSopenharmony_ciAdditions to Appendix A of the OpenGL 2.0 Specification (Invariance) 3025bd8deadSopenharmony_ci 3035bd8deadSopenharmony_ci None 3045bd8deadSopenharmony_ci 3055bd8deadSopenharmony_ciAdditions to the AGL/GLX/WGL Specifications 3065bd8deadSopenharmony_ci 3075bd8deadSopenharmony_ci None 3085bd8deadSopenharmony_ci 3095bd8deadSopenharmony_ciGLX Protocol 3105bd8deadSopenharmony_ci 3115bd8deadSopenharmony_ci None 3125bd8deadSopenharmony_ci 3135bd8deadSopenharmony_ciDependencies on ARB_fragment_program 3145bd8deadSopenharmony_ci 3155bd8deadSopenharmony_ci If ARB_fragment_program is not supported, the changes to section 3.11 3165bd8deadSopenharmony_ci should be ignored. 3175bd8deadSopenharmony_ci 3185bd8deadSopenharmony_ciDependencies on EXT_framebuffer_object 3195bd8deadSopenharmony_ci 3205bd8deadSopenharmony_ci If EXT_framebuffer_object is not supported, the changes to section 3215bd8deadSopenharmony_ci 4.4.2.3 should be ignored. 3225bd8deadSopenharmony_ci 3235bd8deadSopenharmony_ciErrors 3245bd8deadSopenharmony_ci 3255bd8deadSopenharmony_ci None 3265bd8deadSopenharmony_ci 3275bd8deadSopenharmony_ciNew State 3285bd8deadSopenharmony_ci 3295bd8deadSopenharmony_ci None 3305bd8deadSopenharmony_ci 3315bd8deadSopenharmony_ciNew Implementation Dependent State 3325bd8deadSopenharmony_ci 3335bd8deadSopenharmony_ci None 3345bd8deadSopenharmony_ci 3355bd8deadSopenharmony_ciRevision History 3365bd8deadSopenharmony_ci 3375bd8deadSopenharmony_ci ||2005/11/15||0.1||idr||Initial draft version.|| 3385bd8deadSopenharmony_ci ||2005/12/07||0.2||idr||Added framebuffer object interactions.|| 3395bd8deadSopenharmony_ci ||2005/12/12||0.3||idr||Updated fragment program interactions.|| 340