Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JuicyPixels texture loading in Haskell OpenGL?

Tags:

haskell

opengl

How do I load a texture using Haskell, OpenGL and the JuicyPixels library?

I can get as far as this:

loadImage :: IO ()
loadImage = do image <- readPng "data/Picture.png"
               case image of 
                 (Left s) -> do print s
                                exitWith (ExitFailure 1)
                 (Right d) -> do case (ImageRGBA i) -> do etc...

How do I convert this to a TextureObject? I think I need to do a conversion between a Vector Word8 and PixelData (for OpenGL to recognize)

like image 858
Mark Avatar asked May 06 '12 07:05

Mark


1 Answers

You use the texImage2D function. You'd invoke it like this:

import Data.Vector.Storable (unsafeWith)

import Graphics.Rendering.OpenGL.GL.Texturing.Specification (texImage2D, Level, Border, TextureSize2D(..))
import Graphics.Rendering.OpenGL.GL.PixelRectangles.ColorTable (Proxy(..), PixelInternalFormat(..))
import Graphics.Rendering.OpenGL.GL.PixelRectangles.Rasterization (PixelData(..))

-- ...

(ImageRGBA8 (Image width height dat)) ->
  -- Access the data vector pointer
  unsafeWith dat $ \ptr ->
    -- Generate the texture
    texImage2D
      -- No cube map
      Nothing
      -- No proxy
      NoProxy
      -- No mipmaps
      0
      -- Internal storage format: use R8G8B8A8 as internal storage
      RGBA8
      -- Size of the image
      (TextureSize2D width height)
      -- No borders
      0
      -- The pixel data: the vector contains Bytes, in RGBA order
      (PixelData RGBA UnsignedByte ptr)

Note that Juicy doesn't always give back an RGBA image. You have to handle each of the different image variations:

ImageY8, ImageYA8, ImageRGB8, ImageRGBA8, ImageYCrCb8

Also, before this command, you have to have bound a texture object to store the texture data in.

import Data.ObjectName (genObjectNames)
import Graphics.Rendering.OpenGL.GL.Texturing.Objects (textureBinding)
import Graphics.Rendering.OpenGL.GL.Texturing.Specification (TextureTarget(..))

-- ...

-- Generate 1 texture object
[texObject] <- genObjectNames 1

-- Make it the "currently bound 2D texture"
textureBinding Texture2D $= Just texObject

BTW, many of those imports are added automatically when you import Graphics.Rendering.OpenGL; you don't have to import each thing individually if you don't want.

like image 179
dflemstr Avatar answered Oct 14 '22 21:10

dflemstr