VB6プログラミング:DirectX2Dグラフィック学習ログ20ガンマ補正

VB6プログラミング:DirectX 2Dグラフィック学習ログ20ガンマ補正
チュートリアルのダウンロードアドレス:https://download.csdn.net/download/gosub60/13696651
機能:↑キーと下矢印キーを押してガンマの値を変更し、明るさとグレースケールを実現します。変更の
概要:
ソースコードの最後にあるソースコードは次のとおりです。画像が必要です。

'---------------------------------
'标题:DirectX教程
'
'描述:
'
'作者:Jacob Roman
'
'日期:2005年12月2日 翻译:[email protected] QQ:127644712
'
'联系人:[email protected]
'---------------------------------

Option Explicit

''2D(已转换和已点燃)顶点格式类型。
Private Type TLVERTEX

    X As Single
    Y As Single
    Z As Single
    RHW As Single
    Color As Long
    Specular As Long
    TU As Single
    TV As Single
    
End Type

'一些颜色深度常数有助于使DX常数更具可读性。
Private Const COLOR_DEPTH_16_BIT As Long = D3DFMT_R5G6B5
Private Const COLOR_DEPTH_24_BIT As Long = D3DFMT_A8R8G8B8
Private Const COLOR_DEPTH_32_BIT As Long = D3DFMT_X8R8G8B8

'2D(转换和点亮)顶点格式。
Private Const FVF_TLVERTEX As Long = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR

Private DirectX8 As DirectX8 '主DirectX对象。
Private Direct3D As Direct3D8 '控制3D一切。
Private Direct3D_Device As Direct3DDevice8 '表示硬件渲染
Private Direct3DX As D3DX8
Private Direct3D_Caps As D3DCAPS8

Private Main_Font As D3DXFont
Private Main_Font_Description As IFont
Private Text_Rect As RECT

Private Fullscreen_Enabled As Boolean '帮助确定它是否为全屏模式。
Private Running As Boolean '帮助确定主游戏循环是否正在运行。

Private Vertex_List(3) As TLVERTEX '4个顶点将构成一个正方形

Private Texture As Direct3DTexture8

Private Gamma_Factor As Single

'使用此功能可以更轻松地设置具有所需信息的顶点。
Private Function Create_TLVertex(X As Single, Y As Single, Z As Single, RHW As Single, Color As Long, Specular As Long, TU As Single, TV As Single) As TLVERTEX

    Create_TLVertex.X = X
    Create_TLVertex.Y = Y
    Create_TLVertex.Z = Z
    Create_TLVertex.RHW = RHW
    Create_TLVertex.Color = Color
    Create_TLVertex.Specular = Specular
    Create_TLVertex.TU = TU
    Create_TLVertex.TV = TV
    
End Function

Private Function DirectX_Initialize() As Boolean

    On Error GoTo Error_Handler
    
    Dim Display_Mode As D3DDISPLAYMODE '显示模式说明。
    Dim Direct3D_Window As D3DPRESENT_PARAMETERS 'Backbuffer和视口说明。
    
    Set DirectX8 = New DirectX8 '创建DirectX对象。
    Set Direct3D = DirectX8.Direct3DCreate() '使用DirectX对象创建Direct3D对象
    Set Direct3DX = New D3DX8
    
    If Fullscreen_Enabled = True Then
    
        '“现在我们正在全屏模式下工作,我们必须设置
         '屏幕分辨率切换为,而不是使用默认屏幕
         '解析度。
        
        Display_Mode.Width = 1024
        Display_Mode.Height = 768
        Display_Mode.Format = COLOR_DEPTH_32_BIT
    
        Direct3D_Window.Windowed = False '该应用程序将处于全屏模式。
        Direct3D_Window.BackBufferCount = 1 '仅1个后缓冲
        Direct3D_Window.BackBufferWidth = Display_Mode.Width '使后缓冲宽度与显示宽度匹配
        Direct3D_Window.BackBufferHeight = Display_Mode.Height '使后缓冲高度与显示高度匹配
        Direct3D_Window.hDeviceWindow = frmMain.hWnd '使用frmMain作为设备窗口。
        
    Else
    
       Direct3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, Display_Mode '使用您当前使用的显示模式
                                                                         '已经在。 如果您感到困惑,我是
                                                                         '在谈论您当前的屏幕分辨率。 ;)
        
        Direct3D_Window.Windowed = True '该应用程序将处于窗口模式。
    
    End If
    
     Direct3D_Window.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC '监视器运行时刷新。
    Direct3D_Window.BackBufferFormat = Display_Mode.Format '设置检索到后缓冲区中的格式。
    
     
   '使用一些有用的信息以及信息创建渲染设备
     '我们已经设置了Direct3D_Window。
    Set Direct3D_Device = Direct3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, frmMain.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, Direct3D_Window)
    
    Direct3D_Device.SetVertexShader FVF_TLVERTEX '设置顶点着色的类型。 (需要)
    
    '不需要这些行,但能够过滤掉
     '使它们看起来更好的纹理。
    
    Direct3D_Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_POINT
    Direct3D_Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_POINT

    Exit Function
    
