Back to the OpenGL extension cross reference

GL_ARB_shader_objects


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 <pname> argument of GetHandleARB:

PROGRAM_OBJECT_ARB 0x8B40

Accepted by the <pname> 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 <params> parameter of GetObjectParameter{fi}vARB:

SHADER_OBJECT_ARB 0x8B48

Returned by the <type> 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 <obj> is not a type that can
be attached to a container object or if <containerObj> 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 <attachedObj> is not attached to any other container
object in any rendering context, and the object is flagged for deletion,
the information for <attachedObj> and the data for <attachedObj> is
deleted. If <attachedObj> is not attached to <containerObj>, the error
INVALID_OPERATION is generated. The error INVALID_OPERATION is also
generated if <containerObj> 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 <shaderType> 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 <string> argument is an array of pointers to one or more, optionally
null terminated, character strings that make up the source code. The
<length> 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 <length> is set to NULL, all strings in the <string>
argument are considered null terminated. The ShaderSourceARB command
sets the source code for the specified shader object <shaderObj> to the
text strings in the <string> 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 <count>. Any length passed in excludes the null
termination in its count. If <shaderObj> 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 <shaderObj>. 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
<shaderObj> 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 <shaderObj>. If
<shaderObj> 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 <programObj>. 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
<programObj>, are not compiled successfully, or if more active uniform
or active sampler variables are used in <programObj> 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 <programObj>. If <programObj> 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 <programObj> 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 <programObj> 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 <programObj> has not been linked successfully. If
<programObj> 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 <name>. <name>
has to be a null terminated string, without white space. The value of -1
will be returned if <name> does not correspond to an active uniform
variable name in <programObj> or if <name> starts with the reserved
prefix "gl_". If <programObj> has not been successfully linked, or if
<programObj> 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 <name> cannot be a structure, an array of structures, or a
subcomponent of a vector or a matrix. In order to identify a valid
<name>, the "." (dot) and "[]" operators can be used in <name> 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
<name> 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 <index>.
The <index> of 0 selects the first active uniform, and <index> 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 <index> is greater
than or equal to OBJECT_ACTIVE_UNIFORMS_ARB, the error INVALID_VALUE is
generated.

The parameter <programObj> is a handle to a program object for which the
command LinkProgramARB has been issued in the past. It is not necessary
for <programObj> to have been linked successfully. The link could have
failed because the number of active uniforms exceeded the limit. If
<programObj> is not of type PROGRAM_OBJECT_ARB, the error
INVALID_OPERATION is generated.

If an error occurred, the return parameters <length>, <size>, <type> and
<name> will be unmodified.

For the selected uniform, the uniform name is returned into <name>. The
string <name> will be null terminated. The actual number of characters
written by the GL into <name> is returned in <length>. This count
excludes the null termination. If <length> is NULL then the GL ignores
this parameter. The maximum number of characters the GL is allowed to
write into <name> is passed in by <maxLength>. 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
<programObj> 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
<type>. The size of the uniform is returned into <size>. The value in
<size> is in units of the type returned in <type>. 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 <name>, subject to the restrictions
listed above. The type of the array is returned in <type>. The <size>
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, <length> will be set to zero
and <name> 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 <location>.

The Uniform{1234}f{v}ARB commands will load one or more floating-point
values <count> 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
<count> 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 <count> times into a uniform location defined as a matrix or an
array of matrices. If <transpose> 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 <location> 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 <location> is not -1 and <location> 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 <programObj> 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 <programObj> 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.
<pname> 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 <pname> 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 <obj> in <params>.
The parameter value to return is specified by <pname>.

If <pname> is OBJECT_TYPE_ARB, GetObjectParameter{if}vARB returns
PROGRAM_OBJECT_ARB if <obj> references a program object. It returns
SHADER_OBJECT_ARB if <obj> references any shader object. If <obj> is not
of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error
INVALID_OPERATION is generated.

If <pname> is OBJECT_SUBTYPE_ARB, GetObjectParameter{if}vARB returns the
subtype of a shader object. If <obj> is not of type SHADER_OBJECT_ARB,
the error INVALID_OPERATION is generated.

If <pname> 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
<obj> is not of type PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error
INVALID_OPERATION is generated.

If <pname> 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 <obj>
is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is
generated.

If <pname> 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
<obj> is not of type PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is
generated.

If <pname> 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
<obj> is not of type SHADER_OBJECT_ARB, the error INVALID_OPERATION is
generated.

If <pname> 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 <obj> is not of type
PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is
generated.

If <pname> 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 <obj> is not of type PROGRAM_OBJECT_ARB the error
INVALID_OPERATION is generated.

If <pname> 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 <obj> is not of type PROGRAM_OBJECT_ARB the error
INVALID_OPERATION is generated.

