我正在写一个3D图形库作为我的一个项目的一部分,而且我正处于一切正常工作的地步,但还不够好。关于优化Z缓冲区实现的建议?
特别是,我的主要头疼的是,我的像素填充率为可怕慢 - 绘制跨越一个800x600窗口的一半我的目标机器上的三角形时,我甚至不能管理30 FPS(这是无可否认的旧电脑,但它应该是能够管理这个)
我跑gprof的在我的可执行文件,我结束了以下有趣的台词:。
% cumulative self self total
time seconds seconds calls ms/call ms/call name
43.51 9.50 9.50 vSwap
34.86 17.11 7.61 179944 0.04 0.04 grInterpolateHLine
13.99 20.17 3.06 grClearDepthBuffer
<snip>
0.76 21.78 0.17 624 0.27 12.46 grScanlineFill
功能vSwap
是我的双缓冲区交换功能,并且它也执行语音处理,所以对我来说测试程序将花费大量时间在那里等待。 grScanlineFill
是我的三角形绘制功能,它创建一个边缘列表,然后调用grInterpolateHLine
实际填充三角形。
我的引擎当前正在使用Z缓冲来执行隐藏表面去除。如果我们对(假设的)vsynch开销进行折扣,那么事实证明测试程序花费了其执行时间的85%,或者清除深度缓冲区,或者根据深度缓冲区中的值写入像素。我的深度缓冲区清除功能本身就很简单:将浮点数的最大值复制到每个元素中。功能grInterpolateHLine
是:
void grInterpolateHLine(int x1, int x2, int y, float z, float zstep, int colour) {
for(; x1 <= x2; x1 ++, z += zstep) {
if(z < grDepthBuffer[x1 + y*VIDEO_WIDTH]) {
vSetPixel(x1, y, colour);
grDepthBuffer[x1 + y*VIDEO_WIDTH] = z;
}
}
}
我真的不知道怎样才能改善这种,特别是考虑到vSetPixel
是一个宏。
我的优化思路整个股市已经削减到精确之一:
- 使用整数/定点深度缓冲。
,我有整数/定点深度缓冲的问题是,插值可以很烦人,我实际上并不有定点数库呢。有任何进一步的想法吗?任何意见将不胜感激。
使用像OpenGL这样的硬件解决方案? – Lalaland
哈哈,不幸的是,这个项目的重点是要教自己如何真正起作用。类似于使用OpenGL等的对立面。 – Ethereal
也gcc有一些固定点支持本身:http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html – Lalaland