分享
 
 
 

基于DirectDraw的Calibrator机制之探讨

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

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

for (int j = 0; 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有研究者不吝赐教。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有