4.5   灯光状态

  除了“渲染状态”中我们讨论的那些状态之外,Direct3D设备还要控制灯光状态。当灯光状态需要改变时,可以通过设备接口来进行。因此,程序可以将一个特殊的渲染状态或灯光状态应用于单个图元或一组图元。

  设备的灯光状态的特性通过IDirect3DDevice3::SetLightState方法进行控制。所有可能的灯光状态都在D3DLIGHTSTATETYPE枚举类型中进行声明,它的一个成员作为IDirect3DDevice3::SetLightState的第一个参数。灯光状态的属性如下:

4.5.1 顶点颜色光

      D3DVERTEXD3DLVERTEXD3DTLVERTEX类型的顶点不能同时包含颜色和法向量信息。因为缺省的明暗处理模式为Gouraud模式,而它又同时需要顶点的颜色和法向量信息,所以Direct3D在光线计算时不使用顶点颜色。

      在有关可塑(flexible)顶点格式的介绍中,我们可以看到,顶点可以同时包含颜色和法向量信息。缺省情况下,在计算光线时Direct3D会使用这些信息。如果想要程序不使用顶点颜色光线信息,可以引用IDirect3DDevice3::SetLightState方法,并将D3DLIGHTSTATE_COLORVERTEX作为第一个参数, 将第二个参设置为FALSE,这样就会使顶点颜色光线无效。如果将第二个参数设置为TRUE,就会使顶点颜色光线有效。

      如果D3DLIGHTSTATE_COLORVERTEX被设置为TRUE,并且有一个漫散射的顶点颜色存在,那么输出的alpha值就会和顶点的漫散射alpha值相等。否则,输出的alpha就和漫散射材质的alpha成分相等,并且在[0, 255]之间。

4.5.2 环境光

      环境光是指来自于各个方向的环境中的光线。引用IDirect3DDevice3::SetLightState方法可以设置环境光的颜色,同时要将D3DLIGHTSTATE_AMBIENT作为第一个参数,第二个参数是颜色的RGBA格式,缺省时为0

    // This code fragment assumes that lpD3DDevice3 is a valid pointer to
    // a Direct3DDevice3.
    // Set the ambient light.
    D3DCOLOR d3dclrAmbientLightColor = D3DRGBA(1.0f,1.0f,1.0f,1.0f);
    lpD3DDevice3->SetLightState(D3DLIGHTSTATE_AMBIENT, d3dclrAmbientLightColor);

      环境光不会受到方向光(direct light)的影响。详细内容见“方向光对环境光”。

4.5.3 平滑模式光线

      D3DLIGHTSTATE_COLORMODEL光线状态已经不再使用。但创建一个渲染设备时,程序会隐含的选择使用彩色模式。

4.5.4 顶点雾化参数状态

      由于顶点雾化是在光线中使用的,所以可以通过光线接口来控制顶点雾化的参数。有关顶点雾化的有关概念,请看“顶点雾化”部分。

      D3DLIGHTSTATE_FOGMODED3DLIGHTSTATE_FOGSTARTD3DLIGHTSTATE_FOGENDD3DLIGHTSTATE_FOGDENSITY光线状态可以控制顶点雾化的状态。

4.5.5 材质状态

  D3DLIGHTSTATE_MATERIAL光线状态用来控制当前渲染的材质。缺省情况下不使用材质。调用IDirect3DDevice3::SetLightState可以设置一个新的渲染材质,同时要将D3DLIGHTSTATE_MATERIAL作为第一个参数,将代表材质的材质句柄作为第二个参数。要取消对材质的选定,可以将第二个参数设置为NULL。没有选择任何材质时,Direct3D的光线引擎无效。

  详细内容见“材质”。

 

