Can you provide me with an example on how to load a texture with texImage2D (from OpenGL) and readImage (from the JuicyPixels library) in Haskell?
I know there is already a similar question here but cause I'm a newbie, I'm not been able to make that example works. I need the complete code and maybe also some explanation on how it works...
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)