Error_Handler:
    
    MsgBox "初始化DirectX时发生错误!", vbCritical
    
    Close_Program
    
    DirectX_Initialize = False


End Function

Private Sub Create_Polygon()

    Vertex_List(0) = Create_TLVertex(0, 0, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 0, 0)
    Vertex_List(1) = Create_TLVertex(150, 0, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 1, 0)
    Vertex_List(2) = Create_TLVertex(0, 150, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 0, 1)
    Vertex_List(3) = Create_TLVertex(150, 150, 0, 1, D3DColorRGBA(255, 255, 255, 0), 0, 1, 1)

End Sub

Private Sub Load_Texture()

    Dim File_Path As String
    Dim Width As Long
    Dim Height As Long
    Dim Transparency_Color As Long
    
    File_Path = App.Path & "\Texture.jpg"

    Width = 256
    Height = 256
    
    Transparency_Color = D3DColorRGBA(0, 0, 0, 0)

    Set Texture = Direct3DX.CreateTextureFromFileEx(Direct3D_Device, _
                                                    File_Path, _
                                                    Width, Height, _
                                                    0, _
                                                    0, _
                                                    D3DFMT_A8R8G8B8, _
                                                    D3DPOOL_MANAGED, _
                                                    D3DX_FILTER_POINT, _
                                                    D3DX_FILTER_POINT, _
                                                    Transparency_Color, _
                                                    ByVal 0, _
                                                    ByVal 0)

End Sub

Private Sub DirectX8_Set_Gamma(ByVal GammaFactor As Single, Red As Integer, Green As Integer, Blue As Integer)
    
    '注意:伽玛校正仅在全屏模式下有效。
    
    Direct3D_Device.GetDeviceCaps Direct3D_Caps

    If (Direct3D_Caps.Caps2 And D3DCAPS2_FULLSCREENGAMMA) <> D3DCAPS2_FULLSCREENGAMMA Then Exit Sub
    'If (Direct3D_Caps.Caps2 And D3DCAPS2_CANCALIBRATEGAMMA) <> D3DCAPS2_CANCALIBRATEGAMMA Then Exit Sub
    
    Dim Gamma_Ramp As D3DGAMMARAMP
    
    Dim Red_Value As Long
    Dim Green_Value As Long
    Dim Blue_Value As Long
    
    Dim Unsigned_Integer_Red As Long
    Dim Unsigned_Integer_Green As Long
    Dim Unsigned_Integer_Blue As Long
    
    Dim Current_Color As Long

    '创建线性伽玛斜坡
    For Current_Color = 0 To 255
        
        Unsigned_Integer_Red = 0
        Red_Value = Current_Color * GammaFactor * Red
        If Red_Value > 32767 Then Red_Value = Red_Value - 32767: Unsigned_Integer_Red = 1
        If Red_Value > 32767 Then Red_Value = 32767
        
        Unsigned_Integer_Green = 0
        Green_Value = Current_Color * GammaFactor * Green
        If Green_Value > 32767 Then Green_Value = Green_Value - 32767: Unsigned_Integer_Green = 1
        If Green_Value > 32767 Then Green_Value = 32767
        
        Unsigned_Integer_Blue = 0
        Blue_Value = Current_Color * GammaFactor * Blue
        If Blue_Value > 32767 Then Blue_Value = Blue_Value - 32767: Unsigned_Integer_Blue = 1
        If Blue_Value > 32767 Then Blue_Value = 32767

        '操作位以处理无符号整数
        Gamma_Ramp.Red(Current_Color) = Red_Value Or (-32768 * Unsigned_Integer_Red)
        Gamma_Ramp.Green(Current_Color) = Green_Value Or (-32768 * Unsigned_Integer_Green)
        Gamma_Ramp.Blue(Current_Color) = Blue_Value Or (-32768 * Unsigned_Integer_Blue)
        
    Next Current_Color

    '将伽玛斜面发送到设备。 如果其中一个无效,请尝试另一个。
    
    'Call Direct3D_Device.SetGammaRamp(D3DSGR_NO_CALIBRATION, Gamma_Ramp)
    Call Direct3D_Device.SetGammaRamp(D3DSGR_CALIBRATE, Gamma_Ramp)

