XXX - Incomplete

Name

    EXT_multiple_textures

Name Strings

    GL_EXT_multiple_textures

Number

    ???

Basic approach:

Initially I started out adding enumerants and functions everywhere to
add the concept of multiple current textures to the OpenGL API.  This
quickly became unwieldy because the number of functions affected is very
large and the number of enumerants needed for texture control, queries,
texgen, evaluators, vertex arrays, etc. soared into the hundreds.

Rather than try to change a fundamental assumption of the API, I decided
to keep the notion of a current texture but add a function to allow
setting that current texture to any of a number of textures kept current
in the implementation.  The API changes are thus much smaller.  The
internal changes are still substantial but smaller than in the previous
approach because of the lack of new parameters to verify and new
functions to implement.

New enumerants:

GL_MAX_CURRENT_TEXTURES

Specifies the maximum number of textures which may simultaneously be
current.  This number must be at least two and can be no more than
sixteen.

GL_CURRENT_TEXTURE_INDEX

Retrieves the index of the current texture.

GL_SUB
GL_COMBINE_COLOR
GL_TWICE_COMBINE_COLOR
GL_TEX_COLOR
GL_TWICE_TEX_COLOR
GL_ONE_MINUS_COMBINE_COLOR
GL_ONE_MINUS_TEX_COLOR
GL_COMBINE_ALPHA
GL_TWICE_COMBINE_ALPHA
GL_COMBINE_ALPHA_REPLACES_COLOR
GL_TEX_ALPHA
GL_TWICE_TEX_ALPHA
GL_TEX_ALPHA_REPLACES_COLOR
GL_ONE_MINUS_COMBINE_ALPHA
GL_ONE_MINUS_TEX_ALPHA

Add operations allowed for texturing combining.

GL_TEXCOMBINE_CLAMP

Specifies whether intermediate results should be clamped during texture
combining.  This may result in higher or lower performance depending on
the implementation.  An application can check whether clamping is
desirable or not by querying the following enumerant.

GL_TEXCOMBINE_NATURAL_CLAMP

Indicates whether the implementation prefers texcombine clamping or not.
Querying this enumerant returns GL_TRUE, GL_FALSE or GL_DONTCARE,
indicating that the implementation prefers clamping, does not prefer
clamping or is unaffected by the clamping setting.

The following enumerants are numbered consecutively from the 0 entry to
the 15 entry, where n is replaced by the number of the particular
instance.  This restricts the possible set of current textures to
sixteen simultaneously active textures.

GL_TEXCOORDn_BIT

Used to indicate the texture coordinate to affect.  The legal range for
n for a particular implementation is from 0 to
GL_MAX_CURRENT_TEXTURES-1.

GL_TEXCOMBINE_COMBINE_COLORn
GL_TEXCOMBINE_COLOR_OPn
GL_TEXCOMBINE_TEX_COLORn 
GL_TEXCOMBINE_COMBINE_ALPHAn
GL_TEXCOMBINE_ALPHA_OPn
GL_TEXCOMBINE_TEX_ALPHAn

Used to query the current settings for texture combine functions.  The
legal range for n for a particular implementation is 0 to
GL_MAX_CURRENT_TEXTURES-2.

New functions:

void glCurrentTextureIndex(GLuint index);

Sets the current texture index.  index must range from 0 to
GL_MAX_CURRENT_TEXTURES-1 or GL_INVALID_VALUE is generated.  The current
texture index is used for every OpenGL API which references texture
state without explicitly specifying a texture index.

The default index is zero.  The current index can be retrieved with
glGet for GL_CURRENT_TEXTURE_INDEX.

void glMultiTexCoord{1234}{sifd}{v}(GLbitfield mask, T coords);

Sets the texture coordinate for all textures with a corresponding bit
set in the given mask.  mask is a bitfield made up of any combination of
bits taken from the GL_TEXCOORDn_BIT values. Other parameters are as for
glTexCoord.  glMultiTexCoord(n, ...) can be replaced by the code
sequence
	glCurrentTextureIndex(n);
	glTexCoord(...);
for each bit n set in the mask.  It is included for performance and
programming convenience.

There is no corresponding function for retrieval as queries are not
expected to be common enough to warrant a special query enumerant.  To
query the n'th texture coordinate, set the texture index to n and do a
glGet for GL_CURRENT_TEXTURE_COORDS.

