你能给我一个关于如何在Haskell中使用texImage2D(来自OpenGL)和readImage(来自JuicyPixels库)加载纹理的例子吗?
我知道已经存在类似的问题here但是因为我是新手,我无法让这个例子有效。我需要完整的代码,也许还需要解释它是如何工作的......
答案 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)