OES_draw_texture

Name

OES_draw_texture

Name Strings

GL_OES_draw_texture

Contact

Tom Olson (t-olson 'at' ti.com)

Notice

Copyright (c) 2004-2013 The Khronos Group Inc. Copyright terms at
    http://www.khronos.org/registry/speccopyright.html

Specification Update Policy

Khronos-approved extension specifications are updated in response to
issues and bugs prioritized by the Khronos OpenGL ES Working Group. For
extensions which have been promoted to a core Specification, fixes will
first appear in the latest version of that core Specification, and will
eventually be backported to the extension document. This policy is
described in more detail at
    https://www.khronos.org/registry/OpenGL/docs/update_policy.php

Status

Ratified by the Khronos BOP, Aug 5, 2004.

Version

Last Modified Date: 21 July 2004
Author Revision 0.96

Number

OpenGL ES Extension #7

Dependencies

OES_fixed_point is required.
EXT_fog_coord affects the definition of this extension.
This extension is written against the OpenGL 1.3 and
OpenGL ES 1.0 Specifications.

Overview

This extension defines a mechanism for writing pixel
rectangles from one or more textures to a rectangular
region of the screen.  This capability is useful for
fast rendering of background paintings, bitmapped font
glyphs, and 2D framing elements in games.  This
extension is primarily intended for use with OpenGL ES.

The extension relies on a new piece of texture state
called the texture crop rectangle, which defines a
rectangular subregion of a texture object.  These
subregions are used as sources of pixels for the texture
drawing function.

Applications use this extension by configuring the
texture crop rectangle for one or more textures via
ActiveTexture() and TexParameteriv() with pname equal to
TEXTURE_CROP_RECT_OES.  They then request a drawing
operation using DrawTex{sifx}[v]OES().  The effect of
the latter function is to generate a screen-aligned
target rectangle, with texture coordinates chosen to map
the texture crop rectangle(s) linearly to fragments in
the target rectangle.  The fragments are then processed
in accordance with the fragment pipeline state.

IP Status

No known IP issues.

Issues

(1) Should we pass a texture name to the draw function,
    or use the currently bound texture?

    RESOLVED. Use the textures bound to currently
    enabled texture units.  This makes it easy for
    drivers to implement DrawTex*() using existing
    texture hardware.  If we didn't do this, they would
    have to save and restore the state of the texture
    unit(s).

(2) Doesn't DrawPixels make this extension unnecessary?

    RESOLVED.  No.  DrawPixels is hard to support 
    efficiently in hardware because the source pixels
    are in application memory.  Also, the pixel setup
    pipeline (PixelTransfer, PixelMap etc.) is redundant
    for the intended applications.  Also, PixelZoom 
    looks ugly when the zoom factors are large, and there
    is no way to control filtering.  Using textures and
    texture units solves all of these problems.