End Sub

Private Sub Game_Loop()

    Do While Running = True
        
        DoEvents '允许事件发生,以便程序不会锁定。
        
        '----------------------------------------------------
         'DirectX会自动为您处理帧速率
         '这使其运行(最多)与监视器一样快
'         刷新率高,因此您无需在其中添加额外的代码
'         降低循环速度并以一定数量的帧运行
         '每秒。
        '----------------------------------------------------
        
        '清除后缓冲。
        Direct3D_Device.Clear 0, ByVal 0, D3DCLEAR_TARGET, D3DColorRGBA(0, 0, 0, 0), 1#, 0
            
            Direct3D_Device.BeginScene
                
                '设置Gamma斜坡(仅在全屏模式下有效)
                DirectX8_Set_Gamma Gamma_Factor, 255, 255, 255
                
                '设置纹理
                Direct3D_Device.SetTexture 0, Texture
            
                '绘制多边形
                Direct3D_Device.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Vertex_List(0), Len(Vertex_List(0))
                
                If Fullscreen_Enabled = True Then
                
                    '绘制文本。
                    Direct3DX.DrawText Main_Font, D3DColorRGBA(255, 255, 255, 255), "按Up/Down(/)键改变Gamma值 " & vbCrLf & Gamma_Factor, Text_Rect, DT_TOP Or DT_LEFT
                
                Else
                
                    Direct3DX.DrawText Main_Font, D3DColorRGBA(255, 255, 255, 255), "仅在全屏模式下工作", Text_Rect, DT_TOP Or DT_LEFT
                
                End If
                
            Direct3D_Device.EndScene
        
        '将后缓冲区翻转到窗体窗口中。
        Direct3D_Device.Present ByVal 0, ByVal 0, 0, ByVal 0
        
    Loop

End Sub

Private Sub Close_Program()

    Running = False '这有助于程序退出游戏循环。
    
    '卸载所有DirectX对象。
    
    Set Texture = Nothing
    Set Direct3DX = Nothing
    Set Direct3D_Device = Nothing
    Set Direct3D = Nothing
    Set DirectX8 = Nothing
    
    Unload Me '卸载窗体
    
    End ''结束程序
        
        '尽管上方的Unload语句退出了程序,但是您
         '这样做后将导致自动化错误?
         'END 命令 将有助于防止这种情况,并彻底结束该应用程序。

End Sub

Private Sub Form_Activate()

    frmMain.Caption = "DirectX教程:改变Gamma值"
    
    DirectX_Initialize '初始化DirectX和Direct3D。
    
    Create_Polygon '创建多边形。
    
    Load_Texture '从文件加载纹理。
    
    Font.Name = "Arial"
    Font.Size = 14
    Set Main_Font_Description = Font
    Set Main_Font = Direct3DX.CreateFont(Direct3D_Device, Main_Font_Description.hFont)
    
    Text_Rect.Left = 20
    Text_Rect.Top = 160
    Text_Rect.Right = Text_Rect.Left + 300
    Text_Rect.bottom = Text_Rect.Top + 50
    
    Gamma_Factor = 1
    
    Running = True '全部初始化。 现在可以激活游戏循环了。
    
    Game_Loop

