-------------------------------------------------------------------------------- -- | -- Module : Graphics.Rendering.OpenGL.GL.LineSegments -- Copyright : (c) Sven Panne 2002-2019 -- License : BSD3 -- -- Maintainer : Sven Panne <svenpanne@gmail.com> -- Stability : stable -- Portability : portable -- -- This module corresponds to section 3.4 (Line Segments) of the OpenGL 2.1 -- specs. -- -------------------------------------------------------------------------------- module Graphics.Rendering.OpenGL.GL.LineSegments ( -- * Line Rasterization lineWidth, -- * Line Stipple lineStipple, -- * Line Antialiasing lineSmooth, -- * Implementation-Dependent Limits aliasedLineWidthRange, smoothLineWidthRange, smoothLineWidthGranularity ) where import Control.Monad import Data.StateVar import Graphics.Rendering.OpenGL.GL.Capability import Graphics.Rendering.OpenGL.GL.QueryUtils import Graphics.GL -------------------------------------------------------------------------------- -- | 'lineWidth' contains the rasterized width of both aliased and antialiased -- lines. The initial value is 1. Using a line width other than 1 has different -- effects, depending on whether line antialiasing is enabled (see -- 'lineSmooth'). Line antialiasing is initially disabled. -- -- If line antialiasing is disabled, the actual width is determined by rounding -- the supplied width to the nearest integer. (If the rounding results in the -- value 0, it is as if the line width were 1.) If /delta x/ >= /delta y/, /i/ -- pixels are filled in each column that is rasterized, where /i/ is the -- rounded value of 'lineWidth'. Otherwise, /i/ pixels are filled in each row -- that is rasterized. -- -- If antialiasing is enabled, line rasterization produces a fragment for each -- pixel square that intersects the region lying within the rectangle having -- width equal to the current line width, length equal to the actual length of -- the line, and centered on the mathematical line segment. The coverage value -- for each fragment is the window coordinate area of the intersection of the -- rectangular region with the corresponding pixel square. This value is saved -- and used in the final rasterization step. -- -- Not all widths can be supported when line antialiasing is enabled. If an -- unsupported width is requested, the nearest supported width is used. Only -- width 1 is guaranteed to be supported; others depend on the implementation. -- Likewise, there is a range for aliased line widths as well. To query the -- range of supported widths of antialiased lines and the size difference -- between supported widths within the range, query 'smoothLineWidthRange' and -- 'smoothLineWidthGranularity', respectively. For aliased lines, query the -- supported range with 'aliasedLineWidthRange'. -- -- The line width specified when 'lineWidth' is set is always returned when it -- is queried. Clamping and rounding for aliased and antialiased lines have no -- effect on the specified value. -- -- A non-antialiased line width may be clamped to an implementation-dependent -- maximum. Query 'aliasedLineWidthRange' to determine the maximum width. -- -- An 'Graphics.Rendering.OpenGL.GLU.Errors.InvalidValue' is generated if -- 'lineWidth' is set to a value less than or equal to zero. -- -- An 'Graphics.Rendering.OpenGL.GLU.Errors.InvalidOperation' is generated if -- 'lineWidth' is set during -- 'Graphics.Rendering.OpenGL.GL.BeginEnd.renderPrimitive'. lineWidth :: StateVar GLfloat lineWidth :: StateVar GLfloat lineWidth = IO GLfloat -> (GLfloat -> IO ()) -> StateVar GLfloat forall a. IO a -> (a -> IO ()) -> StateVar a makeStateVar ((GLfloat -> GLfloat) -> PName1F -> IO GLfloat forall p a. GetPName1F p => (GLfloat -> a) -> p -> IO a forall a. (GLfloat -> a) -> PName1F -> IO a getFloat1 GLfloat -> GLfloat forall a. a -> a id PName1F GetLineWidth) GLfloat -> IO () forall (m :: * -> *). MonadIO m => GLfloat -> m () glLineWidth -------------------------------------------------------------------------------- -- | Line stippling masks out certain fragments produced by rasterization; those -- fragments will not be drawn. The masking is achieved by using three -- parameters: the repeat count (1st element of the 'lineStipple' pair, clamped -- to the range [ 1 .. 256 ]), the 16-bit line stipple pattern (2nd element), -- and an integer stipple counter /s/. -- -- The counter /s/ is reset to 0 at before the first action during -- 'Graphics.Rendering.OpenGL.GL.BeginEnd.renderPrimitive' is called and before -- each line segment during -- 'Graphics.Rendering.OpenGL.GL.BeginEnd.renderPrimitive' is generated. It is -- incremented after each fragment of a unit width aliased line segment is -- generated or after each /i/ fragments of an /i/ width line segment are -- generated. The /i/ fragments associated with count /s/ are masked out if -- @'Data.Bits.testBit' /pattern/ (( /s/ \/ /factor/ ) /mod/ 16)@ is 'False', -- otherwise these fragments are sent to the frame buffer. Bit zero of the -- pattern is the least significant bit, i.e. it is used first. -- -- Antialiased lines are treated as a sequence of rectangles of height 1 for -- purposes of stippling. Whether rectangle /s/ is rasterized or not depends on -- the fragment rule described for aliased lines, counting rectangles rather -- than groups of fragments. -- -- The initial value of 'lineStipple' is 'Nothing', i.e. line stippling is -- disabled. -- -- An 'Graphics.Rendering.OpenGL.GLU.Errors.InvalidOperation' is generated if -- 'lineStipple' is set during -- 'Graphics.Rendering.OpenGL.GL.BeginEnd.renderPrimitive'. lineStipple :: StateVar (Maybe (GLint, GLushort)) lineStipple :: StateVar (Maybe (GLint, GLushort)) lineStipple = IO EnableCap -> IO (GLint, GLushort) -> ((GLint, GLushort) -> IO ()) -> StateVar (Maybe (GLint, GLushort)) forall a. IO EnableCap -> IO a -> (a -> IO ()) -> StateVar (Maybe a) makeStateVarMaybe (EnableCap -> IO EnableCap forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return EnableCap CapLineStipple) ((GLint -> GLushort -> (GLint, GLushort)) -> IO GLint -> IO GLushort -> IO (GLint, GLushort) forall (m :: * -> *) a1 a2 r. Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r liftM2 (,) ((GLint -> GLint) -> PName1I -> IO GLint forall p a. GetPName1I p => (GLint -> a) -> p -> IO a forall a. (GLint -> a) -> PName1I -> IO a getInteger1 GLint -> GLint forall a. a -> a id PName1I GetLineStippleRepeat) ((GLint -> GLushort) -> PName1I -> IO GLushort forall p a. GetPName1I p => (GLint -> a) -> p -> IO a forall a. (GLint -> a) -> PName1I -> IO a getInteger1 GLint -> GLushort forall a b. (Integral a, Num b) => a -> b fromIntegral PName1I GetLineStipplePattern)) ((GLint -> GLushort -> IO ()) -> (GLint, GLushort) -> IO () forall a b c. (a -> b -> c) -> (a, b) -> c uncurry GLint -> GLushort -> IO () forall (m :: * -> *). MonadIO m => GLint -> GLushort -> m () glLineStipple) -------------------------------------------------------------------------------- -- | Controls whether line antialiasing is enabled. The initial state is -- 'Graphics.Rendering.OpenGL.GL.Capability.Disabled'. lineSmooth :: StateVar Capability lineSmooth :: StateVar Capability lineSmooth = EnableCap -> StateVar Capability makeCapability EnableCap CapLineSmooth -------------------------------------------------------------------------------- -- | The smallest and largest supported width of aliased lines. aliasedLineWidthRange :: GettableStateVar (GLfloat, GLfloat) aliasedLineWidthRange :: GettableStateVar (GLfloat, GLfloat) aliasedLineWidthRange = GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat) forall a. IO a -> IO a makeGettableStateVar (GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat)) -> GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat) forall a b. (a -> b) -> a -> b $ (GLfloat -> GLfloat -> (GLfloat, GLfloat)) -> PName2F -> GettableStateVar (GLfloat, GLfloat) forall p a. GetPName2F p => (GLfloat -> GLfloat -> a) -> p -> IO a forall a. (GLfloat -> GLfloat -> a) -> PName2F -> IO a getFloat2 (,) PName2F GetAliasedLineWidthRange -- | The smallest and largest supported width of antialiased lines. smoothLineWidthRange :: GettableStateVar (GLfloat, GLfloat) smoothLineWidthRange :: GettableStateVar (GLfloat, GLfloat) smoothLineWidthRange = GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat) forall a. IO a -> IO a makeGettableStateVar (GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat)) -> GettableStateVar (GLfloat, GLfloat) -> GettableStateVar (GLfloat, GLfloat) forall a b. (a -> b) -> a -> b $ (GLfloat -> GLfloat -> (GLfloat, GLfloat)) -> PName2F -> GettableStateVar (GLfloat, GLfloat) forall p a. GetPName2F p => (GLfloat -> GLfloat -> a) -> p -> IO a forall a. (GLfloat -> GLfloat -> a) -> PName2F -> IO a getFloat2 (,) PName2F GetSmoothLineWidthRange -- | The antialiased line width granularity, i.e. the size difference between -- supported widths. smoothLineWidthGranularity :: GettableStateVar GLfloat smoothLineWidthGranularity :: IO GLfloat smoothLineWidthGranularity = IO GLfloat -> IO GLfloat forall a. IO a -> IO a makeGettableStateVar (IO GLfloat -> IO GLfloat) -> IO GLfloat -> IO GLfloat forall a b. (a -> b) -> a -> b $ (GLfloat -> GLfloat) -> PName1F -> IO GLfloat forall p a. GetPName1F p => (GLfloat -> a) -> p -> IO a forall a. (GLfloat -> a) -> PName1F -> IO a getFloat1 GLfloat -> GLfloat forall a. a -> a id PName1F GetSmoothLineWidthGranularity