void glBindNthTexture(GLuint index, GLenum target, GLuint texture);

Bind the given texture object to the n'th slot for the given target.
Operates exactly as glBindTexture except for directly acting on the
indexed texture instead of the current texture index.  The current
texture index is not changed.

void glNthTexCombineFunc(GLuint index, GLenum combineColorFactor, GLenum
colorOp, GLenum texColorFactor, GLenum combineAlphaFactor, GLenum
alphaOp, GLenum texAlphaFactor);

glNthTexCombineFunc is used to control how all of the currently enabled
textures are combined together before being combined with the fragment.
The n'th combine function controls how texture values at index n and n+1
are combined, so there are m-1 combine functions for m enabled textures.
index selects the function to be set while combineColorFactor, colorOp,
texColorFactor, combineAlphaFactor, alphaOp and texAlphaFactor control
how texture values are combined to produce the resulting texture value.

When a fragment is being textured all current textures contribute to a
final texture value which is combined with the fragment through the
normal texture environment function.  This texture value is initialized
from the first enabled texture and then modified by following enabled
textures using the texture combine functions.

In the following equation:
	Tc is the current combined texture color.
	Ta is the current combined texture alpha.
	texColor(n) is the n'th texture's color.
	texAlpha(n) is the n'th texture's alpha.  If the texture has no
alpha the value is one.

	n = 0
				Tc = texColor(0), Ta = texAlpha(0).

	n > 0
				Tc = (Tc * combineColorFactor) colorOp
(texColor(n) * texColorFactor).
				Ta = (Ta * combineAlphaFactor) alphaOp
(texAlpha(n) * texAlphaFactor).

combineColorFactor and texColorFactor are one of GL_ZERO, GL_ONE,
GL_COMBINE_COLOR, GL_TWICE_COMBINE_COLOR, GL_TEX_COLOR,
GL_TWICE_TEX_COLOR, GL_COMBINE_ALPHA, GL_TWICE_COMBINE_ALPHA,
GL_COMBINE_ALPHA_REPLACES_COLOR, GL_TEX_ALPHA, GL_TWICE_TEX_ALPHA,
GL_TEX_ALPHA_REPLACES_COLOR, GL_ONE_MINUS_COMBINE_COLOR,
GL_ONE_MINUS_TEX_COLOR, GL_ONE_MINUS_COMBINE_ALPHA and
GL_ONE_MINUS_TEX_ALPHA.  Most of these factors are self-explanatory.
The ALPHA_REPLACES_COLOR enumerants replicate the requested alpha and
replace the color rather than doing a multiply.  This allows the alpha
channel to contain a monochrome color for specular highlights or other
effects.

combineAlphaFactor and texAlphaFactor are one of GL_ZERO, GL_ONE,
GL_COMBINE_ALPHA, GL_TWICE_COMBINE_ALPHA, GL_TEX_ALPHA,
GL_TWICE_TEX_ALPHA, GL_ONE_MINUS_COMBINE_ALPHA and
GL_ONE_MINUS_TEX_ALPHA.

colorOp and alphaOp are one of GL_ADD or GL_SUB.

If GL_TEXCOMBINE_CLAMP is enabled then the results produced at each
stage are clamped to the range (0.0, 1.0).  If it isn't enabled, results
are only clamped after the final computation.  Since results are always
clamped after the final texcombine stage, GL_TEXCOMBINE_CLAMP only has
an effect if more than two textures are enabled.

Texture combine functions can be set for any index regardless of the
texture enable state.  The functions may not be used but it is legal to
set them.  Texture values are treated in a generic way during texture
combining so there are no inherent restrictions on the formats of the
textures in the current texture vector.  Implementations are encouraged
to support arbitrary mixtures of texture size, format and
dimensionality.  Applications can determine if an implementation cannot
support a particular mix of textures through the proxy mechanism.

The default functions are (GL_ONE, GL_ADD, GL_ONE, GL_ONE, GL_ADD,
GL_ONE).

New capabilities for existing functions:

glGet{*}v

GL_MAX_CURRENT_TEXTURES and GL_CURRENT_TEXTURE_INDEX can be retrieved
through glGet.  The enable state of GL_TEXCOMBINE_CLAMP can be retrieved
with glGet.  GL_TEXCOMBINE_NATURAL_CLAMP's setting can be retrieved with
glGet.

