如何在Haskell中使用JuicyPixels库加载OpenGL纹理

时间:2014-07-01 13:00:17

标签: opengl haskell texture2d juicy-pixels

你能给我一个关于如何在Haskell中使用texImage2D(来自OpenGL)和readImage(来自JuicyPixels库)加载纹理的例子吗?

我知道已经存在类似的问题here但是因为我是新手,我无法让这个例子有效。我需要完整的代码,也许还需要解释它是如何工作的......

1 个答案:

答案 0 :(得分:0)

抱歉,我不知道如何使用JuicyPixels,但我已经在OpenGL中完成了纹理加载。

有点复杂。它确实从几个文件加载纹理,假设它们是纹理atlasses(在纹理上包含几个图像)。

您可以检查此程序的哪些部分特定于纹理渲染(通过剪切不必要的部分),并弄清楚如何将JuicePixels图像转换为原始像素颜色数组(查看utils模块中的bindBMPTexture函数)

祝你好运!

import            Data.ByteString         ( ByteString(..) )
import qualified  Data.ByteString  as BS
import qualified  Data.ByteString.Unsafe as BSU
import            Graphics.UI.GLUT
import            Graphics.Rendering.OpenGL (($=))
import qualified  Graphics.Rendering.OpenGL as GL
import qualified  Codec.BMP as BMP 
import            Foreign.ForeignPtr
import            Foreign.Ptr
import            Control.Monad
import            Unsafe.Coerce
import qualified  Graphics.UI.GLFW as GLFW
import            Data.IORef
import            Data.List
import qualified  Data.Map as Map
import            Data.Maybe
import OpenGLUtils

data TextureInfo = TextureInfo GL.TextureObject (Int, Int)
data ImageTexture = ImageTexture String (Int, Int) (Int, Int)
images = [ ImageTexture "data/bricks.bmp" (0, 0) (64, 16)
         , ImageTexture "data/bricks.bmp" (0, 16) (64, 16)
         , ImageTexture "data/bricks.bmp" (0, 32) (64, 16)
         , ImageTexture "data/bricks.bmp" (0, 48) (64, 16)
         ]

main = do
  GLFW.initialize
  GLFW.openWindow (GL.Size (gsizei oSCREEN_WIDTH) (gsizei oSCREEN_HEIGHT)) [GLFW.DisplayAlphaBits 8] GLFW.Window
  GLFW.windowTitle $= "Texture demo"
  GL.shadeModel    $= GL.Smooth
  GL.lineSmooth    $= GL.Enabled
  GL.blend      $= GL.Enabled
  GL.blendFunc  $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
  GL.lineWidth  $= 1.5
  GL.clearColor $= Color4 0 0 0 0

  GLFW.windowSizeCallback $= \ size@(GL.Size w h) -> do
      GL.viewport   $= (GL.Position 0 0, size)
      GL.matrixMode $= GL.Projection
      GL.loadIdentity

  texturesMap <- loadTextures
  glfwStaticRender $ do
     drawTexture_ texturesMap $ images !! 0

  GLFW.closeWindow
  GLFW.terminate

loadTextures :: IO (Map.Map String TextureInfo)
loadTextures = do
    let paths = nub $ map (\(ImageTexture path _ _) -> path) images
    texs <- GL.genObjectNames (length paths)
    let zippedMap = zip paths texs
    sizes <- forM zippedMap $ \(path, tex) ->
        bindBMPTexture tex path
    return $ Map.fromList (zipWith (\(path,tex) size -> (path, TextureInfo tex size)) zippedMap sizes)

drawTexture_ textureMap (ImageTexture path (posX, posY) (sizeX, sizeY)) = do
    let (TextureInfo tex (tSizeX, tSizeY)) = fromJust $ Map.lookup path textureMap
    drawTexture tex (tSizeX, tSizeY) (posX, posY) (sizeX, sizeY)