Discussion on Gamma Calibrator Mechanism Based on DirectDraw

zhaozj2021-02-11  191

Discussion on Gamma Calibrator Mechanism Based on DirectDraw

1. Problem

Gamma Calibrator Based on Dynamic Gamma Ramp Technology. Provide dynamic GAMMA RAMP support for the system, based on the needs of the following applications: 1. The designer of the game program can provide a consistent visual effect for users, regardless of the system of users. 2. With the rapid development of e-commerce, merchants and users are urgently needed to see the true color of the goods samples on the Internet. 3. Who wants that the color of the image on the display is similar to the color of the output.

Based on the above needs, with Microsoft Windows Logo hardware products are required to provide dynamic gamma ramp support (see "Adapter supports downloadable RAMDAC entries for image color matching", URL: www.microsoft.com/hwdev/xpapers/pc98/14grfx98.htm) . As long as the card and its driver supports dynamic GAMMA RAMP, all pixels in Buffer frame can be replaced by the correction value.

In order to support dynamic Gamma Ramp in Windows95, Windows98, and Windows 2000, the IDirectDrawGamMacontrol interface is provided in DirectDraw. This interface allows the program designer to process GAMMA RAMP, allowing the RGB value of the pixel to be corrected before being sent to the DAC display.

Originally, two functions in Win32 API (ie setDevicegammaramp / getDevicegammaramp) can be used to get GAMMA RAMP. But they have the following limitations more than the DirectDRAW interface: 1. SetDeviceGamMARAMP does not allow all possible Gamma RAMP values. It will check GAMMA RAMP if it is too complicated. 2. SetDeviceGamMARAMP does not currently support Gamma Calibrator. 3. Call the set of SetDeviceGamMARAMP and does not automate the operation after shutting down unless the GAMMA RAMP is restored to the value before the settings.

In contrast to the second point above, in addition to the GAMMA RAMP, the DirectDRAW interface allows Gamma Ramp to be corrected, which requires a Gamma Calibrator.

Two. Analysis

As far as I know, so far, DirectDraw registers and uses Gamma Calibrator's mechanism has not finally determined, only one transition plan. This program only uses a short sentence to describe: Calibrator registers itself in a key in the system registry; when the application needs to correct Gamma Ramp, DirectDraw calls this Calibrator.

As for the specific implementation details, I did not find any documentation.

Based on this, I analyzed and guess the mechanism of DirectDraw Calibrator. I found that as follows:

1) The output function called CalibrateGamMARAMP must be implemented in the Calibrator, and the operation of Gamma Calibration is implemented in this function. 2) Calibrator must register its own installation path in the system registry in key: HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / DirectDraw / Gammaclibrator3) The client contacts the Calibrator by calling IDirectDrawGammacontrol :: setgammaramp. The prototype of SetgammaMP is: HRESULT SETGAMMARAMP (DWORD DWFLAGS, LPGAMMARAMP LPRAMPDATA) DWFLAG indicates whether Gamma Calibration is required. If this parameter is set to DDSGR_Calibrate, the system will request Calibrator to adjust the Gamma Ramp to achieve the purpose of correcting the display effect. If you do not need to calibrate, set this parameter to 0. LPRAMPDATA is the address of the DDGamMARAMP structure, which includes the Gamma RAMP value of R, G, and B tripogin. After setting the dwflags parameter, DDSGR_CALIBRATE and call SetgamMaRP, DirectDRAW automatically locates the Calibrator path according to the Calibrator registration information, and calls the Calibrator's CalibrateGamMARAMP output function to implement Gamma Calibration. Implementation

I wrote two test programs to verify the implementation mechanism of Gamma Calibrator. Calibrator.cpp generates Calibrator.dll, which is a Gamma Calibrator program; Test.cpp generates Test.exe, the client, which calls Calibrator.

1. The structure of the CalibratorCalibrator itself is very simple, it only needs three functions (or even one, ie CalibrategamMARAMP, and other two can be implemented in the installer or manual). 1) CalibrateGamMARAMP output function. It is declared as follows: Extern "c" __declspec (dllexport) HRESULT CALIBRATEGAMMARAMP (D3DGAMMARAMP * PRAMP) where the parameter PRAMP is the current GAMMA RAMP value (i.e., the value set when the client is set to setGamMARAMP). For the purpose of the test, this initial value is not taken in my Calibrator, but re-sets Gamma Ramp, and exaggerates all R (Red) values ​​to 0 to facilitate see the test effect.

HDC HDC = :: getdc (null); if (! Hdc) returnif;

Word RamdAntable [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 RamdAntable [i * 256 j] = j * 256;

If (! setDevicegammamp (hdc, ramdactable)) {bool breason = getLastError (); :: MessageBox (Null, "SetDeviceGampramp Failed!", "Error", null;} :: releasedc (null, HDC);

2) In order to allow DLLs to REGISTER and Unregister's own installation path, output two functions DllRegisterServer and DllunregisterServer for the Regsvr32 program. The implementation of these two functions is consistent with the writing in the COM DLL, and details are not described here. Note Information To register to HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / DirectDraw / Gammaclibrator key.

2. Customer program

The client must support DirectDraw to call the Calibrator. 1) First, create a Direct3D object: LPDIRECT3D8 g_pD3D; g_pD3D = :: Direct3DCreate8 (D3D_SDK_VERSION) 2) to obtain the current display mode: D3DDISPLAYMODE d3ddm; g_pD3D-> GetAdapterDisplayMode (D3DADAPTER_DEFAULT, & d3ddm) 3) Create Direct3D device: LPDIRECT3DDEVICE8 g_pd3dDevice = NULL; g_pD3D-> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, & d3dpp, & g_pd3dDevice) 4) detects whether a device supports gamma calibration: D3DCAPS8 d3dcap; if (FAILED (g_pd3dDevice-> GetDeviceCaps (& d3dcap))) {:: MessageBox (NULL, " GetDeviceCaps "," Failed ", NULL); return E_FAIL; (! (d3dcap.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA)} if) {:: MessageBox (NULL," Your machine does not support gamma Calibrator "," warnning ", NULL); Return E_FAIL;} 5) Set Gamma Ramp: D3DGAMMARAMP D3DGAMARAMP; ... // Initialize D3Dgamaramp

// Set Gamma Ramp, and request Calibration G_PD3DDevice-> setgammaramp (D3DSGR_CALIBRATE, & D3DGAMARAMP);

转载请注明原文地址:https://www.9cbs.com/read-4424.html

New Post(0)