blob: 7d3c2ececa0cd80bbf5d7f9704eb9c2e7f2e913b [file] [log] [blame]
Name
NV_draw_texture
Name Strings
GL_NV_draw_texture
Contributors
Steven Holte, NVIDIA Corporation (sholte 'at' nvidia.com)
Contact
Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
Status
Complete
Version
Last Modified Date: 9/19/2012
NVIDIA Revision: 2
Number
OpenGL Extension #430
OpenGL ES Extension #126
Dependencies
This extension is written against the OpenGL 4.1 Specification
(Compatibility Profile).
This extension can also be used with OpenGL ES 2.0 or later (see the section,
"Interactions with OpenGL ES," below).
This extension interacts with EXT_shadow_samplers.
Overview
This extension provides a new function, DrawTextureNV(), allowing
applications to draw an screen-aligned rectangle displaying some or all of
the contents of a two-dimensional or rectangle texture. Callers specify a
texture object, an optional sampler object, window coordinates of the
rectangle to draw, and texture coordinates corresponding to the corners of
the rectangle. For each fragment produced by the rectangle, DrawTextureNV
interpolates the texture coordinates, performs a texture lookup, and uses
the texture result as the fragment color.
No shaders are used by DrawTextureNV; the results of the texture lookup
are used in lieu of a fragment shader output. The fragments generated are
processed by all per-fragment operations. In particular,
DrawTextureNV() fully supports blending and multisampling.
While this functionality can be obtained in unextended OpenGL by drawing a
rectangle and using a fragment shader to do a texture lookup,
DrawTextureNV() is likely to have better power efficiency on
implementations supporting this extension. Additionally, use of this
extension frees the application developer from having to set up
specialized shaders, transformation matrices, vertex attributes, and
various other state in order to render the rectangle.
New Procedures and Functions
void DrawTextureNV(GLuint texture, GLuint sampler,
GLfloat x0, GLfloat y0,
GLfloat x1, GLfloat y1,
GLfloat z,
GLfloat s0, GLfloat t0,
GLfloat s1, GLfloat t1);
New Tokens
None.
Additions to Chapter 2 of the OpenGL 4.1 Specification (OpenGL Operation)
Modify Section 2.19, Conditional Rendering, p. 183
(modify first paragraph to specify that DrawTextureNV is affected by
conditional rendering) ... is false, all rendering commands between
BeginConditionalRender and the corresponding EndConditionalRender are
discarded. In this case, Begin, End, ...and DrawTextureNV (section 4.3.X)
have no effect.
Additions to Chapter 3 of the OpenGL 4.1 Specification (Rasterization)
Modify Section 3.1, Discarding Primitives Before Rasterization, p. 204
(modify the end of the second paragraph) When enabled, RASTERIZER_DISCARD
also causes the [[compatibility profile only: Accum, Bitmap, CopyPixels,
DrawPixels,]] Clear, ClearBuffer*, and DrawTextureNV commands to be
ignored.
Additions to Chapter 4 of the OpenGL 4.1 Specification (Per-Fragment
Operations and the Frame Buffer)
(Insert new section after Section 4.3.1, Writing to the Stencil or
Depth/Stencil Buffers, p. 380)
Section 4.3.X, Drawing Textures
The command:
void DrawTextureNV(GLuint texture, GLuint sampler,
GLfloat x0, GLfloat y0,
GLfloat x1, GLfloat y1,
GLfloat z,
GLfloat s0, GLfloat t0,
GLfloat s1, GLfloat t1);
is used to draw a screen-aligned rectangle displaying a portion of the
contents of the texture <texture>. The four corners of this
screen-aligned rectangle have the floating-point window coordinates
(<x0>,<y0>), (<x0>,<y1>), (<x1>,<y1>), and (<x1>,<y0>). A fragment will
be generated for each pixel covered by the rectangle. Coverage along the
edges of the rectangle will be determined according to polygon
rasterization rules. If the framebuffer does not have a multisample
buffer, or if MULTISAMPLE is disabled, fragments will be generated
according to the polygon rasterization algorithm described in section
3.6.1. Otherwise, fragments will be generated for the rectangle using the
multisample polygon rasterization algorithm described in section 3.6.6.
In either case, the set of fragments generated is not affected by other
state affecting polygon rasterization -- in particular, the CULL_FACE,
POLYGON_SMOOTH, and POLYGON_OFFSET_FILL enables and PolygonMode state have
no effect. All fragments generated for the rectangle will have a Z window
coordinate of <z>.
The color associated with each fragment produced will be obtained by using
an interpolated source coordinate (s,t) to perform a lookup into <texture>
The (s,t) source coordinate for each fragment is interpolated over the
rectangle in the manner described in section 3.6.1, where the (s,t)
coordinates associated with the four corners of the rectangle are:
(<s0>, <t0>) for the corner at (<x0>, <y0>),
(<s1>, <t0>) for the corner at (<x1>, <y0>),
(<s1>, <t1>) for the corner at (<x1>, <y1>), and
(<s0>, <t1>) for the corner at (<x0>, <y1>).
The interpolated texture coordinate (s,t) is used to obtain a texture
color (Rs,Gs,Bs,As) from the <texture> using the process described in
section 3.9. The sampler state used for the texture access will be taken
from the texture object <texture> if <sampler> is zero, or from the
sampler object given by <sampler> otherwise. The filtered texel <tau> is
converted to an (Rb,Gb,Bb,Ab) vector according to table 3.25 and swizzled
as described in Section 3.9.16. [[Core Profile Only: The section
referenced here is present only in the compatibility profile; this
language should be changed to reference the relevant language in the core
profile.]]
The fragments produced by the rectangle are not processed by fragment
shaders [[Compatibility Profile: or fixed-function texture, color sum, or
fog operations]]. These fragments are processed by all of the
per-fragment operations in section 4.1. For the purposes of the scissor
test (section 4.1.2), the enable and scissor rectangle for the first
element in the array of scissor test enables and rectangles are used.
The error INVALID_VALUE is generated by DrawTextureNV if <texture> is not
the name of a texture object, or if <sampler> is neither zero nor the name
of a sampler object. The error INVALID_OPERATION is generated if the
target of <texture> is not TEXTURE_2D or TEXTURE_RECTANGLE, <texture> is
not complete, if <sampler> is zero and the TEXTURE_COMPARE_MODE parameter
of <texture> is COMPARE_REF_TO_TEXTURE, or if <sampler> is non-zero and
the TEXTURE_COMPARE_MODE_PARAMETER of <sampler> is COMPARE_REF_TO_TEXTURE.
Additions to Chapter 5 of the OpenGL 4.1 Specification (Special Functions)
None.
Additions to Chapter 6 of the OpenGL 4.1 Specification (State and
State Requests)
None.
Additions to Appendix A of the OpenGL 4.1 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
!!! TBD
Errors
INVALID_VALUE is generated by DrawTextureNV if <texture> is not the name
of a texture object, or if <sampler> is neither zero nor the name of a
sampler object.
INVALID_OPERATION is generated by DrawTextureNV if the target of <texture>
is not TEXTURE_2D or TEXTURE_RECTANGLE, <texture> is not complete, if
<sampler> is zero and the TEXTURE_COMPARE_MODE parameter of <texture> is
COMPARE_REF_TO_TEXTURE, or if <sampler> is non-zero and the
TEXTURE_COMPARE_MODE_PARAMETER of <sampler> is COMPARE_REF_TO_TEXTURE.
New State
None.
New Implementation Dependent State
None.
Interactions with OpenGL ES
If implemented for OpenGL ES, NV_draw_texture acts as described in this spec,
except:
* Ignore the references to conditional rendering including changes to
section 2.19 "Conditional Rendering".
* Ignore all references to RASTERIZER_DISCARD including changes to
section 3.1 "Discarding Primitives Before Rasterization".
* Ignore references to MULTISAMPLE.
* Ignore references to POLYGON_SMOOTH and PolygonMode.
* Ignore references to TEXTURE_RECTANGLE.
* If the version of OpenGL ES is less than 3.0, the sampler parameter
must always be 0.
* If the version of OpenGL ES is less than 3.0, ignore references to
texture swizzles.
Interactions with OpenGL ES and EXT_shadow_samplers
If implemented for OpenGL ES with the EXT_shadow_samplers extension,
replace references to TEXTURE_COMPARE_FUNC, TEXTURE_COMPARE_MODE, and
COMPARE_REF_TO_TEXTURE, with references to TEXTURE_COMPARE_FUNC_EXT,
TEXTURE_COMPARE_FUNC_EXT and COMPARE_REF_TO_TEXTURE_EXT.
If implemented for OpenGL ES without the EXT_shadow_samplers extension,
ignore references to these symbols.
Issues
(1) Why provide this extension when you can do the same thing by drawing a
quad with a simple fragment shader using texture mapping?
RESOLVED: This extension is intended to provide a high-performance
power-efficient fixed-function path for drawing the contents of a
texture onto the screen. No vertex shader is required to position the
vertices of the quad, and no fragment shader is required to perform a
texture lookup.
(2) Why provide this extension when you can do something similar with
DrawPixels?
RESOLVED: DrawPixels provides similar functionality, but can only
access client memory or a pixel buffer object. If the data to be drawn
on-screen come from a texture, it would be necessary to read the
contents of the texture back to client memory or a pixel buffer object
before drawing.
Additionally, the rendering process for DrawPixels has several
limitations. Addressing a subset of the source data requires either
pointer manipulation or the use of the separate PixelStore APIs, and
doesn't permit sub-pixel addressing in the source data. While
DrawPixels supports scaling via the PixelZoom, the zooming capability
provides only point-sampled filtering. Additionally, DrawPixels is not
supported in the core profile of OpenGL, or in OpenGL ES.
(3) Why provide this extension when you can do something similar with
BlitFramebuffer?
RESOLVED: BlitFramebuffer also provides similar functionality, but it
does not permit per-fragment operations like blending, which is a
significant limitation for some important "2D" use cases of this API
(e.g., compositing several images from textures). Additionally, need to
attach the texture to a framebuffer object, set up a read buffer, and
bind the framebuffer object as the read framebuffer result in several
additional steps not present in the DrawTextureNV API.
(4) The DrawTextureNV API only supports 2D or rectangle textures. Should
we provide support for accessing other types of texture (1D, 3D, cube
maps, arrays)? Or even for pulling a "2D" image out of a more complex
texture (like identifying a texture face, or a layer of a 2D array
texture or a 3D texture)?
RESOLVED: No, we are choosing to keep the API simple and support only
2D/rectangle textures. Adding in support for 3D or array textures would
require additional texture coordinates that would clutter up the "2D"
API or a separate "DrawTexture3DNV" API taking (s,t,r) coordinates.
Adding in support for pulling out a face/layer of a texture with
multiple layers would inject similar clutter or new APIs.
Note that the face/layer selection could also be handled by a
Direct3D-like "resource view" API that would allow callers to create
multiple "views" of a source texture. In particular, one might be able
to use such an extension to create a "virtual" 2D texture object that
refers to a single face/layer of a cube map, 2D array, or 3D texture.
(5) Should we support multisample textures (TEXTURE_2D_MULTISAMPLE)?
RESOLVED: No. Current texture mapping support for multisample texture
only allows for selection of a single numbered texture. There are no
filtered texture lookup capabilities for these sorts of textures.
BlitFramebuffer does support sourcing a multisample texture (via a
framebuffer object attachement), but its capabilities are also fairly
limited -- copies are only supported either by first resolving multiple
samples down to a single sample, or doing a straight sample-by-sample
copy to a matching multisample buffer.
(6) What sort of coordinates should be used to access the texture?
RESOLVED: We use the same coordinate system as is used for normal
texture lookups for a given texture target.
For textures with a TEXTURE_RECTANGLE target, we use non-normalized
coordinates -- to draw a 640x480 rectangle texture on top of a 640x480
window, you would call:
glDrawTexture(texture, sampler,
0, 0, 640, 480, /* destination */
0, 0, 640, 480 /* texture */);
For textures with a TEXTURE_2D target, we use normalized coordinates.
The same example as above with a 640x480 2D texture would use:
glDrawTexture(texture, sampler,
0, 0, 640, 480, /* destination */
0, 0, 1, 1 /* texture */);
(7) What limitations apply to the texture accesses in DrawTextureNV?
RESOLVED: We do not support any texture targets other than TEXTURE_2D
and TEXTURE_RECTANGLE. We also do not support shadow mapping via the
TEXTURE_COMPARE_MODE parameter, given that we don't provide any
interface for specifying a depth reference value. In either case, an
INVALID_OPERATION error will be generated if an unsupported feature is
used.
(8) Is anisotropic texture filtering supported?
RESOLVED: Yes. However, anisotropic filtering may result in lower
performance and power efficiency and should be used only if
required. Given that the destination is a screen-aligned rectangle and
the portion of texture sampled from is a texture-aligned rectangle, the
footprints of pixels in texture space are regular. Unless the
DrawTextureNV command uses a non-uniform scale, anisotropic filtering
should provide no benefit.
(9) Are texture swizzles supported?
RESOLVED: Yes.
(10) Does DrawTextureNV support multisample rasterization?
RESOLVED: Yes. The coordinates of the destination rectangle are
floating-point values, allowing for rectangle boundaries not on pixel
edges. When multisample rasterization is enabled, pixels on the edge of
the rectangle may be partially covered, in which case only some samples
of the pixel will be updated. This multisample support allows for
smoother panning of the drawn rectangles than one could get with the
pixel-aligned updates provided by the BlitFramebuffer API.
(11) Does DrawTextureNV support per-sample shading (i.e., a different
color for each sample in the destination rectangle)?
RESOLVED: No.
(12) Should any per-fragment operations be supported by this extension?
RESOLVED: Yes, we will all support fragment operations. In particular,
blending is particularly important for "2D" operations such as
compositing image layers. It seems interesting to allow stencil
operations to "cut out" portions of the primitive. It also seems
interesting to allow depth testing be used to compare the DrawTextureNV
rectangle (at a fixed depth) against previously rendered primitives
(either "3D" or "2D").
(13) Should we provide a mode to override/disable selected per-fragment
operations when performing DrawTextureNV?
RESOLVED: No. An override would be useful if we expected applications
to be performing operations like toggling between regularly rendered
primitives (with depth testing enabled) and "flat" DrawTexture2D output
(not wanting depth testing) at a fine granularity. It's not clear that
such usage would be common. If we expect switching between modes only
at a coarse granularity, it would be simpler to require the application
to apply the (infrequent) overrides themselves instead of adding clutter
to the DrawTextureNV API.
(14) Is it legal to call DrawTextureNV while transform feedback is active?
If so, what is recorded?
UNRESOLVED: Yes, it's legal to call DrawTextureNV during transform
feedback. Nothing should be recorded in this case. This is consistent
with the handling of other "special" rendering operations (like
DrawPixels and BlitFramebuffer). This behavior falls out of the
definition of transform feedback with no spec changes required; there
are no geometric primitives sent through the pipeline for DrawTextureNV
that could be recorded.
(15) How does DrawTextureNV interact with RASTERIZER_DISCARD?
UNRESOLVED: If RASTERIZER_DISCARD is enabled, DrawTextureNV will be
discarded. This is consistent with the behavior of DrawPixels.
Note: It appears that BlitFramebuffer is not affected by
RASTERIZER_DISCARD, though the extensions that introduced this command
don't explicitly address this one way or the other.
(16) Should samples generated by DrawTextureNV be counted in occlusion
queries?
UNRESOLVED: Yes. Occlusion query is just another per-fragment
operation, and we support all the other ones.
(17) How does this extension interact with the DEPTH_CLAMP enable?
UNRESOLVED: When enabled, depth clamping will be performed on
DrawTextureNV fragments. This appears to be consistent with the spec
language, as applied to DrawPixels. There are two parts to depth
clamping: (a) clipping to the near/far frustum clip planes are
disabled, and (b) clamping is applied to fragment Z as part of the depth
test. There's no language suggesting that (b) doesn't apply to color
DrawPixels or Bitmap commands. (DrawPixels with DEPTH_COMPONENT pixels
is a different beast that doesn't go through the regular pixel path, and
ARB_depth_clamp says that clamping doesn't apply there.)
Note that if depth testing is disabled, the depth clamp enable has no
effect on DrawTextureNV, since (a) doesn't apply because DrawTextureNV
doesn't generate a geometric primitive that could be clipped.
(18) How does the rectangle rendered by DrawTextureNV interact with
polygon rasterization features (culling, polygon smooth, polygon
mode, polygon offset)?
RESOLVED: None of these features affect DrawTextureNV. The spec refers
to the polygon rasterization of the spec only because we apply the same
coverage computation rules to DrawTextureNV as are used for
rasterization of single-sample and multisample polygons.
(19) How does this extension interact with conditional rendering?
UNRESOLVED: If DrawTextureNV is called inside a BeginConditionalRender
and EndConditionalRender pair and the query object indicates that
rendering should be discarded, the DrawTextureNV command is also
discarded. This is consistent with the behavior of DrawPixels.
Revision History
Rev. Date Author Changes
---- -------- -------- -----------------------------------------
1 pbrown Internal revisions.
2 09/19/12 sholte Added ES interactions