首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
 您现在的位置: 中国IT实验室 >> 游戏开发 >> 游戏开发文档 >> 正文
基于DirectDraw的 Calibrator机制之探讨
来源:ChinaItLab 作者: 时间:2004-12-8


  1、问题的提出
  Gamma Calibrator基于动态Gamma ramp技术。为系统提供动态Gamma ramp支持,基于以下应用的需要:
  游戏程序的设计者可以为用户提供一致的视觉效果,而不论用户使用什么系统。
  随着电子商务的迅猛发展,商家和用户都迫切需要在Internet上看到货物样品的真实色彩。
  谁都希望,显示器上图像的色彩尽可能地和输出的色彩相近。
  基于Microsoft Windows Logo的硬件产品都需要提供动态Gamma ramp支持(参见“Adapter supports downloadable RAMDAC entries for image color matching”)。只要显示卡及其驱动程序支持动态Gamma ramp,Buffer Frame中所有象素的RGB值就可以被校正值取代。
  为了在Windows 95、Windows 98及Windows 2000中支持动态Gamma ramp,DirectDraw中提供了IDirectDrawGammaControl接口。此接口允许程序设计者处理Gamma ramp,使得象素的RGB值在被送到DAC显示之前得到校正。本来,Win32 API中有两个函数(即SetDeviceGammaRamp/GetDeviceGammaRamp)可以用来获取和设置Gamma ramp。但它们较之DirectDraw接口有以下局限:
  SetDeviceGammaRamp不允许设置所有可能的Gamma ramp值。它会检查Gamma ramp,如果太复杂会拒绝执行。
  SetDeviceGammaRamp目前不支持Gamma Calibrator。
  调用SetDeviceGammaRamp的程序关闭后不会自动进行清理操作,除非将Gamma ramp恢复到设置前的值。
  与以上第二点相反,除了可以获取和设置Gamma ramp外,DirectDraw接口允许Gamma ramp被校正(Calibrated),这就需要安装一个Gamma Calibrator。
  
  2、分析问题
  据我所知,到目前为止,DirectDraw注册及使用Gamma Calibrator的机制尚未最终确定,只有一个过渡方案。此方案只用短短一句话进行了描述:Calibrator在系统注册表中的某个KEY中注册自身;当应用程序需要校正Gamma ramp的时候,DirectDraw调用这个Calibrator。至于具体实现细节,到目前我没发现任何文档。
  Calibrator中必须实现一个名为CalibrateGammaRamp的输出函数,Gamma Calibration的操作即在此函数中实现。
  
  Calibrator必须将自身所在的安装路径注册在系统注册表的如下key中: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\DirectDraw\\GammaClibrator
  
  客户程序通过调用IDirectDrawGammaControl::SetGammaRamp来间接触发Calibrator。
  SetGammaRamp的原型为:
  
  HRESULT SetGammaRamp(DWORD dwFlags, LPGAMMARAMP lpRampData)
  
  DwFlag表示是否需要进行Gamma Calibration。若这个参数设为DDSGR_CALIBRATE,系统将会请求Calibrator来调整Gamma ramp,从而达到校正显示效果的目的。若不需要校正,将这个参数设为0。LpRampData是DDGAMMARAMP结构的地址,此结构包含R、G、B三色素的Gamma ramp值。
  设置dwFlags参数为DDSGR_CALIBRATE并调用SetGammaRamp后,DirectDraw会自动根据Calibrator的注册信息找到Calibrator的路径,并调用Calibrator的CalibrateGammaRamp输出函数,从而实现Gamma Calibration。
  
  3、想法的实现
  我写了两段测试程序来检验Gamma Calibrator的实现机制。Calibrator.CPP编译链接后生成Calibrator.DLL,即Gamma Calibrator程序。Test.CPP则生成Test.EXE,即客户程序,它调用Calibrator。
  
  3.1 Calibrator
  calibrator本身的结构很简单,它只需要实现三个函数(甚至一个,即CalibrateGammaRamp,其它两个可以在安装程序中或手工实现)。
  1)CalibrateGammaRamp输出函数。其声明如下:
  
  extern \"C\" __declspec(dllexport) HRESULT CalibrateGammaRamp(D3DGAMMARAMP* pRamp)
  
  其中输入参数pRamp为当前的Gamma ramp值(也即,客户程序调用SetGammaRamp时设置的值)。出于测试的目的,在我的Calibrator中没有利用这个初始值,而是重新设置了Gamma ramp,并夸张地将所有的R(Red)值设置为0,以方便地看到测试效果。
  
  HDC hDC = ::GetDC(NULL);
  if (!hDC)
  return E_FAIL;
  
  WORD RamdacTable[3*256];
  
  GetDeviceGammaRamp(hDC, RamdacTable);
  
  for (int i = 0; i < 3; ++i)
  for (int j = 0; j < 256; ++j)
  if ( i == 0)
  RamdacTable[i] = 0;
  else
  RamdacTable[i*256+j] = j*256;
  
  if(!SetDeviceGammaRamp( hDC, RamdacTable))
  {
  BOOL bReason = GetLastError();
  ::MessageBox(NULL, \"SetDeviceGampRamp failed!\", \"Error\", NULL);
  }
  ::ReleaseDC(NULL, hDC);
  
  2)为了让DLL可以Register及unRegister自己的安装路径,输出两个函数DllRegisterServer和DllUnregisterServer,以供regsvr32程序调用。这两个函数的实现和COM DLL中的写法一致,这里不再赘述。注意信息要注册到HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\DirectDraw\\GammaClibrator键之下。
  
  3.2 客户程序
  客户程序必须支持DirectDraw,才能调用calibrator。
  1)首先,创建一个Direct3D object
  
  LPDIRECT3D8 g_pD3D;
  g_pD3D = ::Direct3DCreate8(D3D_SDK_VERSION)
  
  2)获得当前显示模式
  
  D3DDISPLAYMODE d3ddm;
  g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)
  
  3)创建Direct3D device
  
  LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
  g_pD3D->CreateDevice(
  D3DADAPTER_DEFAULT,
  D3DDEVTYPE_HAL,
  hWnd,
  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  &d3dpp,
  &g_pd3dDevice
  )
  
  4)检测设备是否支持Gamma Calibration
  
  D3DCAPS8 d3dcap;
  if( FAILED( g_pd3dDevice->GetDeviceCaps( &d3dcap ) ) )
  {
  ::MessageBox(NULL, \"GetDeviceCaps\", \"Failed\", NULL);
  return E_FAIL;
  }
  if( !( d3dcap.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA ) )
  {
  ::MessageBox(NULL, \"Your machine doesn\'t support gamma Calibrator\", \"Warnning\", NULL);
  return E_FAIL;
  }
  
  5)设置Gamma ramp
  
  D3DGAMMARAMP d3dgamaramp;
  ... // 初始化d3dgamaramp
  
  // 设置gamma ramp,同时请求Calibration
  g_pd3dDevice->SetGammaRamp( D3DSGR_CALIBRATE , &d3dgamaramp);
  
  4、结论
  由于没看到Microsoft©关于Gamma Calibration的正式文档,以上机制纯属自己的猜测。测试程序虽能工作,但终究只是猜测,不知尚有多少规范没有实现。而且,在Windows 2000下,DirectDraw对Gamma Calibration的支持似乎不够。再者,Microsoft©声称,目前DirectDraw和Gamma Calibrator的通信机制以及Calibrator注册自身的方法只是一个过渡方案,将来会改变。鉴于以上原因,特写此文,以请对Gamma Calibration有研究者不吝赐教。
  
【责编:admin】

中国IT教育热线咨询

相关文章
游戏开发新手入门之位图化图形
给希望成为游戏美术设计师的朋友
Ogre游戏引擎鼠标选取物体演示  
所有绘画的核心灵魂——素描知识
DirectDraw与DirectInput游戏编程体验
推荐文章

 精彩友情推荐
·Asp源码 PHP源码
·CGI源码 JSP源码
·建站书籍教程
·服务器软件 .net源码
·建站工具软件
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  为什么要研究攻击行为在人类有记载的5600年的历史中,共计发生了14,400次战争;今天,平均一天要发生............
游戏开发中显示对话的特殊句法
游戏原型设计的介绍
网络游戏中的攻击行为
谈动作类游戏的必要条件
规则的多元分析模式
载入位图文件到DirectDraw
Archer Game Suite 是什么?
浅谈游戏企划-新手入门篇
暴雪称霸游戏业界的六大秘密绝招
骨骼动画及示例Skinned Mesh的解析
  培训中心