The current texture combine functions can be retrieved through glGet
using the GL_TEXCOMBINE_COMBINE_COLORn, GL_TEXCOMBINE_COLOR_OPn,
GL_TEXCOMBINE_TEX_COLORn, GL_TEXCOMBINE_COMBINE_ALPHAn,
GL_TEXCOMBINE_ALPHA_OPn and GL_TECOMBINE_TEX_ALPHAn enumerants.

glEnable, glDisable, glIsEnabled

GL_TEXCOMBINE_CLAMP can be enabled, disabled and checked using the
standard enable functions.

Impact of texture index on existing functions:

glMatrixMode

Each texture coordinate has its own texture matrix so N texture matrices
must be kept instead of one.

glEnable
glDisable
glIsEnabled
glGet{*}v

All of the textures supported by an implementation can be enabled and
disabled using the GL_TEXTURE_1D and GL_TEXTURE_2D enumerants.  As with
single texture implementations, if both textures for a particular n are
enabled then the 2D texture takes precedence.  Enabling texture n
enables all textures between zero and n.  Disabling texture n disables
all textures from n to GL_MAX_CURRENT_TEXTURES-1.  This behavior allows
quick enabling and disabling of multiple textures while preventing
sparse enable states.

Each enabled texture must be consistent according to the OpenGL rules or
it is as if texturing is disabled.

glTexImage{12}D
glCopyTexImage{12}D
glTexSubImage{12}D
glCopyTexSubImage{12}D
glTexParam{if}{v}
glBindTexture
glGetTexGen{if}v
glGetTexParameter{if}v
glGetTexLevelParameter{if}v
glGetTexImage

All of the texture control functions must now cope with N times as many
textures.

Proxies become even more important with multiple texture support as some
implementations may have restrictions on what kinds of textures can be
used simultaneously.  The proxy mechanism can be used to determine if a
particular mix of textures is supported or not.

glPushAttrib
glPopAttrib

All current texture state is pushed and popped.

glMatrixMode
glPushMatrix
glPopMatrix

Each texture coordinate has its own transform and texture stack.

Texture Coordinate Generation and Evaluators

Automatically generated texture coordinates affect the n'th texture
coordinate, where n is the current texture index.  N times as many
texture coordinate generators or texture-coordinate-affecting evaluators
can now be active.  It is invalid to specify evaluator targets other
than the texture coordinates for non-zero current texture indices.

Other State Queries

All state queries for texture-related information must now return
information for the currently selected texture.

Change History

04/15/97
				Changed 'left' to 'combine' and 'right'
to 'tex' to try and make names more descriptive.
				Changed all enumerants ending in _n to
just n to match existing style for consecutive enumerants.
				Changed TEXCOORD_BIT_n to TEXCOORDn_BIT
for consistency.

02/06/97
				Changed glNthTexCoord to glMultiTexCoord
to allow multiple texture coordinates to be set with a single call.  It
is expected that texture coordinates will commonly be the same for
multiple textures and there is some hardware that supports texture
coordinate broadcasting so this is an important programming and
performance issue.

02/04/97	
				Added GL_TEXCOMBINE_NATURAL_CLAMP to
give applications a way to determine whether texcombine clamping should
be enabled or not for maximum performance.

01/27/97
				Added GL_*_ALPHA_REPLACES_COLOR so that
alpha values can override color values when doing texture combining.

01/21/97
				Chose sixteen as the maximum number of
current textures possibly supported.
				glBindNthTexture added.
				glNthTexBlendFunc changed to
glNthTexCombineFunc.
				Scaling factors split into separate
color and alpha factors in glNthTexCombineFunc.  New scaling factors
added and all scaling factors explicitly specified.
				Combine function query enumerants
changed and extended to match glNthTexCombineFunc.
				GL_MULT deleted as an allowed operator
in glNthTexCombineFunc.
				GL_TEXCOMBINE_CLAMP added.
				Changed texture enabled/disable to be
bulk operations rather than affecting a single texture.
				Specified that multiple texture
transforms and stacks must be kept.
				Encouraged implementations to support
mixing texture types in the current texture vector.
				Deleted Questions section as all
previously open issues have been closed.

01/16/97
				Initial release.
