Name ARB_shader_objects Name Strings GL_ARB_shader_objects Contributors Kurt Akeley Allen Akin Dave Baldwin Bob Beretta Pat Brown Matt Craighead Cass Everitt Evan Hart Phil Huxley Deron Dann Johnson Dale Kirkland John Kessenich Steve Koren Jon Leech Bill Licea-Kane Barthold Lichtenbelt Kent Lin Benjamin Lipchak Rob Mace Michael McCool Teri Morrison Jeremy Morris Glenn Ortner Randi Rost Jeremy Sandmel Folker Schamel Mik Wells Contact Barthold Lichtenbelt, 3Dlabs, Inc. (barthold 'at' 3dlabs.com) Randi Rost, 3Dlabs, Inc. (rost 'at' 3dlabs.com) IP Status As described in the Contributor License, which can be found at http://www.3dlabs.com/support/developer/ogl2/specs/3dlabs_contributor.pdf. Status Complete. Approved by the ARB on June 11, 2003. Updated revision 0.89 approved by the ARB on June 17, 2004. Version Last Modified Date: April 6, 2004 Author Revision: 0.89 Number ARB Extension #30 Dependencies OpenGL 1.0 is required. This extension is written against version 1.10 of the OpenGL Shading Language Specification. The extension is written against the OpenGL 1.4 Specification. Overview This extension adds API calls that are necessary to manage shader objects and program objects as defined in the OpenGL 2.0 white papers by 3Dlabs. The generation of an executable that runs on one of OpenGL's programmable units is modeled to that of developing a typical C/C++ application. There are one or more source files, each of which are stored by OpenGL in a shader object. Each shader object (source file) needs to be compiled and attached to a program object. Once all shader objects are compiled successfully, the program object needs to be linked to produce an executable. This executable is part of the program object, and can now be loaded onto the programmable units to make it part of the current OpenGL state. Both the compile and link stages generate a text string that can be queried to get more information. This information could be, but is not limited to, compile errors, link errors, optimization hints, etc. Values for uniform variables, declared in a shader, can be set by the application and used to control a shader's behavior. This extension defines functions for creating shader objects and program objects, for compiling shader objects, for linking program objects, for attaching shader objects to program objects, and for using a program object as part of current state. Functions to load uniform values are also defined. Some house keeping functions, like deleting an object and querying object state, are also provided. Although this extension defines the API for creating shader objects, it does not define any specific types of shader objects. It is assumed that this extension will be implemented along with at least one such additional extension for creating a specific type of OpenGL 2.0 shader (e.g., the ARB_fragment_shader extension or the ARB_vertex_shader extension). Issues 1) What to do if part of a shader pair is not present? DISCUSSION: There are several shader types that go together. For example, a VERTEX_SHADER and a FRAGMENT_SHADER form a pair that is part of the geometry pipeline. It is not required to supply both shader types of a pair in a program object. RESOLUTION: If one or the other of a pair is not present in the program object, OpenGL will substitute the standard 1.4 OpenGL pipeline for the one not present. The most likely place for this substitution to happen is the link stage. Note that it is defined elsewhere exactly what part of the OpenGL 1.4 pipeline a shader replaces. 2) Should source code string passed to ShaderSourceARB be null terminated? DISCUSSION: Source code strings should not be required to end with the byte 0. This is a programming language dependent concept, and interferes with loading source code out of files. (Memory mapping read-only files leaves no ability to add a 0 at the end without an extra copy). Development of shaders can be from files, not necessarily from embedded source. If null termination was required a shader's source code would be read from a file, based on an address and a length, then get copied to add a 0 on, then are passed to the compiler which promptly goes and finds the 0, in order to get back to an address and a length. That is all useless work. RESOLUTION: It is allowed, but not required, to have a null termination at the end of the string. If the string is null terminated, OpenGL can find out the length of the string, and the length parameter passed in can be set to negative one. 3) Should the string passed in to GetUniformLocationARB be null terminated? DISCUSSION: It is not very likely that this will be a memory mapped file, therefore null termination can be assumed. RESOLUTION: Yes. 4) Should the string returned by GetInfoLog be null terminated? DISCUSSION: In this case it is useful to have the info string be null terminated, so it can be passed to printf() directly. All other strings returned by the GL are also null terminated. RESOLUTION: YES 5) Should GetInfoLog also return the length of the string? DISCUSSION: This applies to an older version of GetInfoLog, but is no longer applicable. RESOLUTION: N/A 6) Do we need a new GLcharARB data type to handle input strings? DISCUSSION: Currently there is no precedence of passing in strings into OpenGL. This exposes a deficiency in OpenGL data types. In C++ a literal string is of type char. OpenGL only has GLubyte and GLbyte data types, defined as being unsigned char and signed char respectively. This means that it is not possible to pass a literal string to OpenGL using either GLubyte or GLbyte. For example, GetUniformLocationARB(programObj, "Offset") needs to have the prototype GetUniformLocationARB(handleARB obj, const char *string). RESOLUTION: YES 7) Do we load uniforms using their string representation? DISCUSSION: Loading uniforms is still performance sensitive, although not as much as vertex attributes. Passing in a string into the load uniform command seems too big of a performance hit. Every time the load is called the string needs to be parsed and the location for the data computed. It is better to move this performance cost outside the load uniform command into GetUniformLocationARB. RESOLUTION: NO. 8) Should Uniform*ARB take a program object as a parameter? DISCUSSION: Again, this is a performance issue. If it does, the object passed in needs to be validated for every uniform loaded. Instead, move this validation cost outside the uniform command, and have the uniform command modify uniforms for the currently in use program object (Set by UseProgramObjectARB). The validation cost is now much lower. The program object is validated once, when calling UseProgramObjectARB. RESOLUTION: NO. 9) Should uniform values be state per program object? DISCUSSION: Should values loaded for uniforms be kept in a program object, so that they are retained across program object switches? This is application friendly. However, loading uniforms becomes a bit more of a heavy weight operation because the OpenGL implementation now has to store its values with the program object, and reload when the program object is made current, even if the previous program object already had the same uniform values loaded. RESOLUTION: YES. We don't want to force an application to re-load its uniforms every time a program object is used. 10) Should the name space for uniforms be global per program object? DISCUSSION: If one shader object references a uniform called "foo" and another shader object, attached to the same program object, also references "foo", are those shaders referencing the same uniform? If they do not reference the same uniform values, uniforms now need to be state per shader object and loaded per shader object. Also, if a vertex shader references "foo" and the accompanying fragment shader also references "foo", it would make sense to expect those to be the same uniform reference. RESOLUTION: YES. 11) What to do if no value is loaded for a uniform? DISCUSSION: A program object can be used and rendering commenced without loading values for all the uniforms referenced in its shader objects. What to do in this case? Note that the values of the uniforms are state belonging to the program object. Once loaded, these values are reused whenever the program object is in use again. Should uniforms have an initial value? RESOLUTION: Uniforms are initialized to zero. 12) Should it be allowed to load uniforms in a display list? DISCUSSION: Doing so will make the display list tied to a program object. The location passed in to the load uniform commands is program object specific. However, this can still be useful for some applications. If a program object is in use at CallList time which does not match that display list, then all bets are off. See also issue 30. RESOLUTION: YES 13) Do we need uniforms that are local to a program object and uniforms that are globally accessible by all program objects? DISCUSSION: ARB_vertex_program has this functionality. It seems convenient to be able to set a uniform once, and have its value be accessible across many shaders (for example, a uniform used to set a light position). This type of global uniform could be a performance win as well, its value does not have to be cached by OpenGL per program object, and re-loaded at every program object switch. RESOLUTION: This is useful, but for this version of the spec this functionality is deferred. 14) Do we need INT, FLOAT and BOOL versions of the load uniform commands? DISCUSSION: There are two types to keep separate. The type the uniform is declared in the shader, and the type of the data the application uses for uniform values. There are three basic uniform types that can be declared in a shader: Float, Int and Bool. Thus one can envision an API where the uniform type is encoded in the API name, besides the application's data type. For example, UniformInt3iv(). Where the word 'Int' encodes the uniform type, and 'iv' the user input data type. On the other hand, the uniform type information is known to the GL, and therefore encoding it in the API name is redundant. RESOLUTION: We won't encode the uniform type in the API name. 15) There is the potential for a huge explosion of load uniform commands, what to do? DISCUSSION: We need to be able to load a vec1, vec2, vec3, or vec4, or arrays of vec1, arrays of vec2, arrays of vec3 or arrays of vec4. Furtheremore, there is a need to also load 2x2, 3x3 and 4x4 matrices, and arrays of 2x2, arrays of 3x3 and arrays of 4x4 matrices. The input values to the load uniforms commands can (traditional OpenGL) come in bytes, shorts, ints, floats, doubles and unsigned bytes, unsigned shorts and unsigned ints. RESOLUTION: A suggested subset is in the New Procedures and Functions section below. 16) Should a special INVALID_HANDLE for the data type handleARB be provided, or is 0 sufficient? DISCUSSION: 0 is fine. There are less code defects if code compares to zero than some invalid handle that is defined to zero anyway. Applications should not compare to NULL, since NULL is not necessarily defined to be zero in C, only in C++. Besides, a handleARB is an integer. RESOLUTION: YES. 17) What happens if the currently in use program object is re-linked by calling LinkProgramARB? DISCUSSION: Consider that the currently in use program object has a uniform named "foo". The application changed some code around in that program object, and still has a uniform named "foo", then calls LinkProgramARB. After this link call the location of "foo" does not have to be the same as before the link call. If LinkProgramARB does not imply a call to UseProgramObjectARB, then a call to Uniform*ARB to load a value for "foo" is ill defined. In this case, does the application use the old location of "foo" or the new location? It is consistent with other parts of OpenGL to have updates to an object take effect after the update without issuing another command to make the update active, for example the TexSubImage* commands. RESOLUTION: The re-linked program will be used automatically, without requiring a new call to UseProgarmObjectARB. 18) Should object handles be allocated by the application or by OpenGL? DISCUSSION: For current OpenGL objects such as textures and display lists, object Ids can be assigned by the application. The Id name space is unique for texture objects and display lists. This resulted in a different API for generating and managing texture Ids or Display List Ids. It is not desirable to keep the same mechanism for general object management. It prevents the definition of generic operations on objects such as deletion and querying. It prevents the OpenGL implementation from managing the name space the way it sees fit. It is much more common for the underlying library to allocate and manage handles and thereby keep control of the name space. It can make using a third party supplied library harder or even impossible. RESOLUTION: Object handles should be allocated and its name space managed by OpenGL, not by the application. 19) Should a handle be opaque to the application? DISCUSSION: A handle is only read and written by OpenGL. Therefore the interpretation of the value of the handle does not need to be exposed to the application. However, we will expose how a handle is implemented. Certain implementation choices for handles, like a pointer, are discouraged. The practical solution seems to be to make a handle an integer. RESOLUTION: YES. 20) Do we need a way to get the source code back from a shader object? DISCUSSION: To stay with the OpenGL philosophy that any state that can be set also be queried, we need such a get. This function will return the last set of strings stored in a shader object. Note that this set of strings is not necessarily the same as the set of strings that compiled and linked into program object currently in use. RESOLUTION: YES, this is achieved through GetShaderSourceARB. 21) Are the limits on all resources an executable uses queriable and known to the application? DISCUSSION: Various proposals have been discussed. One very important consideration is to end up with a specification that provides application portability (e.g., ISVs do not need to support multiple rendering back ends in order to run on all the different flavors of hardware). ISVs definitely would prefer the specification to say that the OpenGL Shading Language implementation is responsible for ensuring that all valid shaders must run. RESOLUTION: Resources that are easy to count (number of uniforms available to a vertex shader, number of uniforms available to a fragment shader, number of vertex attributes, number of varyings, number of texture units) will have queriable limits. The application is responsible for working within these externally visible limits. The OpenGL Shading Language implementation is responsible for virtualizing resources that are not easy to count (for example, the number of machine instructions in the final executable, number of temporary registers used in the final executable, etc.). The expectation is that for any practical application an executable (generated by the link stage) will run. 22) Should a higher level shading language be layered on top of OpenGL instead of being designed to fit within OpenGL? DISCUSSION: In the current design, the OpenGL Shading Language is integrated into OpenGL and just provides alternative methods to the state controlled pipeline of OpenGL 1.4. The Stanford approach is to layer their shading language on top of OpenGL. This has some advantages and disadvantages that will become apparent when the differences are examined. The Stanford approach uses a higher abstraction level. This helps with writing some kinds of programs where the abstractions match the problem domain. For example treating lights and surfaces as abstract entities makes some 3D graphics operations easier, however OpenGL is now being used for video and image processing where this abstraction is largely irrelevant. Similarly many games have shunned lighting via traditional means and use textures (light maps) instead. There is nothing in the OpenGL Shading Language or bindings that prevent higher levels of abstractions from being layered on top of a programmable OpenGL. We also wish to keep the overall abstraction level of OpenGL at its current level. The Stanford approach also provides for different computational frequencies. By having the higher levels of abstraction where one program defines the current graphics operation in total allows the compiler to separate out the parts that need to run at the primitive group level, primitive level, vertex level and fragment level. The compiler can therefore generate the code to run on the CPU, vertex processor and fragment processor as appropriate. This is obviously more complicated to implement than having the programmer specify the programs to run on each part of the pipeline (although some hints are still required by the Stanford language), although this does make the virtualization of the hardware easier as the compiler has the overall view. The major disadvantage of this is that it forces more intrusive changes to OpenGL to support the clear delineation of the primitives, vertices and fragment operations. Many of the core OpenGL features have been replaced. An advantage of the current approach is that the look and feel of OpenGL 1.4 is maintained and it allows a graceful mix and match approach during the transition period from fixed functionality to full programmability. This is not a criticism of the Stanford work, as they had no choice but to layer on top of OpenGL. RESOLUTION: The OpenGL Shading Language should be built into OpenGL, and not layered on top. It is also noted that if this is not the case, OpenGL should still have a standard shading language. 23) Should an error be set if a glUseProgramObjectARB call is made on a program object that has not been successfully linked? DISCUSSION: This was an issue when UseProgramObject returned a Boolean indicating success or failure. However, it no longer does, thus an error has to be generated. RESOLUTION: YES 24) Do we need a way to get object code back, just like the model of C on host processors? DISCUSSION: Lots in email on the arb-gl2 mailing list. This is about lowest-level, machine specific code that may not even be portable within a family of cards from the same vendor. One main goal is to save compilation time. There seems to be general consensus that this has merit. RESOLUTION: This is an interesting capability to have, but will be deferred to the next release or could be added as a separate extension. 25) How are samplers used to access textures? DISCUSSION: Samplers are special uniforms used in the OpenGL Shading Language to identify the texture object used for each texture lookup. The value of a sampler indicates the texture image unit being accessed. The type of the sampler identifies the target on that texture image unit. The texture object bound to that texture image unit's target is then used for the texture lookup. For example, a variable of type sampler2D selects target TEXTURE_2D on its texture image unit. Binding of texture objects to targets is done as usual with BindTexture. Selecting the texture image unit to bind is done as usual with ActiveTexture. The location of a sampler needs to be queried with GetUniformLocationARB, just like any uniform variable, and its value needs to be set by calling Uniform1i{v}ARB. In the future, sampler types might allow for binding a texture object directly, instead of binding to a texture image unit first, to get to a texture object. RESOLUTION: Resolved 26) Do we need a validation command as a developers aid? DISCUSSION: The LinkProgramARB command will check if the code in all shaders in the program object will link. It will catch things like having too many active samplers, a mismatch between varyings in a vertex and fragment shader, etc. However, it will not check for any errors related to the values of uniforms or inconsistent OpenGL state that would result in undefined behavior or worse, prevent a program object from executing. A validation command could check for things like a mismatch between a shadow texture lookup and no TEXTURE_COMPARE_MODE set. Or check for values of samplers being out of range. Or check for samplers of different types being used to access the same texture image unit, etc. This validate command will at least do all the validation that needs to occur at render time, and it could do anything extra that might help the developer understand their shader(s) better. Note that it is not necessary to call validate, it only is a development tool. RESOLUTION: YES, this is a desirable feature. 27) Should there be an info log per object? DISCUSSION: To store the info log per object created is consistent with the whole object model. However, it might not be useful to keep an info log around till the object is deleted. It does take resources away from the system. Hence we could keep one info log per object type (shader or program objects) as not to take too many resources. Alternatively, the specification could say that at least one info log is kept per object type, but that the GL implementation is free to keep more. This was considered in an earlier version of this specification, but broke down when considering the life time of an info log in a multi-context situation. Note that in either case the API definition for GetInfoLogARB does not change. The application passes in a handle for the object, and if the info log does not exist it returns an empty string. RESOLUTION: We will have an info log per object, and not worry about the resource usage. 28) Is there a need to have a command to append source code to a shader object? DISCUSSION: AppendShaderARB facilitates applications that generate shaders on the fly. Developers can pass parts of a shader source to OpenGL this way. However, the application can do the same thing in its own memory buffer, and then pass the whole shader to OpenGL using ShaderSourceARB. The application usually doesn't have to copy or concatenate strings together. It can build a list of strings and pass those to OpenGL all at once using ShaderSourceARB. RESOLUTION: No, this is deemed not necessary. 29) Should loading the source code into a shader object automatically invoke a compilation? DISCUSSION: Keeping the loading of source and compilation of the source as two distinctive API commands makes it possible for the application to control when an expensive operation like a compile is done. For example, it could first load all source for all its shaders at startup, and compile them as needed through the execution of the application. Keeping it separate leaves the most control to the application. RESOLUTION: No. 30) What happens if an application tries to load more values in a uniform than its declared extent? DISCUSSION: It is possible to run off the end of a uniform, which could potentially corrupt other uniforms, or any data that is stored by OpenGL at the position next to the uniform. Since it is not known, nor desirable to dictate, where an implementation stores its uniforms, it cannot be defined what happens when a load uniform command runs off the end. While enforcing bounds checking is potentially expensive and can cost a good deal of performance, the safety provided by bounds checking is considered more important than the highest possible uniform loading performance. Note also that the OpenGL Shading Language states that it is undefined when a shader references an array element outside the array bounds. RESOLUTION: The GL implementation must do whatever bounds checking is necessary while loading uniforms. Applications that would like the highest API performance should strongly consider using vertex attributes for a small number of frequently changing values. 31) Should UseProgramObjectARB be display-list-able? DISCUSSION: Consider a geometric object consisting of multiple primitives. The primitives within this geometric object are rendered using different shaders. The only way to encapsulate this into one display list is by allowing UseProgramObjectARB to be compiled into a display list. If this is not allowed, then the geometric object has to be broken up in potentially many display lists, creating a management nightmare for ISVs. ARB_vertex_program allows BindProgramARB to be compiled into a display list. Thus when using ARB_vertex_program it is possible to achieve the scenario described above. UseProgramObjectARB will generate a GL error if its operation failed, so that applications can still check if it succeeded. RESOLUTION: Yes 32) Can you explain how uniform loading works? DISCUSSION: Uniform variables, including samplers, are named and declared in a shader. This name is a string and needs to be used in GetUniformLocationARB to retrieve a location ID. Once this location ID has been retrieved it won't change until the next call to LinkProgramARB. After LinkProgramARB has been issued, the application will have to query the location IDs of uniform variables again. LinkProgramARB will initialize all uniforms to zero. Note that GetUniformLocationARB will only return a location ID if the uniform is part of the set of active uniforms, else it will return -1. The set of active uniforms, for a given program object, can be queried with GetActiveUniformARB. Once the location ID is obtained, it can be used in the Uniform*ARB commands to load value(s) for the uniform. Note that the Uniform*ARB command used has to match the size and the type of the uniform variable. GetUniformLocationARB can only retrieve location IDs for uniforms declared as a basic type (float, int, bool and vectors thereof) and arrays of basic types. It is not possible to query the location ID of a structure, for example. The application will have to break down the structure into its fields until it has reached a basic type or an array of basic type. It does this by using the "." (dot) and "[]" operations in the name string passed to GetUniformLocationARB. It is possible to query the location ID of an element K in an array. It is possible to use that location ID to load multiple values into an array starting at that location K. However, it is not possible to take that location ID and add an integer N to that location ID to advance to element K + N in that array. The application will have to query the location ID of array element K + N separately. For example, consider the following structure: struct { struct { float a; float b[10]; } c[2]; vec2 d; } e; loc1 = GetUniformLocationARB(programObject, "e.d") is a valid command. loc2 = GetUniformLocationARB(programObject, "e.c[0]") is not valid. loc3 = GetUniformLocationARB(programObject, "e.c[0].b") is a valid command. loc4 = GetUniformLocationARB(programObject, "e.c[0].b[2]") is a valid command. The location loc2 cannot be retrieved because "e.c[0]" references a structure. Uniform2fARB(loc1, 1.0f, 2.0f) is a valid command. Uniform2iARB(loc1, 1, 2) is not. loc1 references a vec2, not an ivec2. Uniform1fARB(loc1, 1.0f) is not. loc1 references a vec2, not a float. Uniform1fvARB(loc3, 10, floatPtr) is a valid command. Uniform1fvARB(loc4, 10, floatPtr) is not. It runs off the end of the array. Uniform1fvARB(loc4, 8, floatPtr) is a valid command. RESOLUTION: Yes 33) Should automatic conversion of input data types be done when loading uniforms? DISCUSSION: In other words, if the application passes an integer to the uniform loading commands, and the uniform is declared as a float, should automatic type conversion of that integer to a float occur? The vertex attribute loading commands do this, for example. OpenGL specifies that this kind of type conversion is dependent on the usage of the data. Color, normals and depth components are normalized and converted to floats as specified in Table 2.6. Other components are not normalized before conversion to float. However, generally it is not known what a uniform is used for. It is hard to imagine that it is useful for an application to pass in data that is declared as a different type in the shader. In that case the type of the uniform in the shader could be matched to the application's data type instead. RESOLUTION: NO. If the basic type of the uniform is float, then Uniform*f{v}ARB will have to be used. If the basic type of the uniform is integer, then Uniform*i{v}ARB will have to be used. If the basic type of the uniform is a sampler, then Uniform1i{v}ARB will have to be used. Since there is no Boolean type in C (and we are defining C bindings) but there is a Boolean type in the OpenGL Shading Language, type conversion needs to be done. It is allowed to either pass in floats or integers if the uniform is declared as a boolean. If the basic type of the uniform is a Boolean, then either Uniform*f{v}ARB or Uniform*i{v}ARB can be used. Note that the uniform loading API can later be extended to allow for automatic type conversion, with and without normalization, if it turns out that is desired. 34) Why introduce the new terms "Use" and "Create"? DISCUSSION: This question refers to glUseProgramObjectARB, glCreateShaderObjectARB and glCreateProgramOBjectARB. We could have defined glNewShaderObjectARB, glNewProgramObjectARB and left off the "Use" in glUseProgramOBjectARB, resulting in glProgramObjectARB. RESOLUTION: "New" is used for an existing function name (glNewList) that takes a name as input, instead of returning a handle. We deliberately chose "Create" for functions that return handles. Similarly "Use" is used in a function name that takes a handle as input. Different names make it clear to the developer that there are different semantics. 35) How is a uniform array treated when only some of the array elements are actually used? DISCUSSION: We have two goals in mind: 1) To be able to always load a uniform array starting from offset 0 into the array. 2) To keep the list of active uniforms as small as possible. RESOLUTION: For a uniform array declared in a shader, GetActiveUniformARB() will return the name of the array, its basic type and a count. This count is determined by the highest element used in the shader (as determined by the linker / compiler). If the shader doesn't use the array at all, then the GL should obviously not report it as an active uniform. Loading more data for the array, using Uniform*ARB, than the count returned by GetActiveUniformARB is allowed. The extra data is silently ignored (sent to the bit-bucket). For example, consider the array: uniform vec3 a[10]; Which is used in a shader that uses elements 3 and 7 in this array. GetActiveUniformARB will return: "a" - the name of the array 8 - The size of the array (based on the highest element used, 7) FLOAT_VEC3_ARB - The type Since array elements 0 through 7 are active, the application can query the locations for elements 0, 1, 2, 3, 4, 5, 6, 7 using GetUniformLocationARB(). Loading data for this array using a count of 10 (not 8) is allowed. Thus it is legal to issue: location = GetUniformLocation(progObj, "a"); LoadUniform3fv(location, 10, dataPtr); This will load data into array elements 0 through 7, since only array elements 0 through 7 are active, and will ignore the rest of the data. Array data is queried one element at a time. In order to query any uniform, a location needs to be provided by the application. Therefore, in this example, the application can query data for array elements 0 through 7, but not for elements 8 and 9. This makes array loading portable, independent of the smartness of the compiler / linker. It also encourages shader writers to start using array elements starting at zero, and work their way upwards, to get maximum resource efficiency from the OpenGL implementation. It also works nicely with auto-sized uniform arrays (an array declared with empty brackets "[]" and indexed only with compile time constants). 36) Should a location of -1 passed in to Uniform*ARB generate a GL error? DISCUSSION: The Uniform*API commands will set an INVALID_OPERATION error when passing in a location that does not exist. GetUniformLocationARB will return -1 if the string passed in is not an active uniform, or if it starts with the prefix "gl_". (This means you cannot get a location for active built-in uniforms, for example gl_ModelviewMatrix). If you're looping over GetUniformLocationARB and passing the result to one of the Uniform*ARB commands, and if any -1 location passed to Uniform*ARB will generate a GL error, then this means that you should really bracket your Uniform*ARB command with a 'if (location != -1) statement. It seems desireable to not generate a GL error when -1 is passed in as a location to Uniform*ARB. The data passed in should then be silently ignored. RESOLUTION. NO. Note that this has changed since the version 0.87 (which was published in the extension registry). That version did set an error when passing in a location of -1. 37) What should the behavior of glDeleteObject(0) be? DISCUSSION: It would be desirable to allow 0 as a valid input value, and not raise an error. RESOLUTION: glDeleteObject() will silently ignore deleting the value 0. This is consistent with glDeleteTextures() that also silently ignores deleting the value 0. 38) It is unclear how GetUniform*ARB works for matrices. Is the data returned in column or row major order? DISCUSSION: glGet(MODEL_VIEW_MATRIX) returns data in column major order. It was discussed, but rejected, to add two new commands to return matrices in column or row major order: void GetUniformMatrixfvARB(handleARB programObj, int location, boolean transpose, float *params) void GetUniformMatrixivARB(handleARB programObj, int location, boolean transpose, float *params) RESOLUTION: GetUniformARB will return data in column major order, regardles of the transpose flag used to set the matrix in the LoadUniform*ARB commands. 39) Do "const" qualified variables consume uniform word storage, or not? RESOLUTION: They do not. 40) What happens when a program object currently in use is re-linked, and this re-link fails? DISCUSSION: This should not affect the executable(s), part of the current rendering state. As opposed to revert to fix pipeline for example. RESOLUTION: The currently active executable code will be kept until changed or the program has been linked successfully. 41) What happens when an empty program object (one with no shader objects attached) is linked? DISCUSSION: Linking a program object with just a vertex shader will get you fixed- function fragment processing. Vice versa, linking a program object with just a fragment shader gets you fixed-function vertex processing. RESOLUTION: This will succeed and in this case you get the fixed pipeline for both vertex and fragment processing if UseProgramObject() is issued for this program object. 42) How to indicate the first element of an array when requesting a uniform location? DISCUSSION: There is a desire to have the location of the first element of an array be indicated either using the name of the uniform array, or by using the name appended with "[0]". That would mean the following: uniform s a[1]; // Where 's' is some struct with a field 'f' that is a float. The following string combinations could be formed to pass into GetUniformLocation: a[0].f a.f If 'f' is an array float f[1] then the following string combinations could be formed to pass into GetUniformLocation: a[0].f[0] a[0].f a.f[0] a.f RESOLUTION: The spec is changed so that in the middle of a string it is mandatory to use [0]. Thus that means that only the following two strings are valid to pass to GetUniformLocation: a[0].f a[0].f[0] 43) What does GetActiveUniformARB() report for the following two uniforms? DISCUSSION: Consider shader code with: uniform float a[1]; uniform float a; The size reported by GetActiveUniformARB() will be '1', and the type reported will be float. The string reported can be 'a' in both cases, or can be 'a[0]' in the array case. In other words, from this data it is not clear to the application if 'a' is an array of size one or a scalar. Reporting 'a[0]' is the recommended way for the array case. Technically it doesn't really matter, since it is legal to address the first element of an array with 'a' or 'a[0]' and pass either string into GetUniformLocation. RESOLUTION: The GL implementation can report either string. However, it is recommended to return 'a[0]'. 44) Do GL enables affect the built-in state available to a shader? DISCUSSION: The lighting state, for example, is still tracked and kept current even when lighting, or a specific light, is disabled. This goes for all built-in state listed in Chapter 7.5 of the OpenGL Shading Language Specification. Do realize that the enables VERTEX_PROGRAM_POINT_SIZE and VERTEX_PROGRAM_TWO_SIDE do need to be enabled by the application, to get their desired effect. RESOLUTION: Enable state is a piece of orthogonal state that is not available to a shader. The enable state does not affect the built-in state that is available to a shader, which is listed in Chapter 7.5 of the OpenGL Shading Language specification. 45) Please give an example of using the uniform API. DISCUSSION: Below are two examples. The first one queries each active uniform, then loads a value for it. The second example works of a list of uniforms, and queries their locations. Some of the uniforms in that list might not be active. // // Example code that queries active uniforms, then loads their values // void example1(GLhandleARB programObject) { int i, count, size, type, linked, location; char uniformName[1000]; // Link the program object and make sure it succeeded. glLinkProgramARB(programObject); glGetObjectParameterivARB(programObject, GL_OBJECT_LINK_STATUS_ARB, &linked); if (!linked) { return; } // Install the executables in the program object as part of current state. glUseProgramObjectARB(programObject); // Check for GL Errors // Setup uniform values in the array 'colorInterior'. // Query the number of active uniforms glGetObjectParameterivARB(programObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); // Loop over each of the active uniforms, and set their value for (i = 0; i < count; i++) { glGetActiveUniformARB(programObject, i, 1000, NULL, &size, &type, uniformName); printf("active uniform: %s\n",uniformName); location = glGetUniformLocationARB(programObject, uniformName); if (type == GL_FLOAT_VEC3_ARB) { float *data; // Allocate data based on 'size' // do some kind of hash lookup on the uniform name to get the // data to load for the uniform. lookupUniformData(uniformName, data); // This a vec3, therefore need to use the '3f' or '3fv' version // of the uniform loading commands. glUniform3fvARB(location, size, data); } // else : Setup more types here } } // // Example code that has a list of uniforms, and loads values for each uniform // in the list. Not all uniforms have to be active ones. // void example2(GLhandleARB programObject) { int i, count, linked, location; char **uniformName; float *data; // Link the program object and make sure it succeeded. glLinkProgramARB(programObject); glGetObjectParameterivARB(programObject, GL_OBJECT_LINK_STATUS_ARB, &linked); if (!linked) { return; } // Install the executables in the program object as part of current state. glUseProgramObjectARB(programObject); // Check for GL Errors // Setup uniform values in the array 'data'. // Setup 'count' and the array 'uniformName' // Loop over the list of uniforms in uniformName, and set their value for (i = 0; i < count; i++) { // Location will be -1 if the uniform is not active, but that is OK // the uniform loading commands will silently ignore a location of -1. location = glGetUniformLocationARB(programObject, uniformName[i]); // This a a vec3, therefore need to use the '3f' or '3fv' version of // the uniform loading command. glUniform3fvARB(location, 1, &data[i * 3]); } } 46) Should we add capability to query if an object is dirty? DISCUSSION: Specifically, do we add a way to query if a program object needs relinking? Do we add a way to query if a shader object needs re-compilation? RESOLUTION: No, the application can keep track of this information as well. Mipmap state consistency is not queriable either, for example. New Procedures and Functions void DeleteObjectARB(handleARB obj) handleARB GetHandleARB(enum pname) void DetachObjectARB(handleARB containerObj, handleARB attachedObj) handleARB CreateShaderObjectARB(enum shaderType) void ShaderSourceARB(handleARB shaderObj, sizei count, const charARB **string, const int *length) void CompileShaderARB(handleARB shaderObj) handleARB CreateProgramObjectARB(void) void AttachObjectARB(handleARB containerObj, handleARB obj) void LinkProgramARB(handleARB programObj) void UseProgramObjectARB(handleARB programObj) void ValidateProgramARB(handleARB programObj) void Uniform1fARB(int location, float v0) void Uniform2fARB(int location, float v0, float v1) void Uniform3fARB(int location, float v0, float v1, float v2) void Uniform4fARB(int location, float v0, float v1, float v2, float v3) void Uniform1iARB(int location, int v0) void Uniform2iARB(int location, int v0, int v1) void Uniform3iARB(int location, int v0, int v1, int v2) void Uniform4iARB(int location, int v0, int v1, int v2, int v3) void Uniform1fvARB(int location, sizei count, const float *value) void Uniform2fvARB(int location, sizei count, const float *value) void Uniform3fvARB(int location, sizei count, const float *value) void Uniform4fvARB(int location, sizei count, const float *value) void Uniform1ivARB(int location, sizei count, const int *value) void Uniform2ivARB(int location, sizei count, const int *value) void Uniform3ivARB(int location, sizei count, const int *value) void Uniform4ivARB(int location, sizei count, const int *value) void UniformMatrix2fvARB(int location, sizei count, boolean transpose, const float *value) void UniformMatrix3fvARB(int location, sizei count, boolean transpose, const float *value) void UniformMatrix4fvARB(int location, sizei count, boolean transpose, const float *value) void GetObjectParameterfvARB(handleARB obj, enum pname, float *params) void GetObjectParameterivARB(handleARB obj, enum pname, int *params) void GetInfoLogARB(handleARB obj, sizei maxLength, sizei *length, charARB *infoLog) void GetAttachedObjectsARB(handleARB containerObj, sizei maxCount, sizei *count, handleARB *obj) int GetUniformLocationARB(handleARB programObj, const charARB *name) void GetActiveUniformARB(handleARB programObj, uint index, sizei maxLength, sizei *length, int *size, enum *type, charARB *name) void GetUniformfvARB(handleARB programObj, int location, float *params) void GetUniformivARB(handleARB programObj, int location, int *params) void GetShaderSourceARB(handleARB obj, sizei maxLength, sizei *length, charARB *source) New Tokens Accepted by the argument of GetHandleARB: PROGRAM_OBJECT_ARB 0x8B40 Accepted by the parameter of GetObjectParameter{fi}vARB: OBJECT_TYPE_ARB 0x8B4E OBJECT_SUBTYPE_ARB 0x8B4F OBJECT_DELETE_STATUS_ARB 0x8B80 OBJECT_COMPILE_STATUS_ARB 0x8B81 OBJECT_LINK_STATUS_ARB 0x8B82 OBJECT_VALIDATE_STATUS_ARB 0x8B83 OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 Returned by the parameter of GetObjectParameter{fi}vARB: SHADER_OBJECT_ARB 0x8B48 Returned by the parameter of GetActiveUniformARB: FLOAT 0x1406 FLOAT_VEC2_ARB 0x8B50 FLOAT_VEC3_ARB 0x8B51 FLOAT_VEC4_ARB 0x8B52 INT 0x1404 INT_VEC2_ARB 0x8B53 INT_VEC3_ARB 0x8B54 INT_VEC4_ARB 0x8B55 BOOL_ARB 0x8B56 BOOL_VEC2_ARB 0x8B57 BOOL_VEC3_ARB 0x8B58 BOOL_VEC4_ARB 0x8B59 FLOAT_MAT2_ARB 0x8B5A FLOAT_MAT3_ARB 0x8B5B FLOAT_MAT4_ARB 0x8B5C SAMPLER_1D_ARB 0x8B5D SAMPLER_2D_ARB 0x8B5E SAMPLER_3D_ARB 0x8B5F SAMPLER_CUBE_ARB 0x8B60 SAMPLER_1D_SHADOW_ARB 0x8B61 SAMPLER_2D_SHADOW_ARB 0x8B62 SAMPLER_2D_RECT_ARB 0x8B63 SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 Additions to Chapter 2 of the OpenGL 1.4 Specification (OpenGL Operation) Add two new rows to Table 2.2, page 9. GL Type Minimum Description Bit Width ------- ------- ------------- charARB 8 characters that make up strings handleARB 32 identifier for generic objects Modify Section 2.5, GL Errors, p. 11 (modify the last paragraph, p. 11) Four error generation conditions are implicit... (modify the first paragraph, p. 12) ...the error INVALID_VALUE results. Third, the error INVALID_VALUE is generated by any command that takes one or more handles as input, and one or more of these handles are not a generic object handle generated by OpenGL. Finally, if memory is exhausted... Modify Section 2.6.1 Begin and End Objects, p. 13 Remove the term "objects" from this section. Add a new section 2.14 Generic Objects, p.60 The currently existing object types in OpenGL, texture objects (see Section 3.8.12) and display lists (see Section 5.4), each have their own management API and object ID name space. Rather than designing a new API for each new object type added to OpenGL, this section introduces a more generic object API, which is initially applied to shader objects (Section 2.14.1) and program objects (Section 2.14.2). In OpenGL, a "generic object" is an OpenGL-managed opaque data structure. The data stored in such a generic object may be quite large, so applications are given control over how objects are managed. Generic objects are given handles (names) by OpenGL at object creation time. Applications can specify the data that is to be stored in objects and can modify that data through function calls. Generic objects can be created, deleted, modified, attached, detached and used as part of the current rendering state. Some types of generic objects act as containers for other objects. Linking an object to another is called "attaching" and unlinking an object is called "detaching". To attach an object to a container object, use the command: void AttachObjectARB (handleARB containerObj, handleARB obj) The error INVALID_OPERATION is generated if is not a type that can be attached to a container object or if is not a container object. The same error is generated if an attempt is made to attach the same object more than once to the same container object. To detach an object from the container object it is attached to, use the command: void DetachObjectARB(handleARB containerObj, handleARB attachedObj) If the object is not attached to any other container object in any rendering context, and the object is flagged for deletion, the information for and the data for is deleted. If is not attached to , the error INVALID_OPERATION is generated. The error INVALID_OPERATION is also generated if is not a container object. Generic objects can be deleted with the following command: void DeleteObjectARB(handleARB obj) This command will either delete the object, or flag it for deletion. An object that is attached to a container object is not deleted until it is no longer attached to any container object, for any context. If it is still attached to at least one container object, the object is flagged for deletion. If the object is part of the current rendering state, it is not deleted until it is no longer part of the current rendering state for any context. If the object is still part of the rendering state of at least one context, it is flagged for deletion. if an object is flagged for deletion, its Boolean status bit OBJECT_DELETE_STATUS_ARB is set to true. The value of OBJECT_DELETE_STATUS_ARB can be queried with GetObjectParameter{fi}vARB (see Section 6.1.12). DeleteObjectARB will silently ignore the value zero. When a container object is deleted, it will detach each attached object as part of the deletion process. When an object is deleted, all information for the object referenced is lost. The data for the object is also deleted. One bit of state is needed to indicate if a delete request for an object was made. The default is no request. Add Subsection 2.14.1 Shader Objects Subsequent sections of this specification will define stages of the GL pipeline that are programmable. The source code that makes up a program that gets executed by one of the programmable stages is encapsulated in one or more "shader objects". To create a shader object use the following command: handleARB CreateShaderObjectARB(enum shaderType) The shader object is empty when it is created. The argument specifies the type of shader object to be created, and should be one of < >. (This list to be augmented by other extensions.) If the shader object is created successfully, a handle that can be used to reference it is returned, and its object specific parameter OBJECT_TYPE_ARB is set to SHADER_OBJECT_ARB. The object specific parameter OBJECT_SUBTYPE_ARB is set to the actual type of the shader object created. The value of OBJECT_TYPE_ARB and OBJECT_SUBTYPE_ARB can be queried with GetObjectParameter{fi}vARB (see Section 6.1.12). If the creation failed the handle returned will be 0. Source code for the shader is specified with the command: void ShaderSourceARB(handleARB shaderObj, sizei count, const charARB **string, const int *length) The argument is an array of pointers to one or more, optionally null terminated, character strings that make up the source code. The argument is an array with the number of charARBs in each string (the string length). Each element in this array can be set to negative one (or smaller), indicating that its accompanying string is null terminated. If is set to NULL, all strings in the argument are considered null terminated. The ShaderSourceARB command sets the source code for the specified shader object to the text strings in the array. If the object previously had source code loaded into it, it is completely replaced. The number of strings in the array is given in . Any length passed in excludes the null termination in its count. If does not reference a shader object, the error INVALID_OPERATION is generated. The strings that are loaded into a shader object are expected to form the source code for a valid shader as defined in the OpenGL Shading Language Specification. Once the source code for a shader has been loaded, the shader object can be compiled with the following command: void CompileShaderARB(handleARB shaderObj) This function will compile . Each shader object has a Boolean status, OBJECT_COMPILE_STATUS_ARB, that is modified as a result of compilation. This status can be queried with GetObjectParameter{fi}vARB (see Section 6.1.12). This status will be set to TRUE if the shader was compiled without errors and is ready for use, and FALSE otherwise. Compilation can fail for a variety of reasons as listed in the OpenGL Shading Language Specification. If CompileShaderARB failed, any information about a previous compile is lost and is not restored. Thus a failed compile does not restore the old state of . If does not reference a shader object, the error INVALID_OPERATION is generated. Note that changing the source code of a shader object, through ShaderSourceARB, does not change its compile status OBJECT_COMPILE_STATUS_ARB. Each shader object has an information log that is modified as a result of compilation. This information log can be queried with GetInfoLogARB to obtain more information about the compilation attempt (see Section 6.1.12). Add Subsection 2.14.2 Program Objects The shader objects that are to be used by the programmable stages of OpenGL are collected together to form a "program object". The programs that are executed by these programmable stages are called "executables". All information necessary for defining an executable is encapsulated in a program object. A program object is created with the following command: handleARB CreateProgramObjectARB(void) Program objects are empty when they are created. If the program object is created successfully, a handle that can be used to reference it is returned and its attribute OBJECT_TYPE_ARB is set to PROGRAM_OBJECT_ARB. If the creation failed the handle returned will be 0. A program object is a container object. Shader objects are attached to a program object with the command AttachObjectARB. It is permissible to attach shader objects to program objects before source code has been loaded into the shader object, or before the shader object has been compiled. It is permissible to attach multiple shader objects of the same type to a single program object, and it is permissible to attach a shader object to more than one program object. In order to use the shader objects contained in a program object, the program object must be linked. This is accomplished with the following command: void LinkProgramARB (handleARB programObj) This function will link . Each program object has a Boolean status, OBJECT_LINK_STATUS_ARB, that is modified as a result of linking. This status can be queried with GetObjectParameter{fi}vARB (see Section 6.1.12). This status will be set to TRUE if a valid executable is created, and FALSE otherwise. Linking can fail for a variety of reasons as specified in the OpenGL Shading Language Specification. Linking will also fail if one or more of the shader objects, attached to , are not compiled successfully, or if more active uniform or active sampler variables are used in than allowed (see Sections 2.14.3 and 2.14.4). If LinkProgramARB failed, any information about a previous link is lost and is not restored. Thus a failed link does not restore the old state of . If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. Each program object has an information log that is modified as a result of a link operation. This information log can be queried with GetInfoLogARB to obtain more information about the link operation (see Section 6.1.12). If a valid executable is created, it can be made part of the current rendering state with the following command: void UseProgramObjectARB(handleARB programObj) This command will install the executable code as part of current rendering state if the program object contains valid executable code, i.e. has been linked successfully. If UseProgramObjectARB is called with the handle set to 0, it is as if the GL had no programmable stages and the fixed functionality paths will be used instead. If cannot be made part of the current rendering state, an INVALID_OPERATION error will be generated and the current rendering state left unmodified. This error will be set, for example, if has not been linked successfully. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. While a program object is in use, applications are free to modify attached shader objects, compile attached shader objects, attach additional shader objects, and detach shader objects. This does not affect the link status OBJECT_LINK_STATUS_ARB of the program object. This does not affect the executable code that is part of the current state either. That executable code is only affected when the program object has been re-linked successfully. After such a successful re-link, the LinkProgramARB command will install the generated executable code as part of the current rendering state if the specified program object was already in use as a result of a previous call to UseProgramObjectARB. If this re-link failed, then the executable code part of the current state does not change. Add Subsection 2.14.3 Uniform Variables Shaders can declare and name "uniform variables" as discussed in the OpenGL Shading Language Specification. Values for these uniforms are to remain constant over a primitive, and typically they are constant across many primitives. Uniforms are program object specific state. They retain their values once loaded, and their values are restored whenever a program object is used, as long as the program object has not been re-linked. A uniform is considered "active" if it is determined by the compiler and linker that the uniform will actually be accessed when the executable code is executed. In cases where the compiler and linker cannot make a conclusive determination, the uniform will be considered active. As a result of a successful link all active uniforms belonging to the program object are initialized to zero. A successful link will also generate a location for each active uniform. The values of active uniforms can be changed using this location and the appropriate Uniform*ARB command (see below). These locations are invalidated and new ones assigned after each successful re-link. The following function can be used to find the location of an active uniform variable within a program object: int GetUniformLocationARB(handleARB programObj, const charARB *name) This command will return the location of uniform variable . has to be a null terminated string, without white space. The value of -1 will be returned if does not correspond to an active uniform variable name in or if starts with the reserved prefix "gl_". If has not been successfully linked, or if is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. The location of a uniform variable does not change until the next link command is issued. A valid cannot be a structure, an array of structures, or a subcomponent of a vector or a matrix. In order to identify a valid , the "." (dot) and "[]" operators can be used in to operate on a structure or to operate on an array. The first element of a uniform array is identified using the name of the uniform array appended with "[0]". Except if the last part of the string indicates a uniform array, then the location of the first element of that array can be retrieved by either using the name of the uniform array, or the name of the uniform array appended with "[0]". To determine which of the declared uniform variables are active and to determine their sizes and types, use the command: void GetActiveUniformARB(handleARB programObj, uint index, sizei maxLength, sizei *length, int *size, enum *type, charARB *name) This command provides information about the uniform selected by . The of 0 selects the first active uniform, and of OBJECT_ACTIVE_UNIFORMS_ARB-1 selects the last active uniform. The value of OBJECT_ACTIVE_UNIFORMS_ARB can be queried with GetObjectParameter{if}vARB (see Section 6.1.12). If is greater than or equal to OBJECT_ACTIVE_UNIFORMS_ARB, the error INVALID_VALUE is generated. The parameter is a handle to a program object for which the command LinkProgramARB has been issued in the past. It is not necessary for to have been linked successfully. The link could have failed because the number of active uniforms exceeded the limit. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. If an error occurred, the return parameters , , and will be unmodified. For the selected uniform, the uniform name is returned into . The string will be null terminated. The actual number of characters written by the GL into is returned in . This count excludes the null termination. If is NULL then the GL ignores this parameter. The maximum number of characters the GL is allowed to write into is passed in by . The returned uniform name can be the name of built-in uniform state as well. The complete list of built-in uniform state is described in section 7.5 of the OpenGL Shading Language specification. The length of the longest uniform name in is given by OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, which can be queried with GetObjectParameter{if}vARB (see Section 6.1.12). Each uniform variable, declared in a shader, is broken down into one or more strings using the "." (dot) and "[]" operators, if necessary, to the point that it is legal to pass each string back into GetUniformLocationARB. Each of these strings constitutes one active uniform, and each string is assigned an index. For the selected uniform, the type of the uniform is returned into . The size of the uniform is returned into . The value in is in units of the type returned in . The type returned can be any of FLOAT, FLOAT_VEC2_ARB, FLOAT_VEC3_ARB, FLOAT_VEC4_ARB, INT, INT_VEC2_ARB, INT_VEC3_ARB, INT_VEC4_ARB, BOOL_ARB, BOOL_VEC2_ARB, BOOL_VEC3_ARB, BOOL_VEC4_ARB, FLOAT_MAT2_ARB, FLOAT_MAT3_ARB, FLOAT_MAT4_ARB, SAMPLER_1D_ARB, SAMPLER_2D_ARB, SAMPLER_3D_ARB, SAMPLER_CUBE_ARB, SAMPLER_1D_SHADOW_ARB, SAMPLER_2D_SHADOW_ARB, SAMPLER_2D_RECT_ARB or SAMPLER_2D_RECT_SHADOW_ARB. If one or more elements of an array are active, GetActiveUniformARB will return the name of the array in , subject to the restrictions listed above. The type of the array is returned in . The parameter contains the highest array element index used, plus one. The compiler or linker determines the highest index used. There will be only one active uniform reported by the GL per uniform array. This command will return as much information about active uniforms as possible. If no information is available, will be set to zero and will be an empty string. This situation could arise if GetActiveUniformARB is issued after a failed link. The following commands are used to load values into the uniform variables of the program object that is currently in use. void Uniform{1234}fARB(int location, T value) void Uniform{1234}iARB(int location, T value) void Uniform{1234}fvARB(int location, sizei count, T value) void Uniform{1234}ivARB(int location, sizei count, T value) void UniformMatrix(234}fvARB(int location, sizei count, boolean transpose, T value) These commands will load the given values into the uniform variable location identified by . The Uniform{1234}f{v}ARB commands will load one or more floating-point values times into a uniform location defined as a float or floating-point vector or an array of floats or an array of floating-point vectors. The Uniform{1234}i{v}ARB commands will load one or more integer values times into a uniform location defined as a sampler, integer or integer vector or an array of integers or an array of integer vectors. Only the Uniform1i{v}ARB commands can be used to load sampler values. See section 2.14.4. The UniformMatrix{234}fvARB commands will load a 2x2, 3x3 or 4x4 matrix (corresponding to 2, 3, or 4 in the command name) of floating-point values times into a uniform location defined as a matrix or an array of matrices. If is FALSE, the matrix is specified in column major order, otherwise in row major order. When loading values for a uniform declared as a Boolean, a Boolean vector or an array of Booleans or an array of Boolean vectors, both the Uniform*i{v} and Uniform*f{v} set of commands can be used to load Boolean values. Type conversion is done by the GL. The uniform is set to FALSE if the input value is 0 or 0.0f, and set to TRUE otherwise. The Uniform*ARB command used must match the size of the uniform, as declared in the shader. For example, to load a uniform declared as a bvec2, either Uniform2i{v}ARB or Uniform2f{v}ARB can be used. An INVALID_OPERATION error will be generated if an attempt is made to use a non-matching Uniform*ARB command. In this example using Uniform1ivARB would generate an error. For all other uniform types the Uniform*ARB command used must match the size and type of the uniform, as declared in the shader. No type conversions are done. For example, to load a uniform declared as a vec4, Uniform4f{v}ARB must be used. To load a 3x3 matrix, UniformFloatMatrix3fvARB must be used. An INVALID_OPERATION error will be generated if an attempt is made to use a non-matching Uniform*ARB command. In this example, using Uniform4i{v}ARB would generate an error. When loading N elements starting at an arbitrary position k in a uniform declared as an array, elements k through k + N - 1 in the array will be replaced with the new values. Values for any array element that exceeds the highest array element index used, as reported by GetActiveUniformARB, will be ignored by the GL. If the value of is -1, the Uniform*ARB commands will silently ignore the data passed in. The current uniform values will therefore not be changed. The following applies to errors that can be generated when loading uniforms: - If the size indicated in the name of the Uniform*ARB command used does not match the size of the uniform declared in the shader, an INVALID_OPERATION error is generated and the uniform's value is not changed. - If a uniform not of type Boolean is loaded, then if the type indicated in the name of the Uniform*ARB command used does not match the type of the uniform declared in the shader, an INVALID_OPERATION error is generated and the uniform's value is not changed. - If is not -1 and does not exist for the program object currently in use, the error INVALID_OPERATION is generated. - The error INVALID_OPERATION is generated by any of the Uniform*ARB commands if there is no program object in use. Add Subsection 2.14.4 Samplers Samplers are special uniforms used in the OpenGL Shading Language to identify the texture object used for each texture lookup. The value of a sampler indicates the texture image unit being accessed. Setting a sampler's value to i selects texture image unit number i. The values of i range from zero to the maximum supported number of texture image units. This maximum is implementation dependent, and defined in other specifications. The type of the sampler identifies the target on the texture image unit. The texture object bound to that texture image unit's target is then used for the texture lookup. For example, a variable of type sampler2D selects target TEXTURE_2D on its texture image unit. Binding of texture objects to targets is done as usual with BindTexture. Selecting the texture image unit to bind to is done as usual with ActiveTexture. The location of a sampler needs to be queried with GetUniformLocationARB, just like any uniform variable. Sampler values need to be set by calling Uniform1i{v}ARB. Loading samplers with any of the other Uniform*ARB entry points is not allowed and will result in an INVALID_OPERATION error. It is not allowed to have variables of different sampler types pointing to the same texture image unit within a program object. This situation can only be detected at the next rendering command issued, and an INVALID_OPERATION error will then be generated. Active samplers are samplers actually being used in a program object. The LinkProgramARB command determines if a sampler is active or not. The LinkProgramARB command will attempt to determine if the active samplers in the shader(s) contained in the program object exceed the maximum allowable limits. If it determines that the count of active samplers exceeds the allowable limits, then the link fails. (These limits are determined by other extensions, and can be different for different types of shaders.) If this cannot be determined at link time, for example if the program object only contains a vertex shader, then this will be determined at the next rendering command issued, and an INVALID_OPERATION error will then be generated. Add Subsection 2.14.5 Resource Limits A shader should not fail to compile and a program object to link due to lack of instruction space or lack of temporary variables. Implementations should ensure that all valid shaders and program objects could be successfully compiled, linked and executed. Add Subsection 2.15 Validation It is not always possible to determine at link time if a program object actually will execute. Therefore validation is done when the first rendering command is issued, to determine if the currently active program object can be executed. If it cannot be executed then no fragments will be rendered, and Begin, RasterPos, or any command that performs an explicit Begin will generate the error INVALID_OPERATION. This error is generated by Begin, RasterPos, or any command that performs an explicit Begin if: * One or more samplers of different types in the current program object access the same texture image unit. * If more than the maximum allowable texture image units are accessed based on the count of active samplers and the rest of the GL state. Note that LinkProgramARB can normally resolve this, except for the case where an ARB_vertex_shader shader is mixed with an ARB_fragment_program shader or mixed with fixed-function fragment processing. The INVALID_OPERATION error reported by these rendering commands does not provide enough information to find out why the currently active program object would not execute. No information at all is available about a program object that would still execute, but is inefficient or sub optimal given the current GL state. As a development aid, use the command void ValidateProgramARB(handleARB programObj) to validate the program object against the GL state at that moment. Each program object has a Boolean status, OBJECT_VALIDATE_STATUS_ARB, that is modified as a result of validation. This status can be queried with GetObjectParameter{if}vARB (see Section 6.1.12). If validation succeeded this status will be set to TRUE, otherwise it will be set to FALSE. If validation succeeded the program object is guaranteed to execute, given the current GL state. If validation failed, the program object is guaranteed to not execute, given the current GL state. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. ValidateProgramARB will validate at least as much as is done when a rendering command is issued, and it could validate more. For example, it could give a hint on how to optimize some piece of shader code. ValidateProgramARB will store its information in the info log. This information will either be an empty string or it will contain validation information. ValidateProgramARB is typically only useful during application development. An application should not expect different OpenGL implementations to produce identical information. 2.16 Undefined Behavior By addressing arrays or matrices in a shader it is possible to index outside the declared extent of a uniform. Thus it could be possible to overwrite critical GL data that is stored next to the uniform in memory. What this data could be is GL implementation specific. The OpenGL Shading Language states that it is undefined what happens in this case. The system environment the OpenGL implementation runs in can set certain rules, or good practices, that restrict certain behavior. For example, on a modern OS it is not allowed to overwrite data in someone else's address space. Similarly it would therefore not be allowed to overwrite GL data that belongs to another process. This could be further restricted by disallowing the ability to overwrite data belonging to another context within the same process. The GL implementation, in combination with the system environment, decides what is acceptable behavior; hence the specification leaves results undefined. 2.17 Required State The state required to support shader objects consists of: * The state that must be maintained to indicate which handles are currently in use as shader object names. The state required per shader object consists of: * A handleARB indicating the shader object name. * An array of arrays of type charARB containing the shader strings, initially empty. * An integer holding the length of the concatenation of the shader strings, including one null termination. * An array of unsigned integers holding the length of the shader strings, initially zero. * An integer holding the value of OBJECT_TYPE_ARB * An integer holding the value of OBJECT_SUBTYPE_ARB * A Boolean holding the status of the last compile. * A Boolean holding the delete status. * An array of type charARB containing the info log, initially empty. * An integer holding the length of the info log, including a null termination. Initially, no shader objects exist. The state required to support program objects consists of: * The state that must be maintained to indicate which handles are currently in use as program object names. * One handleARB to store the handle of the program object currently in use. The state required per program object consists of: * A handleARB indicating the program object object name. * A list of handleARB to keep track of shader objects attached. * An integer holding the number of attached shader objects. * A Boolean indicating if the program object has been successfully linked. * A Boolean holding the status of the last validation attempt. * A Boolean holding the delete status. * An integer holding the value of OBJECT_TYPE_ARB. * An array of type charARB containing the info log, initially empty. * An integer holding the length of the info log, including a null termination. * An array of type charARB for each active uniform containing its name, initially empty. * An integer holding the length of the longest active uniform name, including a null termination. * An integer holding the number of active uniforms. * An integer for each active uniform, containing its size. * An integer for each active uniform, containing its type. * An integer for each active uniform, holdings its location. Initially, no program objects exist. Additions to Chapter 3 of the OpenGL 1.4 Specification (Rasterization) None Additions to Chapter 4 of the OpenGL 1.4 Specification (Per-Fragment Operations and the Frame Buffer) None Additions to Chapter 5 of the OpenGL 1.4 Specification (Special Functions) Add to section 5.4, Display Lists. Commands that are used to create and manage objects are not included in display lists, but are executed immediately. These include DeleteObjectARB, DetachObjectARB, CreateShaderObjectARB, ShaderSourceARB, CompileShaderARB, CreateProgramObjectARB, AttachObjectARB, and LinkProgramARB. Commands that are used to query various pieces of object state are not included in display lists, but are executed immediately. These include GetHandleARB, GetObjectParameterfvARB, GetObjectParameterivARB, GetInfoLogARB, GetUniformfvARB, GetUniformivARB, GetUniformLocationARB, GetShaderSourceARB, GetActiveUniformARB, GetAttachedObjectsARB and ValidateProgramARB. Additions to Chapter 6 of the OpenGL 1.4 Specification (State and State Requests) Add a new section just after section 6.1.11 (p. 214) called 6.1.12 "Generic Object Queries" and renumber section 6.1.12 as 6.1.13. The command handleARB GetHandleARB(enum pname) returns the handle to an object that is in use as part of current state. specifies the state item for which the current object is to be returned and can be one of PROGRAM_OBJECT_ARB. (This list is augmented by other extensions.) If is not a valid state item, 0 is returned. The commands void GetObjectParameterfvARB(handleARB obj, enum pname, float *params) void GetObjectParameterivARB(handleARB obj, enum pname, int *params) return object specific parameter values for object in . The parameter value to return is specified by . If is OBJECT_TYPE_ARB, GetObjectParameter{if}vARB returns PROGRAM_OBJECT_ARB if references a program object. It returns SHADER_OBJECT_ARB if references any shader object. If is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_SUBTYPE_ARB, GetObjectParameter{if}vARB returns the subtype of a shader object. If is not of type SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_DELETE_STATUS_ARB, GetObjectParameter{if}vARB returns 1 or 1.0f if status is TRUE and 0 or 0.0f if status is FALSE. If is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_LINK_STATUS_ARB, GetObjectParameter{if}vARB returns 1 or 1.0f if status is TRUE and 0 or 0.0f if status is FALSE. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_VALIDATE_STATUS_ARB, GetObjectParameter{if}vARB returns 1 or 1.0f if status is TRUE and 0 or 0.0f if status is FALSE. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_COMPILE_STATUS_ARB, GetObjectParameter{if}vARB returns 1 or 1.0f if status is TRUE and 0 or 0.0f if status is FALSE. If is not of type SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_INFO_LOG_LENGTH_ARB, GetObjectParameter{if}vARB returns the length of the info log, including a null termination. If there is no info log, 0 or 0.0f is returned. If is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If is OBJECT_ATTACHED_OBJECTS_ARB, GetObjectParameter{if}vARB returns the number of objects attached. If no objects are attached, 0 or 0.0f is returned. If is not of type PROGRAM_OBJECT_ARB the error INVALID_OPERATION is generated. If is OBJECT_ACTIVE_UNIFORMS_ARB, GetObjectParameter{if}vARB returns the number of active uniforms. If no active uniforms exist, 0 or 0.0f is returned. If is not of type PROGRAM_OBJECT_ARB the error INVALID_OPERATION is generated. If is OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, GetObjectParameter{if}vARB returns the length of the longest active uniform name, including a null termination. If no active uniforms exist, 0 or 0.0f is returned. If is not of type PROGRAM_OBJECT_ARB the error INVALID_OPERATION is generated. If is OBJECT_SHADER_SOURCE_LENGTH_ARB, GetObjectParameter{if}vARB returns the length of the concatenation of the source strings making up the shader source, including a null termination. If no source exists, 0 or 0.0f is returned. If is not of type SHADER_OBJECT_ARB the error INVALID_OPERATION is generated. If an error occurred, the return parameter will be unmodified. The command void GetAttachedObjectsARB(handleARB containerObj, sizei maxCount, sizei *count, handleARB *obj) returns the handles of objects attached to in . The actual number of object handles written by the GL into is returned in . If no objects are attached, is set to zero. If is NULL then the GL ignores this parameter. The maximum number of handles the GL is allowed to write into is passed in by . The number of objects attached to is given by OBJECT_ATTACHED_OBJECTS_ARB, which can be queried with GetObjectParameter{if}vARB. If is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. If an error occurred, the return parameters and will be unmodified. A string that contains information about the last link or validation attempt and last compilation attempt are kept per program or shader object. This string is called the info log and can be obtained with the command: void GetInfoLogARB(handleARB obj, sizei maxLength, sizei *length, charARB *infoLog) This command returns the info log string in . This string will be null terminated. The actual number of characters written by the GL into is returned in , excluding the null termination. If is NULL then the GL ignores this parameter. The maximum number of characters the GL is allowed to write into is passed in by . The number of characters in the info log is given by OBJECT_INFO_LOG_LENGTH_ARB, which can be queried with GetObjectParameter{fi}vARB. If is a shader object, the returned info log will either be an empty string or it will contain information about the last compilation attempt for that object. If is a program object, the returned info log will either be an empty string or it will contain information about the last link attempt or last validation attempt for that object. If is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If an error occurred, the return parameters and will be unmodified. The info log is typically only useful during application development and an application should not expect different OpenGL implementations to produce identical info logs. The command void GetShaderSourceARB(handleARB obj, sizei maxLength, sizei *length, charARB *source) will return in the string making up the source code for the shader object . The string will be null terminated. The actual number of characters written by the GL into is returned in , excluding the null termination. If is NULL then the GL ignores this parameter. The maximum number of characters the GL is allowed to write into is passed in by . The string is a concatenation of the strings passed to OpenGL using ShaderSourceARB. The length of this concatenation is given by OBJECT_SHADER_SOURCE_LENGTH_ARB, which can be queried with GetObjectParameter{if}vARB. If is not of type SHADER_OBJECT_ARB, the error INVALID_OPERATION is generated. If an error occurred, the return parameters and will be unmodified. The commands void GetUniformfvARB(handleARB programObj, int location, float *params) void GetUniformivARB(handleARB programObj, int location, int *params) return the value or values of the uniform at location for program object in the array . The type of the uniform at determines the number of values returned. The error INVALID_OPERATION is generated if is not of type PROGRAM_OBJECT_ARB or if has not been linked successfully or if is not a valid location for . In order to query the values of an array of uniforms a GetUniform*ARB command needs to be issued for each array element. If the uniform queried is a matrix, the values of the matrix are returned in column major order. If an error occurred, the return parameter will be unmodified. Add to Table 6.3: State Variable Types (p. 217) H Object handle Additions to Appendix A of the OpenGL 1.4 Specification (Invariance) None Additions to the AGL/GLX/WGL Specifications Analogous to sharing display lists and texture objects, it is possible to share the name space for handles for all objects across a set of contexts, as long as the server sides of the contexts share the same address space. No change is made to the AGL/GLX/WGL API. If handles are shared across contexts the data belonging to those objects are shared as well. Changes to objects shared between multiple rendering contexts will be serialized (i.e., the changes will occur in a specific order). Changes to a program object made by one rendering context are not guaranteed to take effect in another rendering context until the other calls UseProgramObjectARB for that object. When a program object is deleted by one rendering context, the object itself is not destroyed until it is no longer the current program object in any context. When a shader object is deleted by one rendering context, the object itself is not destroyed until it is no longer attached to any program object in any context. Errors The error INVALID_VALUE is generated by any command that takes one or more handles as input, and one or more of these handles are not an object handle generated by OpenGL. Note that this error is also set when passing in the value 0 as a handle, except for UseProgramObjectARB and DeleteObject. Passing in 0 to UseProgramObjectARB is valid, and ignored by DeleteObject. The error INVALID_OPERATION is generated by AttachObjectARB if is not of type SHADER_OBJECT_ARB or if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by AttachObjectARB if is already attached to . The error INVALID_OPERATION is generated by DetachObjectARB if is not attached to . The error INVALID_OPERATION is generated by DetachObjectARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by ShaderSourceARB and CompileShaderARB if is not of type SHADER_OBJECT_ARB. The error INVALID_OPERATION is generated by LinkProgramARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by UseProgramObjectARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by UseProgramObjectARB if could not be made part of the current state. The error INVALID_OPERATION is generated by GetUniformLocationARB if is not of type PROGRAM_OBJECT_ARB or if has not been linked successfully. The error INVALID_OPERATION is generated by GetActiveUniformARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_VALUE is generated by GetActiveUniformARB if is greater than or equal to OBJECT_ACTIVE_UNIFORMS_ARB. The error INVALID_OPERATION is generated by the Uniform*ARB commands if the size does not match the size of the uniform declared in the shader. The error INVALID_OPERATION is generated by the Uniform*ARB commands if the type does not match the type of the uniform declared in the shader, if the uniform is not of type Boolean. The error INVALID_OPERATION is generated by the Uniform*ARB commands if is not -1 and does not exist for the program object currently in use. The error INVALID_OPERATION is generated by the Uniform*ARB commands if there is no program object in use. The error INVALID_OPERATION is generated if a uniform command other than Uniform1i{v}ARB is used to load a sampler value. The error INVALID_OPERATION is generated by ValidateProgramARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB if is OBJECT_TYPE_ARB or OBJECT_DELETE_STATUS_ARB or OBJECT_INFO_LOG_LENGTH_ARB and is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB. The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB if is OBJECT_LINK_STATUS_ARB or OBJECT_VALIDATE_STATUS_ARB or OBJECT_ATTACHED_OBJECTS_ARB or OBJECT_ACTIVE_UNIFORMS_ARB or OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB and is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB if is OBJECT_SUBTYPE_ARB or OBJECT_COMPILE_STATUS_ARB or OBJECT_SHADER_SOURCE_LENGTH_ARB and is not of type SHADER_OBJECT_ARB. The error INVALID_OPERATION is generated by GetAttachedObjectsARB if is not of type PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by GetInfoLogARB if is not of type SHADER_OBJECT_ARB or PROGRAM_OBJECT_ARB. The error INVALID_OPERATION is generated by GetShaderSourceARB if is not of type SHADER_OBJECT_ARB. The error INVALID_OPERATION is generated by GetUniform{if}vARB if is not of type PROGRAM_OBJECT_ARB or if has not been linked successfully or if is not a valid location for . The error INVALID_OPERATION is generated if Begin, RasterPos, or any command that performs an explicit Begin is called if: - One or more samplers of different types in the current program object access the same texture image unit. - More than the maximum allowable texture image units are accessed based on the count of active samplers and the rest of the GL state (note that LinkProgramARB can normally resolve this, except for the case where an ARB_vertex_shader shader is mixed with an ARB_fragment_program shader or mixed with fixed-function fragment processing). New State Initial Get Value Type Get Command Value Description Sec. Attribute --------- ---- ------------------------- ------- ----------- ---- --------- PROGRAM_OBJECT_ARB H GetHandle 0 Handle of current 2.14.2 - program object Table X. New state introduced. Initial Get Value Type Get Command Value Description Sec. Attribute --------- ----- ----------------------- ------------- ----------- ---- --------- - H object specific object handle 2.14.1 - - 0+xchar GetInfoLogARB "" Info log for shader 6.1.12 - objects - 0+xchar GetShaderSourceARB "" source for a shader 2.14.1 - OBJECT_TYPE_ARB Z+ GetObjectParameterivARB SHADER_OBJECT Type of object 2.14.1 - OBJECT_SUBTYPE_ARB Z+ GetObjectParameterivARB - Sub type of object 2.14.1 - OBJECT_DELETE_STATUS_ARB B GetObjectParameterivARB FALSE Shader deleted 2.14 - OBJECT_COMPILE_STATUS_ARB B GetObjectParameterivARB FALSE Compile succeeded 2.14.1 - OBJECT_INFO_LOG_LENGTH_ARB Z+ GetObjectParameterivARB 0 Length of info log 6.1.12 - OBJECT_SHADER_SOURCE_LENGTH_ARB Z+ GetObjectParameterivARB 0 Length of source code 6.1.12 - Table X Shader object state. Initial Get Value Type Get Command Value Description Sec. Attribute --------- ----- ----------------------- ------------- ----------- ---- --------- - 0+xZ+ GetActiveUniformARB - Size of active uniform 2.14.3 - - 0+xZ+ GetActiveUniformARB - Type of active uniform 2.14.3 - - 0+xcharARB GetActiveUniformARB "" Name of active uniform 2.14.3 - - 0+xZ GetUniformLocationARB - Location of active uniform 2.14.3 - - 0+xchar GetInfoLogARB "" Info log for program objects 6.1.12 - OBJECT_ATTACHED_OBJECTS_ARB Z+ GetObjectParameterivARB 0 Number of attached objects 6.1.12 - OBJECT_ACTIVE_UNIFORMS_ARB Z+ GetObjectParameterivARB 0 Number of active uniforms 2.14.3 - OBJECT_DELETE_STATUS_ARB B GetObjectParameterivARB FALSE Program object deleted 2.14 - OBJECT_LINK_STATUS_ARB B GetObjectParameterivARB FALSE Link succeeded 2.14.2 - OBJECT_VALIDATE_STATUS_ARB B GetObjectParameterivARB FALSE Validate succeeded 2.15 - OBJECT_INFO_LOG_LENGTH_ARB Z+ GetObjectParameterivARB 0 Length of info log 6.1.12 - OBJECT_TYPE_ARB Z+ GetObjectParameterivARB PROGRAM_OBJECT Type of object 2.14.2 - OBJECT_ACTIVE_UNIFORM_ MAX_LENGTH_ARB Z+ GetObjectParameterivARB 0 Max uniform name length 6.1.12 - - 0+xhandle GetAttachedObjectsARB empty list Shader objects attached 6.1.12 - H object specific object handle 2.14.2 - Table X Program object state. New Implementation Dependent State None Sample Usage For examples on how to use GetUniformLocationARB and the Uniform*ARB API, see issue 32. // // Example usage of GetActiveUniformARB. // GLint maxLength; GLint i, uniformCount; GLcharARB **name; GLsizei *length; GLint *size; GLenum *type; // // Get the number of uniforms, and the length of the longest name. // glGetObjectParameterivARB(programObject, GL_OBJECTS_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &maxLength); glGetObjectParameterivARB(programObject, GL_OBJECTS_ACTIVE_UNIFORMS_ARB, &uniformCount); // // Allocate arrays to store the answers in. For simplicity, the return // from malloc is not checked for NULL. // size = (GLint *) malloc(uniformCount * sizeof(GLint)); type = (GLint *) malloc(uniformCount * sizeof(GLenum)); length = (GLsizei *) malloc(uniformCount * sizeof(GLsizei)); name = (GLcharARB **) malloc(uniformCount * sizeof(GLcharARB **)); // // Loop over glGetActiveUniformARB and store the results away. // for (i = 0; i < uniformCount; i++) { name[i] = (GLcharARB *) malloc(maxLength * sizeof(GLcharARB)); glGetActiveUniformARB(programObject, i, maxLength, &length[i], &size[i], &type[i], name[i]); } See the ARB_vertex_shader and ARB_fragment_shader extension documents for more examples. Revision History Revision: 0.5 6/5/2002 - First draft for circulation Revision: 0.51 - Started issues section. Added string discussions and uniform discussions. - Added content to the Contributors, and Errors section - Named and explained all parameters to all API calls - Added a new GLchar type - Load/AppendShaderGL2 take a length argument - GetUniformLocationGL2 takes a length argument for the string passed in - GetInfoLogGL2 now also optionally returns the length of the string - Clarified DetachObjectGL2 and DeleteObject(s)GL2 and their interaction Revision 0.52 - Removed NULL_HANDLE_GL2 - Added explanation of what happens when program and shader objects are shared among contexts. Revision: 0.60 - Merged GL2_core_objects extension into this one. Core_objects is now obsolete. Revision: 0.61 - Took out any reference to 'project'. This term was unnecessary, since it meant the same as program object. Revision: 0.62 - Now references V1.0 of OpenGL Shading Language Specification - Fixed minor typos - Accepted by the GL2 working group Revision: 0.63 10/17/2002 - Removed IsObjectGL2(). It overlaps with GetObjectParameter{if}vGL2. - Expanded GetObjectParameter{if}GL2. Added OBJECT_TYPE_GL2. Revision: 0.64 10/18/2002 - Added list of entrypoints that are not compiled into a display list to section 5. - Updated Errors section. Revision: 0.65 10/23/2002 - Added GetShaderSourceGL2. - Added GetUniform{if}vGL2 - Updated errors section. - Moved shader resources section in here from GL2_vertex_shader. Revision: 0.7 10/29/2002 - Added issue number 16. - Second distribution to the GL2 working group. - Now written against the OpenGL 1.4 specification. Revision: 0.71 11/26/2002 - Added six more issues discussion uniform loading (issues 7-15). - Added loadUniform commands to load values for INT and BOOL declared uniforms. - Changed the behavior for loadUniforms to allow to load the first N values if loading into a uniform declared with an extent bigger than N. - Made a GLhandle an unsigned integer, read and written only by the GL - Added high level shading language layering issue 22. This issue came from the OpenGL Shading Language document. - Updated resource limits issue number 21. Revision: 0.72 01/27/2003 - Added issue 24. - Added to the list of contributors. - Changed the GLchar type to GLcharGL2 - Changed GLhandle type to GLhandleGL2 Revision: 0.73 02/20/2003 - Updated section 2.14.4. Loading uniforms of the wrong type will result in undefined shader results. - Loading more or less data than the declared extent of the uniform is now handled consistently. - Added section 2.14.4.1 'Samplers' - Added an extra error condition for LinkProgramGL2 when using too many active samplers. - Added issue 25, explaining how to use samplers for texture access. - Added issue 26, need for a validate command. - Added section 2.15, Validation Revision: 0.74 02/23/2003 - Added use of [] and . (dot) operators in GetUniformLocationGL2 - Refined wording in section 2.14.4.1. Revision: 0.75 03/27/2003 - Begin can generate an error in certain cases. - Closed issue 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 and made spec changes, if necessary, to reflect the resolutions of these issues. - Added issues 27, 28, 29, 30, 31. - Changed the loadUniform API. Less entry points, aimed at performance of loading uniforms. Also added a transpose flag to the matrix ones. - Updated IP Status section to point to the contributors agreement. - Removed ObjectParameter*GL2. These are not used anywhere. - AttachObjectGL2 no longer returns a Boolean. There is no reason that an attach should ever fail, if a valid program object and shader object are passed in. - Defined the lifetime of the pointers returned by GetInfoLogGL2 and GetShaderSourceGL2. - Added GetAttachedObjectsGL2. Revision: 0.76 03/28/2003 - UseProgramObjectGL2 no longer returns anything. It can now be compiled into a display list. - Closed issues 14, 15, 30. - Allowed loading more than one element in a uniform array, by just querying the location of the first element to be loaded. - Added the UNIFORM_ERROR_CHECK_GL2 enable. - Changed GetInfoLogGL2 so that GL only has to maintain at least one info log for shader objects and at least one for program objects. - Added section 2.16, undefined behavior Revision: 0.77 04/03/2003 - AppendShader now takes an array of strings, just like ShaderSource. - GetShaderSources returns an array of strings. - Closed issues 16, 17, 18, 19, 20. Revision: 0.78 04/07/2003 - Closed issues 21, 22, 23, 24, 25, 26. - Added lifetime to the pointer returned by ValidateProgram. Also changed ValidateProgram to take a handle to a program object. - LinkProgramGL2 will now set all uniforms to zero. - Added GetShaderSourceGL2 example code. Revision: 0.79 04/09/2003 - Added section 2.17, required state. - Clarified GetInfoLog, especially when sharing objects across contexts. - Changed ValidateProgramGL2 to store its information in the info log. It'll return a Boolean to indicate a successful validation. - Clarified the use of the '.' And '[]' operators in GetUniformLocation. Revision: 0.80 04/17/2003 - Removed AppendShaderGL2. - Closed issues 28, 29, 30 and 31. - Clarified GetUniformLocationGL2 based on Folker's feedback. - Added GetActiveUniformsGL2. Revision: 0.81 04/18/2003 - GetUniformLocationGL2 only works for active uniforms now. - Re-worded GetActiveUniformsGL2 to be more like GetActiveAttribsGL2. - Added wording explicitly saying that a failed compile or link is not state neutral (does not revert back to the old state). - Added a sentence saying that the memory pointer returned by GetActiveUniforms, GetInfoLog, GetAttachedObjects and GetShaderSource is owned by OpenGL and should not be overwritten by the caller. Revision: 0.82 04/27/2003 - Forgot to close issue 27. - Changed a few occurances of "char" to charGL2. - Updated language describing GetUniformLocationGL2. - Changed the location of the Contributors License to a publicly accessible place on www.3dlabs.com. - GetActiveUniformsGL2 is not display-listable. - Removed one error condition for ValidateProgramGL2. - Added errors for GetAttachedObjectsGL2. - Renamed the following functions: - glLoadShader --> glShaderSource - glGetShaderString --> glGetShaderSource - glAttachShaderObject --> glAttachObject - glGetAttachedShaderObjects --> glGetAttachedObjects - Clarified that GetActiveUniformsGL2 will return as much information as possible. If it has none, it'll return a count of zero. - Numerous clarifications and some reordering of paragraphs based on Pat's feedback. - Spelled out three reasons why LinkProgram can fail. - Spelled out that the Uniform*GL2 command used needs to match both the type and the size of a uniform declared in a shader. - Updated the error checking rules for the Uniform*GL2 commands. - Passing in '0', or a handle that is not an object handle generated by the GL, results in the error INVALID_VALUE. All other calls that get passed a valid handle, but that handle is of the wrong type for that operation, set an INVALID_OPERATION error. - Added issue 32, explaining GetUniformLocationGL2 and uniform loading. Revision: 0.83 04/28/2003 - Added more state tables. - Added Kent Lin to the list of contributors. Revision: 0.84 04/29/2003 - Added a few more examples to issue 32. - Clarified the Errors section with respect to passing in 0 as a handle. - Version voted on, and approved, by the ARB-GL2 working group. Revision: 0.85 05/09/2003 - Fixed a mistake in the program object state table for GetInfoLogGL2. - Fixed a mistake in the resolution of issue 27. - Clarified the resolution of issue 17. - Clarified that in case of doubt by the compiler/linker, a uniform will be marked as active. Section 2.14.3 (intro). - Clarified that you need to pass in three NULL pointers to GetActiveUniformsGL2, to only get the count of active uniforms. - Clarified the lifetime of the pointers returned by GetActiveUniformsGL2, GetShaderSourceGL2 and GetAttachedObjectsGL2. - Fixed a typo in the first entry in the Errors section. - Changed the count parameter in the Uniform*vGL2 commands to be of type sizei. Also did this for ShaderSourceGL2. - Expanded the two paragraphs explaining how Uniform*GL2 works into several smaller ones. - Clarified that GetInfoLogGL2 returns NULL if the handle passed in is invalid, or not a program or shader object. - Added fourth implicit error rule to section 2.5, GL Errors. Note that this rule was already in the Errors section. - Added Jon Leech, Evan Hart, Benjamin Lipchak and Jeremy Sandmel to the list of contributors. - Assigned enum values. Revision: 0.86 05/15/2003 - Assigned missing enum value to SHADER_OBJECT_GL2. - Replaced all GL2 occurrences with ARB. Fixed some typos. - Added several more to the contributors list. If anyone is still left out, let Bill Licea Kane, Jon Leech or myself know. Revision: 0.87 06/13/2003 - Changed resolution of issue 27 and the description of GetInfoLog to have an info log per object. Removed the info log language from the AGL/GLX/WGL section. - Changed the resolution of issue 14, 15, 25 (uniform API name). - Changed the discussion and resolution of issue 30. (uniform loading). - Added issue 33. - Changed the uniform API commands. The type of the uniform is no longer encoded in the name of the API. - Updated section 2.14.4, samplers. - Updated the Errors section w.r.t. uniform loading - Updated section 2.16, undefined behavior. - Deleted DeleteObjectsARB. - Removed the Boolean return from CompileShaderARB, LinkProgramARB and ValidateProgramARB. - Added several new error conditions for GetObjectParameter{if}vARB to the Errors section an section 6.1.12. - Updated the New State and Required State sections. - Changed GetInfoLog to no longer return a pointer to GL memory. - Changed GetAttachedObjects to no longer return a pointer to GL memory. - Changed GetActiveUniform to no longer return a pointer to GL memory. This call now returns data for one active uniform, instead of all active uniforms. Also added its returns (type, size and name) to the state tables and Required State section. - Changed GetShaderSource to no longer return a pointer to GL memory. - Added OBJECT_SUBTYPE_ARB, OBJECT_DELETE_STATUS_ARB, OBJECT_COMPILE_STATUS_ARB, OBJECT_LINK_STATUS_ARB, OBJECT_VALIDATE_STATUS_ARB, OBJECT_INFO_LOG_LENGTH_ARB, OBJECT_ATTACHED_OBJECTS_ARB, OBJECT_ACTIVE_UNIFORMS_ARB, OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, OBJECT_SHADER_SOURCE_LENGTH_ARB as a queriable parameter to GetObjectParameter{if}vARB. - Modified the introduction to section 2.14 to mention texture and display list objects. - Added issue 34. - Updated the example section with a new example. - Re-ordered the Errors section. They are now in the order of API calls described in Sections 2-6. - Language clean-up throughout the document. - Consistently used "OpenGL Shading Language" where appropriate (This is the official name). - Changed issue 5. This issue is now obsolete, with the new GetInfoLog API. - Clarified section 2.14.4, Samplers. The values to load range from 0 to to max available texture image units. - ARB approved version. Revision: 0.88 03/29/2004 - Added ARB extension number (31) and edited the status paragraph. - GetActiveUniform now returns types for samplers. - If at least one element in a uniform array is active, then this array will be reported by GetActiveUniform as being active starting at element 0 through the highest element used. Added issue 35 explaining this in detail. - Passing in a location of -1 to Uniform*ARB will be silently ignored (no GL error will be generated). Also added issue 36 explaining this. - DeleteObject will silently ignore the value 0. Added issue 37. - The current program object handle is no longer part of the 'current' state. - Specified that GetUniform returns values in column major order for matrices. Also clarified that GetUniform returns only one element of an array of uniforms. Added issue 38. - Specified what happens when ValidateProgramARB fails. This means that the program object will not execute, and no fragments will be rendered. - Added 'const' to the data passed in the Uniform*vARB commands. - Clarified that return parameters of the various Get commands are unmodified if an error occurred. - Added issue 39. - Added issue 40, and clarified failed re-link behavior in the spec. - Added issue 41. - Clarified that the compile status of a shader object does not change when source is loaded in it. - Clarified that the link status of a program object is not affected by attaching or detaching or re-compiling attached shader objects. - Few fixes to the Errors section. - Clarified GetUniformLocation and GetActiveUniform when addressing the first element of an array. Added issue 42 explaining this. - Added issue 43, 44 and 45. Revision: 0.89 04/06/2004 - Updated the Shading Language Version referenced to the now official version 1.10. - Added language describing the Uniform* loading commands that Uniform1i{v} is used to load samplers. - Clarified issues 36, 42 and 43 based on Pat's feedback. - Changed the examples in issue 45 a bit. Hopefully for the better. - Added issue 46. - Removed an error condition I had added earlier for glBegin(). - Expanded section 2.15 to include the exact conditions when validation is allowed to fail. Previously these conditions were only in the Errors section, listed for glBegin(). - ARB-GL2 workgroup approved version.