End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

    Select Case KeyCode
    
        Case vbKeyEscape '如果用户按Esc键则退出程序
    
            Close_Program
    
        Case vbKeyUp
        
            Gamma_Factor = Gamma_Factor + 0.01
            
        Case vbKeyDown
        
            Gamma_Factor = Gamma_Factor - 0.01
    
    End Select
    
    If Gamma_Factor >= 2 Then Gamma_Factor = 2
    If Gamma_Factor <= 0 Then Gamma_Factor = 0

End Sub

Private Sub Form_Load()

    '窗口完全加载之前将触发此事件。
    
    If MsgBox("单击“是”进入全屏(推荐)", vbQuestion Or vbYesNo, "选项") = vbYes Then Fullscreen_Enabled = True

End Sub
Private Sub Form_Unload(Cancel As Integer)

    Close_Program

End Sub

プログラム分析
1.初期化プロセス:
①前と同じようにサブルーチンを呼び出します。DirectX_Initialize'DirectXおよびDirect3Dを初期化します
②ポリゴンを作成するには、前と同じようにサブルーチンを呼び出します。Create_Polygon 'ポリゴンを作成します。
③テクスチャ画像をロードします。前と同じようにサブルーチンを呼び出します。Load_Texture 'ファイルからテクスチャをロードします。
④テキストを作成する