(3) Doesn't ARB_point_sprite make this extension unnecessary?

    RESOLVED. No.  Key differences include:
    * ARB_point_sprite uses the entire source texture to
      paint a point, i.e. its texture coordinates range
      from 0.0 to 1.0.  This extension allows a
      subregion of a texture to be used as the source.
    * ARB_point_sprite sprites are limited by the
      maximum point size, which may be small.  This
      extension is limited only by the maximum supported
      texture size and the screen size.
    * ARB_point_sprite sprites are square.  This
      extension supports general rectangles as sprite
      shapes.
    * ARB_point_sprite sprites are clipped as points, so
      if the center of a sprite falls outside the
      frustrum, nothing is drawn.  This extension draws
      any portion of a sprite that lies within the
      viewing frustrum.  (There is a well-known
      work-around for this, but it's ugly.)

(4) How is the texture sampled?  

    RESOLVED.  It is sampled like a normal texture, and
    not like an image sent to DrawPixels.  This
    facilitates implementing with texture hardware.

(5) How does this work when multisampling is enabled?

    RESOLVED. Implementations should generate
    multisample texture coordinates using the same
    method they use in normal texture mapping.
    Approximations are acceptable, e.g. they may use the
    same texture value for all samples associated with a
    fragment generated by DrawTex*(), even if they use
    another policy for multisampled triangle rendering.

(6) Do we really want the full fragment pipeline to be
    active?

    RESOLVED. Yes, on grounds of orthogonality and
    simplicity.  Again, this makes it easy for existing
    hardware to implement the extension.

(7) How does this interact with user clip planes?

    RESOLVED.  User clip planes are ignored. This is a
    screen-level operation, so geometric entities like
    clip planes are irrelevant.

(8) How does this interact with mip-mapping?

    RESOLVED.  It behaves exactly as in texturing.
    This is really easy to do as LOD is a constant
    across the target rectangle.
 
(9) What happens when multiple texture units are
    enabled?

    RESOLVED. All enabled texture units participate in
    generating the final fragment color.  Each unit
    generates its own s,t based on its texture's crop
    rectangle.

(10) Should the target location be specified by the current raster position (RasterPos or WindowPos), or by arguments to DrawTex*OES()?

    RESOLVED.  Use arguments passed to DrawTex*. In the
    intended uses, the target will be set once per call,
    so using arguments saves one inner loop function
    call.

(11) Do we want stretch-blt capability?

    RESOLVED. Yes.  Supply a window size as well as
    window position to DrawTex*()

(12) OpenGL ES issue: WindowPos (if we use it) adds 16 entry points ({23}{sifd}[v]), which seems like a lot even if they are trivial. Can we live with a subset? (Note that the ‘d' versions go away, but they are replaced by ‘x' versions.)

    RESOLVED. Moot, as we do not use WindowPos.  But the
    intent was to add only 3{si}[v] versions (four entry
    points).  This is not orthogonal and may be
    surprising.  But there is no intent to support
    sub-pixel placement of rectangles, so the {fx}
    versions are superfluous.  {2} versions are easy to
    express using {3} versions.  Vector and individual
    argument versions are kept to reduce the surprise
    factor, and because constructing calls to a v-type
    function is a huge pain if you don't already have
    the data in vector format.

(13) TexCropRect*OES adds eight entry points. Can we live with a subset? For the intended use, integer values suffice, so the {fx} versions are superfluous. But orthogonality and ‘least-astonishment' are virtues too.

    RESOLVED. Moot. Replace with TexParameteriv().

(14) Would it be better to remove the texture crop rectangle from the state, and instead pass parameters to DrawTextureOES()?

    RESOLVED. No.  Drawing the same pixel pattern multiple
    times is a plausible usage scenario.

(15) Should texture crop rect parameters be stored internally as integers, or as float/fixed? I.e. should we allow the crop rect to include fractional texels? This is more flexible, but is not the intended use. Software implementations would have to add a test for the (normal) special case of integer bounds.

    RESOLVED.  Integer only.  Texture crop rect is
    conceptually a subregion of an integer grid, so its
    natural coordinates are integers.

(16) Should we have a single global crop rect, or one per texture unit?

    RESOLVED.  Neither.  We should have one per texture,
    with TexParameter setting the rect for the currently
    active texture.  It isn't a lot of state, it
    attaches the rect to a specific texture (which makes
    sense) rather than a texture unit (which doesn't),
    it is more orthogonal, and it allows tex coords to
    be meaningful (if not actually useful) when multiple
    texture units are enabled.

(17) Should the destination rectangle specified by DrawTex*() be defined as integer only like the crop rectangle, or should its parameters be real-valued?

    RESOLVED.  Real-valued.  Since we now support
    stretch-blit, we want the ability to animate the
    scaling factor smoothly.  If the destination rectangle
    size is rounded to an integer, you won't get smooth
    animation.

New Procedures and Functions

Added to OpenGL 1.3 and OpenGL ES 1.0:

void DrawTex{sifx}OES(T X, T Y, T Z, T W, T H);
void DrawTex{sifx}vOES(T* coords);

Added to OpenGL ES 1.0:

void TexParameter{ifx}v(enum target, enum pname, T param);

New Types

None

New Tokens

Accepted by the parameter of TexParameter() and GetTexParameter():

TEXTURE_CROP_RECT_OES        0x8B9D

Additions to Chapter 2 of the OpenGL 1.3 Specification (OpenGL Operation):

None

Additions to Chapter 3 of the OpenGL 1.3 Specification (Rasterization):

In Table 3.19: Texture parameters and their values, p. 133, add this line at the end of the table:

Name Type Legal Values ——————————————————– TEXTURE_CROP_RECT_OES 4 integers any value

In section 3.8.4, Texture Parameters, after paragraph 3 (page 132) insert new paragraph:

The texture parameter TEXTURE_CROP_RECT_OES controls the operation of DrawTex{sifx}[v]OES(), as described in section 5.7. It has no effect on the rasterization of other primitives.

Additions to Chapter 4 of the OpenGL 1.3 Specification (Per-Fragment Operations and the Frame Buffer):

None

Additions to Chapter 5 of the OpenGL 1.3 Specification (Special Functions):

In Chapter 5, paragraph one, replace the last two words ("and hints.") with the words "hints, and texture rectangle drawing."

After section 5.6, p. 196, insert:

5.7 Texture Rectangle Drawing

OpenGL supports drawing sub-regions of a texture to
rectangular regions of the screen using the texturing
pipeline.  Source region size and content are determined
by the texture crop rectangle(s) of the enabled
texture(s) (see section 3.8.14).

The functions 

void DrawTex{sifx}OES(T Xs, T Ys, T Zs, T Ws, T Hs);
void DrawTex{sifx}vOES(T *coords);

draw a texture rectangle to the screen.  Xs, Ys, and Zs
specify the position of the affected screen rectangle.
Xs and Ys are given directly in window (viewport)
coordinates.  Zs is mapped to window depth Zw as follows:

             { n,                 if z <= 0
        Zw = { f,                 if z >= 1
             { n + z * (f - n),   otherwise

where <n> and <f> are the near and far values of
DEPTH_RANGE.  Ws and Hs specify the width and height of
the affected screen rectangle in pixels.  These values
may be positive or negative; however, if either (Ws <=
0) or (Hs <= 0), the INVALID_VALUE error is generated.

Calling one of the DrawTex functions generates a
fragment for each pixel that overlaps the screen
rectangle bounded by (Xs, Ys) and (Xs + Ws), (Ys + Hs).
For each generated fragment, the depth is given by Zw
as defined above, and the color by the current color.

If EXT_fog_coord is supported, and FOG_COORDINATE_SOURCE_EXT
is set to FOG_COORINATE_EXT, then the fragment distance for
fog purposes is set to CURRENT_FOG_COORDINATE. Otherwise,
the fragment distance for fog purposes is set to 0.

Texture coordinates for each texture unit are computed
as follows:

Let X and Y be the screen x and y coordinates of each
sample point associated with the fragment.  Let Wt and
Ht be the width and height in texels of the texture
currently bound to the texture unit.  (If the texture is
a mipmap, let Wt and Ht be the dimensions of the level
specified by TEXTURE_BASE_LEVEL.)  Let Ucr, Vcr, Wcr and
Hcr be (respectively) the four integers that make up the
texture crop rectangle parameter for the currently bound
texture.  The fragment texture coordinates (s, t, r, q)
are given by

s = (Ucr + (X - Xs)*(Wcr/Ws)) / Wt
t = (Vcr + (Y - Ys)*(Hcr/Hs)) / Ht
r = 0
q = 1

In the specific case where X, Y, Xs and Ys are all
integers, Wcr/Ws and Hcr/Hs are both equal to one, the
base level is used for the texture read, and fragments
are sampled at pixel centers, implementations are
required to ensure that the resulting u, v texture
indices are also integers.  This results in a one-to-one
mapping of texels to fragments.

Note that Wcr and/or Hcr can be negative.  The formulas
given above for s and t still apply in this case.  The
result is that if Wcr is negative, the source rectangle
for DrawTex operations lies to the left of the reference
point (Ucr, Vcr) rather than to the right of it, and
appears right-to-left reversed on the screen after a
call to DrawTex.  Similarly, if Hcr is negative, the
source rectangle lies below the reference point (Ucr,
Vcr) rather than above it, and appears upside-down on
the screen.

Note also that s, t, r, and q are computed for each
fragment as part of DrawTex rendering.  This implies
that the texture matrix is ignored and has no effect on
the rendered result.

Additions to Chapter 6 of the OpenGL 1.3 Specification (State and State Requests):

None

Additions to Appendix A of the OpenGL 1.3 Specification (Invariance):

None

Additions to the AGL/GLX/WGL Specifications:

None

Additions to Chapter 2 of the OpenGL ES 1.0 Specification (OpenGL Operation):

None

Additions to Chapter 3 of the OpenGL ES 1.0 Specification (Rasterization):

After the fourth paragraph of section 3.8, Texturing, p. 17, insert a new paragraph:

DrawTexOES is supported.

In the (unnamed) table of supported texture functions, p. 19, delete the entry for TexParameter{i[v] fv}(), and replace the entry for TexParameterf() with the following:

OpenGL 1.3 Common Common-Lite ———————————————— —— ———– TexParameter{if}v target = TEXTURE_2D, pname = TEXTURE_CROP_RECT_OES (check) (check) target = TEXTURE_1D, TEXTURE_3D, TEXTURE_CUBE_MAP - - pname = TEXTURE_MIN_FILTER, TEXTURE_MAG_FILTER (check) (check) pname = TEXTURE_WRAP_S, TEXTURE_WRAP_T (check) (check) pname = TEXTURE_BORDER_COLOR - - pname = TEXTURE_MIN_LOD, TEXTURE_MAX_LOD - - pname = TEXTURE_BASE_LEVEL, TEXTURE_MAX_LEVEL - - pname = TEXTURE_WRAP_R - - pname = TEXTURE_PRIORITY - -

In the same table, modify the entry for GetTexParameter{if}v() to read as follows:

OpenGL 1.3 Common Common-Lite ——————————————————- —— ———– GetTexParameter{if}v(enum target, enum param, T *params) (check) (dagger)

Additions to Chapter 4 of the OpenGL ES 1.0 Specification (Per-Fragment Operations and the Frame Buffer):

None

Additions to Chapter 5 of the OpenGL ES 1.0 Specification (Special Functions):

None

Additions to Chapter 6 of the OpenGL ES 1.0 Specification (State and State Requests):

At the end of table 6.15, Texture Objects (cont.), p. 36, insert a new entry:

State Exposed Queriable ——————————————- ——- ——— TEXTURE_CROP_RECT_OES (check) (check)

Replace the fourth paragraph of Chapter 7, Core Additions and Extensions, p. 46, with the following:

The Common and Common-Lite profiles add subsets of the OES_byte_coordinates, OES_fixed_point, and OES_single_precision ES-specific extensions as core additions; OES_readFormat and OES_compressed_paletted_texture as required profile extensions; and OES_query_matrix and OES_draw_texture as optional profile extensions.

Additions to Chapter 7 of the OpenGL ES 1.0 Specification (Core Additions and Extensions):

At the end of Table 7.1: OES Extension Disposition, add a new entry:

Extension Name Common Common-Lite ———————— —————— —————— OES_draw_texture optional extension optional extension

After section 7.6, Query Matrix, insert

7.7 Draw Texture

The optional OES_draw_texture extension allows rectangular subregions of a texture to be written to the screen using the fragment pipeline. Texture coordinates are generated for each fragment in the destination rectangle, such that texels in the source texture are mapped linearly to pixels on the screen.

GLX Protocol

None

Errors

None

Dependencies on OES_fixed_point

The DrawTex{sifx}v function makes use of the ‘x' suffix and (in that form) accepts parameters of type fixed, as defined in OES_fixed_point.

Dependencies on EXT_fog_coord

EXT_fog_coord affects the distance that is used in the fog equations for fragments generated by DrawTex{sifx}v. If EXT_fog_coord is not supported, the fog distance for each fragment is set to zero. If EXT_fog_coord is supported, the fog distance depends on the value of FOG_COORDINATE_SOURCE_EXT. If the latter is set to FRAGMENT_DEPTH_EXT, the fog distance is again set to zero. If FOG_COORDINATE_SOURCE_EXT is set to FOG_COORDINATE_EXT, the distance is set to CURRENT_FOG_COORDINATE.

New State

(table 6.16, Texture Objects (cont.), p. 224):

                                         Initial   Get Value         Type   Get Command       Value       Description   Sec   Attribute   ---------         ----   -----------       ---------   -----------   ---   ---------   TEXTURE_CROP_RECT  4xZ   GetTexParameteriv 0,0,0,0     texture crop  5.7   texture
                                                     rectangle

New Implementation Dependent State

None.

Revision History

July 21, 2004 (v0.96)
    - Modified to say that if Ws or Hs < 0 then an 
      INVALID_VALUE error is generated

July  16, 2004 (v0.95)
    - Corrected a bug in the text description of DrawTex
      with negative crop rectangle width or height.  Thanks
      to Petri Kero for the catch.

July  14, 2004 (v0.9)
    - added a Zs parameter to the destination rectangle
      location specification.  This allows applications
      to control the depth coordinate of fragments generated
      by DrawTex().
    - Removed DOS-mode carriage returns.  

June  29, 2004 (v0.8)
    - Corrected dependencies to comply with ARB recommended
      practice for extensions.
    - Restructured the "Additions to the OpenGL ES 1.0 Spec"
      sections to separate changes by chapter, following
      ARB recommended practice for OpenGL and
      GLX specifications.
    - Modified TexParameter usage to be consistent with
      OpenGL ES 1.1.
    - Added a dependency on EXT_fog_coord.
    - Inserted enumerant value.

June  16, 2004 (v0.7)
    - Modified to make texture crop rectangle part of
      texture state (set by TexParameter) rather than by
      an ad hoc function (TexCropRectOES).
    - Modified to provide stretch-blit functionality.

May   28, 2004 (v0.6)
    - Formalized changes to 1.3 and ES 1.0 specs.
      Modified to take screen coordinate arguments
      rather than using the current raster position.
      
May   19, 2004 (v0.5)
    - Simplified to support only one-to-one source
      blit.  Sprite functionality was moved to a
      separate proposal.

May    4, 2004 (v0.4)
    - Rewrote to use explicit source and destination
      rectangles instead of overloading PixelZoom.
      Made current raster rectangle explicit and 
      provided both screen space and object space
      ways to define it.

April 13, 2004
    - Initial version (v0.3)