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 . The four corners of this screen-aligned rectangle have the floating-point window coordinates (,), (,), (,), and (,). 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 . The color associated with each fragment produced will be obtained by using an interpolated source coordinate (s,t) to perform a lookup into 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: (, ) for the corner at (, ), (, ) for the corner at (, ), (, ) for the corner at (, ), and (, ) for the corner at (, ). The interpolated texture coordinate (s,t) is used to obtain a texture color (Rs,Gs,Bs,As) from the using the process described in section 3.9. The sampler state used for the texture access will be taken from the texture object if is zero, or from the sampler object given by otherwise. The filtered texel 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 is not the name of a texture object, or if is neither zero nor the name of a sampler object. The error INVALID_OPERATION is generated if the target of is not TEXTURE_2D or TEXTURE_RECTANGLE, is not complete, if is zero and the TEXTURE_COMPARE_MODE parameter of is COMPARE_REF_TO_TEXTURE, or if is non-zero and the TEXTURE_COMPARE_MODE_PARAMETER of 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 is not the name of a texture object, or if is neither zero nor the name of a sampler object. INVALID_OPERATION is generated by DrawTextureNV if the target of is not TEXTURE_2D or TEXTURE_RECTANGLE, is not complete, if is zero and the TEXTURE_COMPARE_MODE parameter of is COMPARE_REF_TO_TEXTURE, or if is non-zero and the TEXTURE_COMPARE_MODE_PARAMETER of 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