5.  仿真模式

  Direct3D提供三种设备对3-D硬件进行方针:MMXRGB,和ramp设备。详细内容见“MMX Device”,“RGB Device”和“Ramp Device”。由于这些设备是对硬件的仿真,因此它们在渲染时要比3-D硬件慢。但是,如果用户的机器没有3-D硬件的支持,那么这三种仿真设备是非常实用的。

  MMXRGB模式提供了Direct3D变换和光线模块所有的功能。在这两种模式中,可以使用8-16-24-、或 32-bit纹理。

  Ramp模式利用了变换模块的所有功能,但是不支持有颜色的光线。一个ramp模式设备值使用Direct3D光线模块中的单灰度光线。因此,ramp模式中的光线只有亮度而没有颜色。灰度值存放在光线颜色的蓝色成分中。

  Ramp模式中可以使用彩色材质和纹理。Direct3D用材质或纹理的颜色作为它的基本颜色。如果白光(全照度光线)照在材质或纹理上,就使用这一基本颜色。但是,如果光强不是全照度的,Direct3D会将灰色或黑色混合到材质或纹理的颜色当中。如果程序在ramp模式中使用纹理,那么必须设置D3DLIGHTSTATETYPE枚举类型的D3DLIGHTSTATE_MATERIAL成员。在ramp模式中只能使用8-bit纹理。详细内容见“材质”和“Ramp模式光线”。

  要想设置应用于ramp模式的材质或纹理的颜色值的数量,程序必须在创建材质时设置D3DMATERIAL结构的dwRampSize成员。Direct3D用材质和纹理的颜色作为基本颜色。根据光线的亮度,dwRampSize成员中的值决定基本颜色采用多少级梯度。Direct3D根据dwRampSize成员中声明的入口号(基于1)创建一个颜色调色板。因为调色板入口的最大值小于256256要减去Windows实用的保留色),所以程序应该声明所需的灰度值的最小值。

  最好的结果是使ramp大小能与大多数或所有程序中的材质具有相同的值。当Direct3D运行完所有的调色板入口,它会在当前的材质中进行搜索,找到一个最接近的颜色。只有具有相同的ramp大小的材质才会被认为是匹配的。

 

6.  AGP表面与Direct3D设备

  在一个3-D程序中使用纹理可以使场景更加真实。对于程序开发人员来说,用于存放纹理的内存永远是不够的。DirectDrawDirect3D支持图形加速端口(Accelerated Graphics Port(AGP)结构。AGP结构使我们能够在程序内存中来创建DirectDraw表面。这样可以显著的扩充用于存放纹理的内存。

  只有Direct3D HAL设备支持AGP结构。有关AGP结构的使用的详细内容见“使用非本地显存表面”。

 

7.  执行缓冲

这一部分我们讨论有关执行缓冲的内容。

7.1 关于执行缓冲

  以前,所有的Direct3D立即模式程序都要使用执行缓冲。现在,出现了DrawPrimitive方法,因此,大多数新编的程序不再使用执行缓冲或IDirect3DexecuteBuffer接口。

  执行缓冲与OpenGL中的显示列表比较相似。执行缓冲包含一个顶点列表,后面接着一个指令流。这个指令流包括了运算代码(operation codes)或操作码(opcodes),以及修改这些操作码的数据。每个执行缓冲都被限制于一个单独的Direct3D设备。

  可以通过调用IDirect3DDevice::CreateExecuteBuffer创建一个IDirect3DexecuteBuffer接口。

lpD3DDevice->CreateExecuteBuffer( lpDesc, // Address of a DIRECT3DEXECUTEBUFFERDESC structure
                lplpDirect3DExecuteBuffer, // Address to contain a pointer to theDirect3DExecuteBuffer object
                pUnkOuter); // NULL

  执行缓冲驻留在一个设备列表上。可以使用IDirect3DDevice::CreateExecuteBuffer方法为当前的缓冲器定位,这个缓冲器也可能在硬件设备上。

  使用IDirect3DExecuteBuffer::LockIDirect3DExecuteBuffer::Unlock、和IDirect3DExecuteBuffer::SetExecuteData方法将两个相邻的顶点和操作码数组填充到缓冲器中。

lpD3DExBuf->Lock( lpDesc);. // Address of a DIRECT3DEXECUTEBUFFERDESC structure

// .
// . Store contents through the supplied address
// .

lpD3DExBuf->Unlock();
lpD3DExBuf->SetExecuteData( lpData); // Address of a D3DEXECUTEDATA structure

  上面例子中的最后一个调用是IDirect3DExecuteBuffer::SetExecuteData方法。这个方法用来通知Direct3D,将缓冲器的两个部分驻留在相对于由IDirect3DExecuteBuffer::Lock方法返回的地址的地方。

  使用IDirect3DexecuteBuffer接口,可以得到和设置执行数据,还可以锁定、解锁、优化和确认执行缓冲。

 

 

上一页 | 目录 | 下一页