Как загрузить текстуру OpenGL с библиотекой JuicyPixels в Haskell

Можете ли вы дать мне пример того, как загрузить текстуру с помощью texImage2D (из OpenGL) и readImage (из библиотеки JuicyPixels) в Haskell?

Я знаю, что здесь уже есть подобный вопрос, но, поскольку я новичок, я не смог заставить этот пример работать. Мне нужен полный код и, возможно, также некоторые пояснения о том, как он работает...

1 ответ

Решение

Извините, я не знаю, как работать с JuicyPixels, но я загрузил текстуру в OpenGL.

Это немного сложнее. Он загружает текстуры из нескольких файлов, предполагая, что они являются текстурными классами (содержат несколько изображений на текстуре).

Вы можете проверить, какие части этой программы относятся к рендерингу текстур (обрезая ненужные части) и выяснить, как преобразовать изображение JuicePixels в необработанный массив цветов пикселей (см. 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)
Другие вопросы по тегам