1

您能否提供一个示例,说明如何在 Haskell 中使用 texImage2D(来自 OpenGL)和 readImage(来自 JuicyPixels 库)加载纹理?

我知道这里已经有一个类似的问题但是由于我是新手,我无法使该示例有效。我需要完整的代码,也许还需要一些关于它是如何工作的解释......

4

1 回答 1

0

Sorry, I don't know how to operate with JuicyPixels, but I've done texture loading in OpenGL.

It is a bit more complex. It does loading textures from several files, assuming they are texture atlasses (contain several images on a texture).

You can examine what parts of this program specific to texture rendering (by cutting unnecessary parts) and figure out how to convert JuicePixels image to raw array of pixel colors (look into bindBMPTexture function in utils module)

Good luck!

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)
于 2014-07-01T20:10:04.710 回答