0

我在两个不同的对象上使用两个纹理,每个对象都有自己的着色器程序。但是,第二个对象在渲染时应用了两种纹理并带有一些奇怪的扭曲。

当第一个对象和纹理正确渲染时,我将重点关注第二个对象的代码。

第一个纹理是这样加载的:

-- Icosahedron texture
dice_textureP <- malloc
glGenTextures 1 dice_textureP
diceText <- peek dice_textureP
glBindTexture GL_TEXTURE_2D diceText
glEnable GL_BLEND
glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
glGenerateMipmap GL_TEXTURE_2D
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEAT
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEAT
eErrDI0 <- readImage "app/numbers.png"
dyImage0 <- case eErrDI0 of
    Left e -> do
        putStrLn e
        return $ ImageRGBA8 $ generateImage (\x y ->
            let x' = fromIntegral x in (PixelRGBA8 x' x' x' x')) 500 400
    Right di -> return di
let ipixelrgba80 = convertRGBA8 dyImage0
    iWidth0 = fromIntegral $ imageWidth ipixelrgba80
    iHeight0 = fromIntegral $ imageHeight ipixelrgba80
    iData0 = imageData ipixelrgba80
VS.unsafeWith iData0 $ \dataP ->
    glTexImage2D GL_TEXTURE_2D 0 GL_RGBA iWidth0 iHeight0 0 GL_RGBA GL_UNSIGNED_BYTE (castPtr dataP)
glGenerateMipmap GL_TEXTURE_2D
glBindTexture GL_TEXTURE_2D 0

第二个纹理是这样加载的:

card_oneP <- malloc
glGenTextures 1 card_oneP
card_oneTexture <- peek card_oneP
glBindTexture GL_TEXTURE_2D card_oneTexture
glDisable GL_BLEND
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST_MIPMAP_NEAREST
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_NEAREST_MIPMAP_NEAREST
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_CLAMP_TO_EDGE
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_CLAMP_TO_EDGE
eErrDI1 <- readImage "app/card_one.jpg"
dyImage1 <- case eErrDI1 of
    Left e -> do
        putStrLn e
        return $ ImageRGBA8 $ generateImage (\x y ->
            let x' = fromIntegral x in (PixelRGBA8 x' x' x' x')) 312 445
    Right di -> return di
let ipixelrgb81 = convertRGBA8 dyImage1
    iWidth1 = fromIntegral $ imageWidth ipixelrgb81
    iHeight1 = fromIntegral $ imageHeight ipixelrgb81
    iData1 = imageData ipixelrgb81
VS.unsafeWith iData1 $ \dataP ->
    glTexImage2D GL_TEXTURE_2D 0 GL_RGBA iWidth0 iHeight0 0 GL_RGBA GL_UNSIGNED_BYTE (castPtr dataP)
glGenerateMipmap GL_TEXTURE_2D
glBindTexture GL_TEXTURE_2D 0

我在绘制第一个对象之前绑定第一个纹理,如下所示:

-- first vao and shader program
glUseProgram ico_shaderProgram
glBindVertexArray ico_vao

-- bind first texture
glActiveTexture GL_TEXTURE0
glBindTexture GL_TEXTURE_2D diceText
diceTextureLocation <- glGetUniformLocation ico_shaderProgram diceTexture
glUniform1i diceTextureLocation 0

调用glDrawArrays第一个对象后,我使用glBindTexture_2D 0.

第二个纹理以类似的方式绑定:

-- second vao and shader
glUseProgram card_shaderProgram
glBindVertexArray card_vao
-- bind second texture
glActiveTexture GL_TEXTURE0
glBindTexture GL_TEXTURE_2D card_oneTexture
cardTextureLocation <- glGetUniformLocation card_shaderProgram cardTexture
glUniform1i cardTextureLocation 0

glBindTexture_2D 0在重新进入渲染循环之前在绘制之后调用。

结果如下所示:

在此处输入图像描述

如您所见,右侧的对象有一些伪影......第二个纹理在第一个纹理之上渲染(应该只在第一个对象上)。而且,第二个纹理全部扭曲了。

第二个对象的顶点和 uv 坐标可以在这里找到(要点)。

用于此对象的着色器在此处(要点)。

第二个对象的属性设置如下:

-- second object attribs
glVertexAttribPointer 0 3 GL_FLOAT GL_FALSE (5*floatSize) nullPtr 
glEnableVertexAttribArray 0
let threeFloatOffset = castPtr $ plusPtr nullPtr (fromIntegral $ 3*floatSize)
glVertexAttribPointer 1 2 GL_FLOAT GL_FALSE (5*floatSize) threeFloatOffset
glEnableVertexAttribArray 1           
glBindVertexArray 0

我试图包含最相关的代码。如果有人能发现我的错误,我将不胜感激。如果需要,我 100% 愿意发布更多代码。

更新:

评论中有人友好地指出,我的代码对第二个纹理使用了不正确的宽度和高度值。我现在正在使用此功能加载图像:

loadImageTexture :: [Char] -> Int -> Int -> IO (Image PixelRGBA8)
loadImageTexture filePath w h = do
    errorOrDyImage <- readImage filePath
    dyImage <- case errorOrDyImage of
        Left e -> do
            putStrLn e
            return $ ImageRGBA8 $ generateImage (\x y ->
                let x' = fromIntegral x in (PixelRGBA8 x' x' x' x')) w h
        Right di -> return di
    return $ convertRGBA8 dyImage
4

1 回答 1

0

正如有人在评论中指出的那样,iWidth0并且iHeight0(第一个纹理的宽度和高度)被错误地称为第二个纹理:

glTexImage2D GL_TEXTURE_2D 0 GL_RGBA iWidth0 iHeight0 0 GL_RGBA GL_UNSIGNED_BYTE (castPtr dataP)

它应该是:

glTexImage2D GL_TEXTURE_2D 0 GL_RGBA iWidth1 iHeight1 0 GL_RGBA GL_UNSIGNED_BYTE (castPtr dataP)

创建一个处理加载纹理的函数可以从一开始就避免这个问题。

于 2020-07-17T14:29:08.273 回答