If <pname> 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 <obj> is not of type PROGRAM_OBJECT_ARB the
error INVALID_OPERATION is generated.

If <pname> 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 <obj> is not
of type SHADER_OBJECT_ARB the error INVALID_OPERATION is generated.

If an error occurred, the return parameter <params> will be unmodified.

The command

void GetAttachedObjectsARB(handleARB containerObj, sizei maxCount,
sizei *count, handleARB *obj)

returns the handles of objects attached to <containerObj> in <obj>. The
actual number of object handles written by the GL into <obj> is returned
in <count>. If no objects are attached, <count> is set to zero. If
<count> is NULL then the GL ignores this parameter. The maximum number
of handles the GL is allowed to write into <obj> is passed in by
<maxCount>. The number of objects attached to <containerObj> is given by
OBJECT_ATTACHED_OBJECTS_ARB, which can be queried with
GetObjectParameter{if}vARB. If <containerObj> is not of type
PROGRAM_OBJECT_ARB, the error INVALID_OPERATION is generated. If an
error occurred, the return parameters <count> and <obj> 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 <infoLog>. This string will
be null terminated. The actual number of characters written by the GL
into <infoLog> is returned in <length>, excluding the null termination.
If <length> is NULL then the GL ignores this parameter. The maximum
number of characters the GL is allowed to write into <infoLog> is passed
in by <maxLength>. 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 <obj> 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 <obj> 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 <obj> is not of type
PROGRAM_OBJECT_ARB or SHADER_OBJECT_ARB, the error INVALID_OPERATION is
generated. If an error occurred, the return parameters <length> and
<infoLog> 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 <source> the string making up the source code for the
shader object <obj>. The string <source> will be null terminated. The
actual number of characters written by the GL into <source> is returned
in <length>, excluding the null termination. If <length> is NULL then
the GL ignores this parameter. The maximum number of characters the GL
is allowed to write into <source> is passed in by <maxLength>. The
string <source> 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 <obj> is not of type SHADER_OBJECT_ARB,
the error INVALID_OPERATION is generated. If an error occurred, the
return parameters <length> and <source> 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 <location> for
program object <programObj> in the array <params>. The type of the
uniform at <location> determines the number of values returned. The
error INVALID_OPERATION is generated if <programObj> is not of type
PROGRAM_OBJECT_ARB or if <programObj> has not been linked successfully
or if <location> is not a valid location for <programObj>. 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 <params> 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 <obj> is
not of type SHADER_OBJECT_ARB or if <containerObj> is not of type
PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by AttachObjectARB if <obj> is
already attached to <containerObj>.

The error INVALID_OPERATION is generated by DetachObjectARB if
<attachedObj> is not attached to <containerObj>.

The error INVALID_OPERATION is generated by DetachObjectARB if
<containerObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by ShaderSourceARB and
CompileShaderARB if <shaderObj> is not of type SHADER_OBJECT_ARB.

The error INVALID_OPERATION is generated by LinkProgramARB if
<programObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by UseProgramObjectARB if
<programObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by UseProgramObjectARB if
<programObj> could not be made part of the current state.

The error INVALID_OPERATION is generated by GetUniformLocationARB if
<programObj> is not of type PROGRAM_OBJECT_ARB or if <programObj> has
not been linked successfully.

The error INVALID_OPERATION is generated by GetActiveUniformARB if
<programObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_VALUE is generated by GetActiveUniformARB if <index>
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
<location> is not -1 and <location> 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
<programObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB
if <pname> is OBJECT_TYPE_ARB or OBJECT_DELETE_STATUS_ARB or
OBJECT_INFO_LOG_LENGTH_ARB and <obj> is not of type PROGRAM_OBJECT_ARB
or SHADER_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB
if <pname> 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 <obj> is not of type
PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetObjectParameter{if}vARB
if <pname> is OBJECT_SUBTYPE_ARB or OBJECT_COMPILE_STATUS_ARB or
OBJECT_SHADER_SOURCE_LENGTH_ARB and <obj> is not of type
SHADER_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetAttachedObjectsARB if
<containerObj> is not of type PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetInfoLogARB if <obj> is
not of type SHADER_OBJECT_ARB or PROGRAM_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetShaderSourceARB if <obj>
is not of type SHADER_OBJECT_ARB.

The error INVALID_OPERATION is generated by GetUniform{if}vARB if
<programObj> is not of type PROGRAM_OBJECT_ARB or if <programObj> has
not been linked successfully or if <location> is not a valid location
for <programObj>.

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.

Implementation Support


   List of OpenGL implementations supporting the GL_ARB_shader_objects extension

Original File


   Original text file for the GL_ARB_shader_objects extension


Page generated on Sun Nov 20 18:36:48 2005