无法在 Common Lisp 的 OpenGL 中使用纹理
Unable to get textures to work in OpenGL in Common Lisp
我正在构建一个 simple Solar system model 并尝试在某些球体上设置纹理。
几何体已正确生成,我尝试了几种不同的方法来生成纹理坐标。目前我依靠 glu:quadric-texture
在调用 glu:sphere
时生成坐标。
但是,纹理从未出现 - 对象以纯色呈现。
我浏览了几个 OpenGL 指南,我认为我没有遗漏任何一步,但谁知道呢。
大致情况如下:
- 调用
gl:enable :texture-2d
打开纹理
- 使用
cl-jpeg
加载图片
- 致电
gl:bind-texture
- 使用
gl:tex-image-2d
从图像复制数据
- 使用
gl:gen-textures
生成纹理 ID。还尝试一个一个地生成 ID,而不是一次全部生成,但没有效果。
- 在绘制过程中创建新的二次曲面,启用纹理坐标生成并在生成二次曲面点之前绑定纹理:
(let ((q (glu:new-quadric)))
(if (planet-state-texture-id ps)
(progn (gl:enable :texture-gen-s)
(gl:enable :texture-gen-t)
(glu:quadric-texture q :true)
(gl:bind-texture :texture-2d planet-texture-id)))
(glu:quadric-texture q :false))
(glu:sphere q
planet-diameter
*sphere-resolution*
*sphere-resolution*)
我也尝试了更手动的纹理坐标生成方法,但没有效果。
这里没有想法……
程序运行时,我可以看到纹理已加载并且纹理 ID 已保留,它会打印
loading texture from textures/2k_neptune.jpg with id 1919249769
Loaded data. Image dimensions: 1024x2048
我不知道您是否找到了解决问题的方法,但在创建测试图像并修改您的一些代码后,我能够获得要应用于球体的纹理。
问题在于您在启用纹理之前尝试将它们上传到 GPU。 (gl:enable :texture-2d) 必须在开始处理 texture/image 数据之前调用。
我建议将 let* 块与主函数中的 planets-init 放在 'setup-gl' 之后,并移动带有行星数据的 'format' 函数以正常工作而不会出现错误。
我的建议是这样的:
(let ((camera ...
...
(setup-gl ...)
(let* ((planets...
...
(format ... planet-state)
在你的 draw-planet 函数中,你需要在它的末尾添加 (gl:bind-texture :texture-2d 0) 这样纹理就不会被其他物体使用,比如轨道路径。
实际上,(gl:quadratic-texture ...) 之前的 (gl:color 1.0 ...) 将修改渲染对象的颜色,因此它可能看起来不像您期望的那样。
编辑:我应该澄清这一点,但按照你的代码,它是
initialize-planets > make-textures > enable-textures > render
什么时候应该
enable-textures > init-planets > make-textures > render
你没有遗漏任何一步是正确的,只是你代码中的步骤顺序错了。
我正在构建一个 simple Solar system model 并尝试在某些球体上设置纹理。
几何体已正确生成,我尝试了几种不同的方法来生成纹理坐标。目前我依靠 glu:quadric-texture
在调用 glu:sphere
时生成坐标。
但是,纹理从未出现 - 对象以纯色呈现。
我浏览了几个 OpenGL 指南,我认为我没有遗漏任何一步,但谁知道呢。
大致情况如下:
- 调用
gl:enable :texture-2d
打开纹理 - 使用
cl-jpeg
加载图片
- 致电
gl:bind-texture
- 使用
gl:tex-image-2d
从图像复制数据
- 使用
gl:gen-textures
生成纹理 ID。还尝试一个一个地生成 ID,而不是一次全部生成,但没有效果。 - 在绘制过程中创建新的二次曲面,启用纹理坐标生成并在生成二次曲面点之前绑定纹理:
(let ((q (glu:new-quadric)))
(if (planet-state-texture-id ps)
(progn (gl:enable :texture-gen-s)
(gl:enable :texture-gen-t)
(glu:quadric-texture q :true)
(gl:bind-texture :texture-2d planet-texture-id)))
(glu:quadric-texture q :false))
(glu:sphere q
planet-diameter
*sphere-resolution*
*sphere-resolution*)
我也尝试了更手动的纹理坐标生成方法,但没有效果。
这里没有想法……
程序运行时,我可以看到纹理已加载并且纹理 ID 已保留,它会打印
loading texture from textures/2k_neptune.jpg with id 1919249769
Loaded data. Image dimensions: 1024x2048
我不知道您是否找到了解决问题的方法,但在创建测试图像并修改您的一些代码后,我能够获得要应用于球体的纹理。
问题在于您在启用纹理之前尝试将它们上传到 GPU。 (gl:enable :texture-2d) 必须在开始处理 texture/image 数据之前调用。
我建议将 let* 块与主函数中的 planets-init 放在 'setup-gl' 之后,并移动带有行星数据的 'format' 函数以正常工作而不会出现错误。
我的建议是这样的:
(let ((camera ...
...
(setup-gl ...)
(let* ((planets...
...
(format ... planet-state)
在你的 draw-planet 函数中,你需要在它的末尾添加 (gl:bind-texture :texture-2d 0) 这样纹理就不会被其他物体使用,比如轨道路径。
实际上,(gl:quadratic-texture ...) 之前的 (gl:color 1.0 ...) 将修改渲染对象的颜色,因此它可能看起来不像您期望的那样。
编辑:我应该澄清这一点,但按照你的代码,它是
initialize-planets > make-textures > enable-textures > render
什么时候应该
enable-textures > init-planets > make-textures > render
你没有遗漏任何一步是正确的,只是你代码中的步骤顺序错了。