Reputation: 5744
I'm trying to implement mouse picking in a small application written in haskell. I want to retrieve the projection matrix that has been set with this code found in the resize
function that gets called when the window resizes itself:
resize w h = do
GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral w) (fromIntegral h))
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.perspective 45 (fromIntegral w / fromIntegral h) 1 100
The best I've achieved so far is to set the current matrix to GL.Projection
and then trying to read the GL.currentMatrix
statevar like this:
GL.matrixMode $= GL.Projection
pm <- GL.get GL.currentMatrix
-- inverse the matrix, somehow, and multiply this with the clip plane position of
-- of the mouse
This doesn't work and produces this error:
Ambiguous type variable `m0' in the constraint:
(GL.Matrix m0) arising from a use of `GL.currentMatrix'
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `GL.get', namely `GL.currentMatrix'
In a stmt of a 'do' expression: pm <- GL.get GL.currentMatrix
I think I should be using some sort of type constraint when trying to get the matrix out of the StateVar
, but changing the GL.get
call to pm <- GL.get (GL.currentMatrix :: GL.GLfloat)
just produces a different and equally puzzling message.
I know this is using the old deprecated OpenGL matrix stack and modern code should be using shaders and such to perform their own matrix handling, but I'm not quite comfortable enough in haskell to attempt to really do anything beyond the most basic of projects. If it's easy enough I would certainly try to convert what little rendering code I have to a more modern style, but I find it difficult to find suitable tutorials to help me along.
Upvotes: 2
Views: 1636
Reputation: 2822
First thing is first: currentMatrix
is deprecated and is removed in the most recent OpenGL package (2.9.2.0). In order to use the most recent version, you can upgrade the dependency in your .cabal file. If you look at the source, GL.currentMatrix
is identical to calling GL.matrix Nothing
.
Second: The error you're receiving is because Haskell doesn't know the type of matrix component (float or double) that you're trying to read from the GL state. You're on the right track about adding a type signature to the function call, but GL.currentMatrix
has type
GL.Matrix m, GL.MatrixComponent c => GL.StateVar (m c)
Hence, you need to fully specify the type if you plan on using it in order to disambiguate it to haskell. If you're set on using the old fixed function pipeline, then the type signature should look something like this:
pm <- GL.get (GL.currentMatrix :: GL.StateVar (GL.GLmatrix GL.GLfloat))
That being said, your mouse picking code may still have problems because there're a couple of other factors that you need to account for:
You need both the modelview and projection matrices to get the proper world-space position of the ray into your scene. The call to GL.currentMatrix
just gets the current matrix for whatever the current matrix mode is.
Inverting a 4x4 matrix isn't part of the OpenGL
package, IIRC and you'll need your own inverting code.
Once you get the proper matrices, the OpenGL.GLU
package has an unproject
function that might do what you need
Upvotes: 1