QUAKE 3源代码审查:渲染器

QUAKE 3源代码评论:RENDERER(第2部分,共5部分)>>

Quake III渲染器是Quake II硬件加速渲染器的演变:经典部分是建立在“二进制分区”/“潜在可见集”架构上,但两个新的关键方面是显着的:

  • 一个基于OpenGL 1.X固定管道的着色器系统。这在1999年是相当成就的。它在现在无处不在的顶点,几何和片段着色器之前的一个时代提供了大量的创新空间。
  • 支持多核架构:OpenGL客户机/服务器模型在某些方法上阻塞,线程系统部分消除了此问题。

结构

渲染器完全包含在renderer.lib静态链接中quake3.exe


渲染器的整体构架是Quake Classic:它依赖于着名的BSP / PVS / Lightmap组合:

  • 预处理:
    1. 游戏设计师使用QRadiant创建并保存.map。
    2. q3bsp.exe通过二进制空间分区对地图进行切片。我在Quake1渲染器审查中写了这个。
    3. 在BSP之外,生成门户系统:我在Doom3 Dmap工具中写了这个。
    4. q3vis.exe使用门户系统并为每次休假生成PVS(潜在可见集)。每个PVS被压缩并存储在一个bsp文件中,就像我之前的文章中描述的那样。
    5. 门户系统被丢弃。
    6. q3light.exe 计算地图中每个多边形的所有照明,并将结果作为光照贴图存储在bsp文件中。
    7. 此时,所有预处理(PVS和Lightmaps)都存储在.bsp文件中。
  • 运行时刻:
    1. 引擎加载地图和bsp。
    2. 要求转载时:
    3. 引擎解压PVS作为当前休假,确定实际上是可见的。
    4. 对于每个多边形,它通过多重打印将光线图与颜色相结合。

当引擎被修改为仅显示一个或另一个引擎时,可以清楚地看到多重贴图和光照图步骤:

由水平设计师/艺术家绘制的纹理:由下列生成

的光照图q3light.exe

通过多纹理在运行时组合时的最终结果:

渲染Brian Hook在1999年游戏开发者大会上讨论了架构。不幸的是,GDC Vault视频目前正在关闭:(!

着色器

着色器系统建立在OpenGL 1.X固定管道之上,因此非常昂贵。开发人员可以编程顶点修改,但也可以添加纹理过程。这是在“地震3着色器圣经”中描述的:

多核渲染器和SMP(对称多处理)

对许多人来说是未知的:Quake III Arena 通过cvariable 发送SMP支持 r_smp。前端和后端通过标准的生产者/消费者设计进行通信。当r_smp设置为1时,绘图表面交替存储在位于RAM中的双缓冲区中。前端(在本示例中称为主线程)或者写入缓冲区之一,而另一个由后端读取(在本示例中称为渲染器线程)。

说明事情如何运作的一个例子:

从t0到t1:

  • 主线程决定绘制和写入surfacebuffer1的曲面。
  • 渲染器线程正在挨饿,因此锁定。
  • GPU线程也不做任何事情。

从t1到t2:事情开始移动到整个地方:

  • 主线程正在决定下一帧可见的内容。它将surface写入surfacebuffer2:这是Double Buffering的典型示例。
  • 同时,渲染器线程使OpenGL调用并耐心等待,直到GPU线程将所有内容复制到安全的空间。
  • GPU线程从Renderer线程指向的地方读取表面。

请注意,在t2:

  • 渲染器线程仍然将数据传输到GPU:SurfaceBuffer1正在使用中。
  • 主线程完成写入SurfaceBuffer2 ...但无法开始写入SurfaceBuffer1:它被锁定

这种情况(渲染器线程锁定主线程)实际上是玩Quake III时最常见的:它说明了OpenGL API中某些方法的阻止限制,

t2:

  • 渲染器线程一旦完成了SurfaceBuffer1(t3),它就会从SurfaceBuffer2开始抽取曲面。
  • 一旦解锁(在t3),主线程开始在下一帧工作,写入SurfaceBuffer1。
  • GPU几乎不会空闲这个配置。

注意:通过执行同步 Windows事件对象 在 winglimp.c(在底部SMP加速区间)。

下一部分

你可能感兴趣的:(quake3)