-------------------------------------------------------------------------------- -- | -- Module : Graphics.Rendering.OGL.GL.BeginEnd -- Copyright : (c) Sven Panne 2002-2006 -- License : BSD-style (see the file libraries/OpenGL/LICENSE) -- -- Maintainer : sven.panne@aedion.de -- Stability : stable -- Portability : portable -- -- This module corresponds to section 2.6 (Begin\/End Paradigm) of the -- OpenGL 2.1 specs. -- -------------------------------------------------------------------------------- module Graphics.Rendering.OGL.GL.BeginEnd ( -- * Begin and End Objects PrimitiveMode(..), renderPrimitive, unsafeRenderPrimitive, primitiveRestart, -- * Polygon Edges EdgeFlag(..), edgeFlag ) where import Graphics.Rendering.OGL.Monad import Graphics.Rendering.OGL.GL.BasicTypes ( GLenum, GLboolean ) import Graphics.Rendering.OGL.GL.EdgeFlag ( EdgeFlag(..), marshalEdgeFlag, unmarshalEdgeFlag ) import Graphics.Rendering.OGL.GL.Exception ( bracket_, unsafeBracket_ ) import Graphics.Rendering.OGL.GL.Extensions ( FunPtr, unsafePerformIO, Invoker, getProcAddress ) import Graphics.Rendering.OGL.GL.PrimitiveMode ( PrimitiveMode(..), marshalPrimitiveMode ) import Graphics.Rendering.OGL.GL.QueryUtils ( getBoolean1, GetPName(GetEdgeFlag) ) import Graphics.Rendering.OGL.GL.StateVar ( StateVar, makeStateVar ) -------------------------------------------------------------------------------- #include "HsOpenGLExt.h" -------------------------------------------------------------------------------- -- | Delimit the vertices that define a primitive or a group of like primitives. -- -- Only a subset of GL commands can be used in the delimited action: -- Those for specifying vertex coordinates -- ('Graphics.Rendering.OGL.GL.VertexSpec.vertex', -- 'Graphics.Rendering.OGL.GL.VertexSpec.vertexv'), -- vertex colors -- ('Graphics.Rendering.OGL.GL.VertexSpec.color', -- 'Graphics.Rendering.OGL.GL.VertexSpec.colorv', -- 'Graphics.Rendering.OGL.GL.VertexSpec.secondaryColor', -- 'Graphics.Rendering.OGL.GL.VertexSpec.secondaryColorv', -- 'Graphics.Rendering.OGL.GL.VertexSpec.index', -- 'Graphics.Rendering.OGL.GL.VertexSpec.indexv'), -- normal -- ('Graphics.Rendering.OGL.GL.VertexSpec.normal', -- 'Graphics.Rendering.OGL.GL.VertexSpec.normalv'), -- texture coordinates -- ('Graphics.Rendering.OGL.GL.VertexSpec.texCoord', -- 'Graphics.Rendering.OGL.GL.VertexSpec.texCoordv', -- 'Graphics.Rendering.OGL.GL.VertexSpec.multiTexCoord', -- 'Graphics.Rendering.OGL.GL.VertexSpec.multiTexCoordv'), -- and fog coordinates -- ('Graphics.Rendering.OGL.GL.VertexSpec.fogCoord', -- 'Graphics.Rendering.OGL.GL.VertexSpec.fogCoordv'). -- Additionally, -- 'Graphics.Rendering.OGL.GL.Evaluators.evalPoint1', -- 'Graphics.Rendering.OGL.GL.Evaluators.evalPoint2', -- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord1', -- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord1v', -- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord2', -- 'Graphics.Rendering.OGL.GL.Evaluators.evalCoord2v', -- 'Graphics.Rendering.OGL.GL.Colors.materialAmbient', -- 'Graphics.Rendering.OGL.GL.Colors.materialDiffuse', -- 'Graphics.Rendering.OGL.GL.Colors.materialAmbientAndDiffuse', -- 'Graphics.Rendering.OGL.GL.Colors.materialSpecular', -- 'Graphics.Rendering.OGL.GL.Colors.materialEmission', -- 'Graphics.Rendering.OGL.GL.Colors.materialShininess', -- 'Graphics.Rendering.OGL.GL.DisplayLists.callList', -- 'Graphics.Rendering.OGL.GL.DisplayLists.callLists', -- and setting 'edgeFlag' are allowed. Writing the respective state variables -- is allowed in the delimited action, too. -- -- Regardless of the chosen 'PrimitiveMode', there is no limit to the number of -- vertices that can be defined during a single 'renderPrimitive'. Lines, -- triangles, quadrilaterals, and polygons that are incompletely specified are -- not drawn. Incomplete specification results when either too few vertices are -- provided to specify even a single primitive or when an incorrect multiple of -- vertices is specified. The incomplete primitive is ignored; the rest are -- drawn. -- -- The minimum specification of vertices for each primitive is as follows: 1 -- for a point, 2 for a line, 3 for a triangle, 4 for a quadrilateral, and 3 for -- a polygon. Modes that require a certain multiple of vertices are 'Lines' (2), -- 'Triangles' (3), 'Quads' (4), and 'QuadStrip' (2). renderPrimitive :: PrimitiveMode -> PrimitiveGL a -> GL a renderPrimitive x y = liftIO $ renderPrim bracket_ x (runPrimitive y) -- | A more efficient, but potentially dangerous version of 'renderPrimitive': -- The given action is not allowed to throw an exception. unsafeRenderPrimitive :: PrimitiveMode -> PrimitiveGL a -> GL a unsafeRenderPrimitive x y = liftIO $ renderPrim unsafeBracket_ x (runPrimitive y) {-# INLINE renderPrim #-} renderPrim :: (IO () -> IO () -> IO a -> IO a) -> PrimitiveMode -> IO a -> IO a renderPrim brack_ beginMode = brack_ (glBegin (marshalPrimitiveMode beginMode)) glEnd foreign import CALLCONV unsafe "glBegin" glBegin :: GLenum -> IO () foreign import CALLCONV unsafe "glEnd" glEnd :: IO () -------------------------------------------------------------------------------- primitiveRestart :: GL () primitiveRestart = liftIO $ glPrimitiveRestartNV EXTENSION_ENTRY("GL_NV_primitive_restart",glPrimitiveRestartNV,IO ()) -------------------------------------------------------------------------------- -- | Each vertex of a polygon, separate triangle, or separate quadrilateral -- specified during 'renderPrimitive' is marked as the start of either a boundary -- or nonboundary (interior) edge. -- -- The vertices of connected triangles and connected quadrilaterals are always -- marked as boundary, regardless of the value of the edge flag. -- -- Boundary and nonboundary edge flags on vertices are significant only if -- 'Graphics.Rendering.OGL.GL.Polygons.polygonMode' is set to -- 'Graphics.Rendering.OGL.GL.Polygons.Point' or -- 'Graphics.Rendering.OGL.GL.Polygons.Line'. -- -- Note that the current edge flag can be updated at any time, in particular -- during 'renderPrimitive'. edgeFlag :: StateVar EdgeFlag edgeFlag = makeStateVar (getBoolean1 unmarshalEdgeFlag GetEdgeFlag) (glEdgeFlag . marshalEdgeFlag) foreign import CALLCONV unsafe "glEdgeFlag" glEdgeFlag :: GLboolean -> IO ()