【问题标题】:How to change textures in OpenGL using Haskell如何使用 Haskell 在 OpenGL 中更改纹理
【发布时间】:2011-04-21 21:34:09
【问题描述】:

我一直在尝试使用 Haskell 让多个纹理在 OpenGL 中工作。我一直在网上关注 NeHe tuts 和其他各种 OpenGL 资源,但是稍微不同的调用和我的新手相结合造成了障碍。

具体来说,我想渲染两个立方体,每个立方体都有不同的纹理(目前所有 6 个面的纹理相同)。渲染一个带有纹理的立方体就可以了。渲染多个具有相同纹理的立方体也可以正常工作。但我一直无法弄清楚如何更改两个立方体的纹理

如果我没记错的话,更改纹理的调用是:

textureBinding $ Texture2D $= Just *mytexture*

其中 mytexture 应该是某种形式的 textureID(一个 TextureObject)。 mytexture 点到底是什么? 这应该很容易,但我花了 2 天的大部分时间试图弄清楚这一点,但无济于事。任何帮助表示赞赏。

主要:

    -- imports --
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
import Data.IORef
import Display
import Bindings
import Control.Monad
import Textures

-- main --
main = do
    (program, _) <- getArgsAndInitialize         -- convenience, return program name and non-GLUT commands
    initialDisplayMode $= [DoubleBuffered, WithDepthBuffer] -- inital display mode
    initialWindowSize $= Size 600 600
    createWindow "OpenGL Basics"
    reshapeCallback $= Just reshape
    angle <- newIORef (0.1::GLfloat) -- linked to angle of rotation (speed?)
    delta <- newIORef (0.1::GLfloat)
    position <- newIORef (0.0::GLfloat, 0.0) -- position, pass to display
    texture Texture2D $= Enabled
    tex <- getAndCreateTextures ["goldblock","pumpkintop"]
    keyboardMouseCallback $= Just (keyboardMouse delta position) --require keys, delta, and position
    idleCallback $= Just (idle angle delta) --ref idle angle and delta
    displayCallback $= (display angle position tex) --ref display angle and delta
    cullFace $= Just Front 
    mainLoop    -- runs forever until a hard exit is called

Main中我调用getAndCreateTextures(从网上借来的),它返回一个纹理对象列表。

显示(用于渲染):

    -- display (main) --
display angle position tex = do
    clear [ColorBuffer, DepthBuffer]
    loadIdentity --modelview
    shadeModel $= Smooth
    (x,z) <- get position --get current position from init or keys
    translate $ Vector3 x 0 z -- move to the position before drawing stuff
--    DO STUFF HERE
--    texture $ Texture2D $= Just wtfgoeshere
    preservingMatrix $ do
        a <- get angle
        rotate a $ Vector3 (1::GLfloat) 0 0
--        rotate a $ Vector3 0 0 (1::GLfloat)
        rotate a $ Vector3 0 (1::GLfloat) 0
--        scale 0.7 0.7 (0.7::GLfloat)
--        color $ Color3 (0.5::GLfloat) (0.1::GLfloat) (0.1::GLfloat)
        cubeTexture (0.1::GLfloat)
    swapBuffers

--idle (main)
idle angle delta = do
    a <- get angle      -- get existing angle
    d <- get delta      -- get delta
    angle $= a + d      -- new angle is old angle plus plus delta
    postRedisplay Nothing

【问题讨论】:

    标签: opengl haskell


    【解决方案1】:

    getAndCreateTextures 几乎可以肯定在做你需要的事情。我在网上找到的那个名字的函数类型为IO [Maybe TextureObject],这些是你需要的TextureObject 值。所以你可以这样做,

    [gtex, ptex] <- getAndCreateTextures ["goldblock","pumpkintop"]
    textureBinding Texture2D $= gtex
    

    例如。

    【讨论】:

    • 叮叮叮!这允许我加载多个纹理并将它们传递给渲染部分。接下来的想法是,随着纹理列表的增加,在当前设置中,我必须先传递每个纹理以显示,然后才能调用它们。为了简化多个纹理的传递,我只需在单独的区域中调用 getAndCreateTextures 并将大量纹理作为一个变量返回,对吗?
    • @llanoraw 通常,您会将纹理的加载和它们的使用分开。您可能能够在启动时加载所有纹理,或者您可能希望根据当前可见场景一次加载一些纹理。您可能需要考虑将几何与记录中必要的TextureObject(s) 配对,然后渲染该记录。
    【解决方案2】:

    您传递纹理对象。 getAndCreateTextures 似乎为您提供了纹理对象列表。您将其中一个传递给绑定,例如

    textureBinding $ Texture2D $= Just tex[0]
    

    【讨论】:

    • 这就是我的想法..虽然它无法运行。我得到一个类型不匹配:预期类型 TextureTarget,实际类型 IO()
    • $ 让它就像你把所有的右边都放在一个参数中一样 textureBinding
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多