DirectX8 Gamma Correction (Resolved and works!)

Started by
2 comments, last by Jacob Roman 19 years, 6 months ago
I'm having a difficult time working with gamma correction in DirectX8 for VB. All I get is a black screen no matter what the values are, which means I have done something wrong. Yes, my video card supports it and yes, I'm already looping through all 255 colors of Red Green, and Blue. Anyone know how to do this correctly. A small clip of source code would help, whether it is in VB or C++, doesn't matter just as long as I get the general idea of the solution to my problem. Thanx. [Edited by - Jacob Roman on October 13, 2004 10:46:25 PM]
Advertisement
Ok I've fixed my code a little bit and now it just displays the gamma color which fills the screen, but not what I'm blitting, which would be the FPS, the Mouse Coordinates, and the game(not shown in the example code). Here is some, but not all of my code. It will not be the same as my program since I have a lot more written, but all of that is not needed in this example code.

Public Gamma_Ramp As D3DGAMMARAMPPublic Original_Ramp As D3DGAMMARAMPPublic Function Signed(Value As Long) As Integer        If Value <= 32767 Then            Signed = CInt(Value)                Exit Function            End If        Signed = CInt(Value - 65535)    End FunctionPublic Function Unsigned(Value As Integer) As Long    If Value >= 0 Then            Unsigned = Value        Exit Function            End If        Unsigned = Value + 65535    End FunctionPublic Sub Update_Gamma(Red As Integer, Green As Integer, Blue As Integer)    On Error GoTo Error_Handler:    Dim Current_Color As Long    For Current_Color = 0 To 255                If Red < 0 Then Gamma_Ramp.Red(Current_Color) = Signed(Unsigned(Original_Ramp.Red(Current_Color)) * (100 - Abs(Red)) / 100)        If Red = 0 Then Gamma_Ramp.Red(Current_Color) = Original_Ramp.Red(Current_Color)        If Red > 0 Then Gamma_Ramp.Red(Current_Color) = Signed(65535 - ((65535 - Unsigned(Original_Ramp.Red(Current_Color))) * (100 - Red) / 100))                If Green < 0 Then Gamma_Ramp.Green(Current_Color) = Signed(Unsigned(Original_Ramp.Green(Current_Color)) * (100 - Abs(Green)) / 100)        If Green = 0 Then Gamma_Ramp.Green(Current_Color) = Original_Ramp.Green(Current_Color)        If Green > 0 Then Gamma_Ramp.Green(Current_Color) = Signed(65535 - ((65535 - Unsigned(Original_Ramp.Green(Current_Color))) * (100 - Green) / 100))                If Blue < 0 Then Gamma_Ramp.Blue(Current_Color) = Signed(Unsigned(Original_Ramp.Blue(Current_Color)) * (100 - Abs(Blue)) / 100)        If Blue = 0 Then Gamma_Ramp.Blue(Current_Color) = Original_Ramp.Blue(Current_Color)        If Blue > 0 Then Gamma_Ramp.Blue(Current_Color) = Signed(65535 - ((65535 - Unsigned(Original_Ramp.Blue(Current_Color))) * (100 - Blue) / 100))        Next    Direct3D_Device.SetGammaRamp D3DSGR_CALIBRATE, Gamma_Ramp    Exit SubError_Handler:End SubPublic Sub Game_Loop()     Direct3D_Device.GetGammaRamp Original_Ramp     While Game_Active = True          If GetQueueStatus(QS_HOTKEY Or QS_KEY Or QS_MOUSEBUTTON Or QS_POSTMESSAGE Or QS_PAINT) Then DoEvents          Direct3D_Device.Clear 0, ByVal 0, D3DCLEAR_TARGET, RGB(0, 0, 0), 1#, 0                          Direct3D_Device.BeginScene               Draw_FPS                                       Draw_Mouse_Coodinates                                  Direct3D_Device.EndScene              Direct3D_Device.Present ByVal 0, ByVal 0, frmMain.hWnd, ByVal 0          Update_Gamma 50, 50, 50 'So it's 50% brighter.     WendEnd Sub 


So what am I doing wrong. How come it is not blitting the other things I want drawn. I already tried putting Update_Gamma before the Direct3D_Device.Present statement too. Something is missing.
I don't understand why noone is answering my question. Maybe it's too advanced for some people, I don't know.
AH HA. I just found the rarest article out there on doing Gamma Correction for VB using DirectX8. And it works! DO NOT PASS THIS UP!!! THIS IS RARE. Here is the URL:

http://www.mvps.org/vbdx/articles/gamma/index.html

And here is the code:

Public Sub SetGamma(Optional ByVal GammaFactor As Single = 1!)    Dim d3dCaps As D3DCAPS8    Dim NewRamp As D3DGAMMARAMP    Dim NewValue As Long    Dim ui As Long    Dim i As Long    'see if this device can do fullscreen gamma    Call D3DDevice.GetDeviceCaps(d3dCaps)    If (d3dCaps.Caps2 And D3DCAPS2_FULLSCREENGAMMA) _            <> D3DCAPS2_FULLSCREENGAMMA Then        'device does not support gamma correction        Exit Sub    End If    'create linear gamma ramp    For i = 0 To 255        NewValue = i * GammaFactor * 255: ui = 0        If NewValue > 32767 Then NewValue = NewValue - 32767: ui = 1        If NewValue > 32767 Then NewValue = 32767        'manipulate bits to handle unsigned integers        NewRamp.red(i) = NewValue Or (&H8000 * ui)        NewRamp.green(i) = NewValue Or (&H8000 * ui)        NewRamp.blue(i) = NewValue Or (&H8000 * ui)    Next i    'send gamma ramp to device    Call D3DDevice.SetGammaRamp(D3DSGR_NO_CALIBRATION, NewRamp)End Sub


I changed the code a little bit. The D3DDevice is the most commonly named variable for the Direct3DDevice8 data type. The guy had g_oDevice. I myself don't like to abreviate variables. My code actually looks like real english and is easy to read that way, so I call mine Direct3D_Device. Some beginner can look at D3DDevice and go "Huh? what's the 'D' in D3DDevice?" or something like that. Anyways, that's not that important. back to the subject. In the GammaFactor, it's default value is 1. I prefere 3 or maybe 5 as an example to where you can actually see it working.

"Where do I use it in a loop?" I asked myself the same question. I just put it one line before the Direct3D_Device.Clear statement.

While Game_Active = True     DoEvents     '------------------------     SetGamma 3 'HERE IT IS  <----------------     '------------------------                         Direct3D_Device.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, RGB(0, 0, 0), 1#, 0                     Direct3D_Device.BeginScene                                 Draw_FPS         Draw_Mouse_Coodinates                                 Direct3D_Device.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Polygon(0), Len(Polygon(0))                             Direct3D_Device.EndScene         Direct3D_Device.Present ByVal 0, ByVal 0, 0, ByVal 0Wend

This topic is closed to new replies.

Advertisement