Font.Name = "Arial"
Font.Size = 14
Set Main_Font_Description = Font
Set Main_Font = Direct3DX.CreateFont(Direct3D_Device, Main_Font_Description.hFont)
Text_Rect.Left = 20
Text_Rect.Top = 160
Text_Rect.Right = Text_Rect.Left + 300
Text_Rect.bottom = Text_Rect.Top + 50`

⑤ガンマ値を初期化します:Gamma_Factor = 1

2.上記の初期化が完了したら、Game_Loopサブルーチンのゲームループ
に入ります。Game_Loopループで、ウィンドウフラグFullscreen_Enabledに従ってウィンドウステータスを判断します。Fullscreen_Enabled= falseの場合、プロンプト:ガンマ値を変更せずにフルスクリーンモードでのみ機能します。
それ以外の場合は、プロンプト:上/下(上/下)キーを押してガンマ値を変更します。

3. Form_KeyDown:キー検出
ESCを押した場合は、プログラムを終了し
ます。vbKeyUp(上キー)
を押した場合、ガンマ値+0.01 vbKeyDown(下キー)を押した場合、ガンマ値-0.01
ガンマ値は0の間です。 -2の間。

第4に、DirectX8_Set_Gammaサブルーチンを使用して、ガンマ値の変更を制御します。

サブルーチン宣言:DirectX8_Set_Gamma(ByVal GammaFactor As Single、Red As Integer、Green As Integer、Blue As Integer)
GammaFactorはガンマ値、Red = Red、Green = Green、Blue = Blue

①ハードウェアデバイス(グラフィックカード)がガンマ補正に対応しているか確認してください

Private Direct3D_Caps As D3DCAPS8
Direct3D_Device.GetDeviceCaps Direct3D_Caps'该函数检索指定设备的设备指定信息
If (Direct3D_Caps.Caps2 And D3DCAPS2_FULLSCREENGAMMA) <> D3DCAPS2_FULLSCREENGAMMA Then Exit Sub

サポートされていない場合は、サブルーチン呼び出しを終了します。D3DCAPS列挙型のc ++ソースコードは次のとおりです。

struct D3DCAPS8
{
	D3DDEVTYPE DeviceType;定义设备类型。
	UINT AdapterOrdinal;
	DWORD Caps, Caps2, Caps3;
	DWORD PresentationIntervals;
	DWORD CursorCaps;
	DWORD DevCaps;
	DWORD PrimitiveMiscCaps;
	DWORD RasterCaps;
	DWORD ZCmpCaps;
	DWORD SrcBlendCaps;
	DWORD DestBlendCaps;
	DWORD AlphaCmpCaps;
	DWORD ShadeCaps;
	DWORD TextureCaps;
	DWORD TextureFilterCaps;
	DWORD CubeTextureFilterCaps;
	DWORD VolumeTextureFilterCaps;
	DWORD TextureAddressCaps;
	DWORD VolumeTextureAddressCaps;
	DWORD LineCaps;
	DWORD MaxTextureWidth, MaxTextureHeight;
	DWORD MaxVolumeExtent;
	DWORD MaxTextureRepeat;
	DWORD MaxTextureAspectRatio;
	DWORD MaxAnisotropy;
	float MaxVertexW;
	float GuardBandLeft, GuardBandTop, GuardBandRight, GuardBandBottom;
	float ExtentsAdjust;
	DWORD StencilCaps;
	DWORD FVFCaps;
	DWORD TextureOpCaps;
	DWORD MaxTextureBlendStages;
	DWORD MaxSimultaneousTextures;
	DWORD VertexProcessingCaps;
	DWORD MaxActiveLights;
	DWORD MaxUserClipPlanes;
	DWORD MaxVertexBlendMatrices;
	DWORD MaxVertexBlendMatrixIndex;
	float MaxPointSize;
	DWORD MaxPrimitiveCount;
	DWORD MaxVertexIndex;
	DWORD MaxStreams;
	DWORD MaxStreamStride;
	DWORD VertexShaderVersion;
	DWORD MaxVertexShaderConst;
	DWORD PixelShaderVersion;
	float MaxPixelShaderValue;
};

②Gamma_Ramp(Gamma_Ramp)をD3DGAMMARAMP構造タイプとして定義します

Dim Gamma_Ramp As D3DGAMMARAMP

D3DGAMMARAMPの構造は次のとおりです。VB6ソースコード:

Type D3DGAMMARAMP
blue(0 To 255) As Integer
green(0 To 255) As Integer
red(0 To 255) As Integer

次に、関連する変数を定義します。

    Dim Red_Value As Long'红色值
    Dim Green_Value As Long'绿色值
    Dim Blue_Value As Long'蓝色值
    
    Dim Unsigned_Integer_Red As Long '无符号_整数_红色
    Dim Unsigned_Integer_Green As Long '无符号_整数_绿色
    Dim Unsigned_Integer_Blue As Long '无符号_整数_蓝色
    
    Dim Current_Color As Long'当前颜色

③線形ガンマランプを作成

'创建线性伽玛斜坡
    For Current_Color = 0 To 255
        
        Unsigned_Integer_Red = 0
        Red_Value = Current_Color * GammaFactor * Red
        If Red_Value > 32767 Then Red_Value = Red_Value - 32767: Unsigned_Integer_Red = 1
        If Red_Value > 32767 Then Red_Value = 32767
        
        Unsigned_Integer_Green = 0
        Green_Value = Current_Color * GammaFactor * Green
        If Green_Value > 32767 Then Green_Value = Green_Value - 32767: Unsigned_Integer_Green = 1
        If Green_Value > 32767 Then Green_Value = 32767
        
        Unsigned_Integer_Blue = 0
        Blue_Value = Current_Color * GammaFactor * Blue
        If Blue_Value > 32767 Then Blue_Value = Blue_Value - 32767: Unsigned_Integer_Blue = 1
        If Blue_Value > 32767 Then Blue_Value = 32767

        '操作位以处理无符号整数
        Gamma_Ramp.Red(Current_Color) = Red_Value Or (-32768 * Unsigned_Integer_Red)
        Gamma_Ramp.Green(Current_Color) = Green_Value Or (-32768 * Unsigned_Integer_Green)
        Gamma_Ramp.Blue(Current_Color) = Blue_Value Or (-32768 * Unsigned_Integer_Blue)
        
    Next Current_Color

④最後に、ガンマスロープをデバイスに送信します。

'将伽玛斜面发送到设备。 如果其中一个无效,请尝试另一个。
    
    'Call Direct3D_Device.SetGammaRamp(D3DSGR_NO_CALIBRATION, Gamma_Ramp)
    Call Direct3D_Device.SetGammaRamp(D3DSGR_CALIBRATE, Gamma_Ramp)

上記は、このレッスンの詳細な説明です。

おすすめ

転載: blog.csdn.net/gosub60/article/details/111205607