游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7297|回复: 18

DX7下如何实现半透明?

[复制链接]

7

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2005-9-1 16:43:00 | 显示全部楼层 |阅读模式
DX7下如何实现半透明?
能否直接获取一个表面上一点的颜色值?
游戏中的半透明一般都是如何实现的?

0

主题

46

帖子

46

积分

注册会员

Rank: 2

积分
46
发表于 2005-9-1 22:35:00 | 显示全部楼层

Re:DX7下如何实现半透明?

alpha混合

187

主题

600

帖子

606

积分

高级会员

Rank: 4

积分
606
QQ
发表于 2005-9-3 09:09:00 | 显示全部楼层

Re:DX7下如何实现半透明?

DX7本身不支持的,需要自己写,但是VB语言不是很适合写这些低级的东西,建议你用d3d或者使用专门的api函数,我记得2k下就有alpha混合的函数,速度还可以的

7

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
 楼主| 发表于 2005-9-4 11:45:00 | 显示全部楼层

Re:DX7下如何实现半透明?

谁有例子?

187

主题

600

帖子

606

积分

高级会员

Rank: 4

积分
606
QQ
发表于 2005-9-4 12:44:00 | 显示全部楼层

Re:DX7下如何实现半透明?

API  AlphaBlend函数:具体请参考MSDN

32

主题

1583

帖子

1589

积分

金牌会员

Rank: 6Rank: 6

积分
1589
发表于 2005-9-4 13:17:00 | 显示全部楼层

Re:DX7下如何实现半透明?

Alpha混合和直接获取表面的颜色都是先Lock表面,然后修改内存。

VB实现半透明一般只有三个方法:Win32API+图象处理,DDraw7+与高效语言混编,D3DSprite。

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-9-7 10:13:00 | 显示全部楼层

Re:DX7下如何实现半透明?

Option Explicit
'//* 'NOTE THIS SAMPLES SHOWS HOW TO BLIT TO AREAS OF THE SCREEN
'//* '声明 ( 场所他们在声明断面的相同模组中)
'//*  ************************最好过程名,不用下划线命名*********************
Private Type My_Surface
    DDSface7 As DirectDrawSurface7
    iWidth As Integer
    iHeight As Integer
    iIndex As Integer
    BitMask As Byte
    D3d As Byte
End Type '//* BitMask=0 为 False,D3d=255 为 True
   
'//*  ****************  DIRECTDRAW   ************************************
    Public dx As New DirectX7
    Public DD As DirectDraw7             '//* The DirectDraw7 object
    Dim ClipperObj As DirectDrawClipper '//*   裁剪器
    Dim ClipperObj0 As DirectDrawClipper '//*   裁剪器
    Public Primary As DirectDrawSurface7         '//* 最初的表面 (荧屏)
    Public BackBuffer As DirectDrawSurface7      '//* 背景缓冲表面 (存储器)
    Public BackGround() As My_Surface
    Public Sprite() As My_Surface '//*  声名一个 精灵 为了 自定 Surface

    Dim rBack As RECT
    Private EmptyRect As RECT
'//*  ********************** DIRECT3D  *************************
    Public D3d As Direct3D7         'Direct3D 立即的模态物件  The Direct3D Immediate Mode object
    Dim Dev As Direct3DDevice7
    'Dim LIGHT As D3DLIGHT7

'//*  **********   伽?刂  ***********************************
    Private GammaControler As DirectDrawGammaControl
    Private GammaRamp As DDGAMMARAMP
    Private OriginalRamp As DDGAMMARAMP
    Private GammaSupport As Boolean
'//* ----------------------------------------------------------
        Public gT_Dx_Start_Ok As Boolean '//*  Dx 系统运行正常
        Public gI_Dx_FPS_Revise As Integer '//*  Dx FPS 刷新修正 Revise
        Public T_Timer As Single
        Public FPS As Integer              'Holds the number of frames per second
'//********************             **************  以上为变量常数区  *******************
'//* ----------------  主过程说明  --------------------
'//* DisplaySurface_0D0  一般显示 无透明、不自动裁减(手动位置、大小)
'//* DisplaySurface_0D1  一般显示 透明、不自动裁减(手动位置、大小)
'//* DisplaySurface_1D0  地面(0层) 无特效、无透明  可自动裁减,使用Revise_0(修正)区域修正
'//* DisplaySurface_1D1  地面(1层) 无特效、透明  可自动裁减,使用Revise_0(修正)区域修正
'//* DisplaySurface_2D0  天空(4层) 特效、透明  可自动裁减,使用Revise_0(修正)区域修正
'//* DisplaySurface_2D1  人物(2,3层) 特效、透明  可自动裁减,使用Revise(修正)区域修正

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-9-7 10:13:00 | 显示全部楼层

Re:DX7下如何实现半透明?

Sub Run_FPS() '//*  这个过程是重要的
   On Error Resume Next
    'Static i As Integer
    Static mlngTimer As Long           '----}
    Static mlngFrameTimer As Long      '    }  Used to calculate the Frames per second
    Static mintFPSCounter As Integer   '----}

'//*  *
        mlngTimer = dx.TickCount() 'DX.TickCount
        If dx.TickCount() - mlngFrameTimer >= 1000 Then
            mlngFrameTimer = dx.TickCount() 'DX.TickCount
            FPS = mintFPSCounter
            mintFPSCounter = 0
        Else
            mintFPSCounter = mintFPSCounter + 1
        End If
      If (FPS >= 81) Then gI_Dx_FPS_Revise = -2
      If (FPS <= 80) And (FPS >= 61) Then gI_Dx_FPS_Revise = -1 '42
      If (FPS <= 60) And (FPS >= 37) Then gI_Dx_FPS_Revise = 0 '42
      If (FPS <= 36) And (FPS >= 26) Then gI_Dx_FPS_Revise = 1 '30
      If (FPS <= 25) And (FPS >= 19) Then gI_Dx_FPS_Revise = 3 '25
      If (FPS <= 18) And (FPS >= 16) Then gI_Dx_FPS_Revise = 5 '18
      If (FPS <= 15) And (FPS >= 11) Then gI_Dx_FPS_Revise = 8 '15
      If (FPS <= 10) Then gI_Dx_FPS_Revise = 11 '10
    '//*  -------------------------Frames per Second = FPS
    Call DxDDraw.DisplayString(3, 350, 5, gE_formScreen.ScreenWidth & "x" & gE_formScreen.ScreenHeight & "x16Bit FPS " & FPS & " Timer " & Timer)
    Call DxDDraw.DisplayString(1, 10, 90, "Click Screen to Exit")
End Sub





'------------------------------------------------------
Sub InitDirectDraw(Optional hWnd As Long = 0, Optional iWidth As Integer = 640, _
   Optional iHeight As Integer = 480, Optional BPP As Byte = 16) '//*  等于 Init()
   
     Call Err_Msg_Log.AppendToLog("初始化 DX.DirectDraw", True, False) '//*  调试用过程
     
   On Local Error GoTo ErrOut
     Set DD = dx.DirectDrawCreate("")
     Call Err_Msg_Log.CheckComputer(False) '//*  调试用过程系统性能
      If hWnd = 0 Then hWnd = gL_mFromHwnd
'//* ' 产生 DirectDraw, 放置独家的 coopeerative 水平而且设定电视的模态。
'//* '指出我们 dont 需要改变展览深度  'indicate that we dont need to change display depth
''    DD.SetCooperativeLevel frmMain.hWnd, DDSCL_NORMAL Or DDSCL_NOWINDOWCHANGES
    Call DD.SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN Or DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)
    Call DD.SetDisplayMode(iWidth, iHeight, BPP, 0, DDSDM_DEFAULT)   '设分辨率 800 X 600
    Call Err_Msg_Log.AppendToLog("设分辨率 宽:" & iWidth & " 高:" & iHeight & " 色:" & BPP, True, True)  '//*  调试用过程
    EmptyRect.Top = 0
    EmptyRect.Bottom = EmptyRect.Top + iHeight
    EmptyRect.Left = 0
    EmptyRect.Right = EmptyRect.Left + iWidth

      Exit Sub
ErrOut:
    Call Err_Msg_Log.AT_Error_Run("无法对DirectDraw进行初始化", Err.Number)
'//*  DDSCL_FULLSCREEN 使用全?幕?必?和DDSCL_EXCLUSIVE一起用?
'//*  DDSCL_ALLOWMODEX 使用Modex模式
'//*  DDSCL_EXCLUSIVE 使用??啄J
'//*  DDSCL_NORMAL 使用Windows的程式?窗
'//*  DDSCL_NOWINDOWCHANGES 禁止改??窗大小
End Sub


Function ExModeActive() As Boolean '//* DX 主运行窗口是否被最小化,不在焦点
    Dim TestCoopRes As Long
    TestCoopRes = DD.TestCooperativeLevel
    If (TestCoopRes = DD_OK) Then
        ExModeActive = True
    Else
        ExModeActive = False
    End If
End Function

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-9-7 10:14:00 | 显示全部楼层

Re:DX7下如何实现半透明?

'//* ********************************************************************************
'//* *                              (第一个调用)                                    *
'//* *   创建主表面和后备表面;                                                     *
'//* *   三缓冲(Triple Buffering)                                                   *
'//* *   在某些情况下,那就是,当显示适配器拥有足够的内存,那么,                       *
'//* *   你就可以使用三缓冲区(Triple Buffering)来加速你的应用程序的显示速度.        *
'//* *   三缓冲区使用一个主页面(primary surface)和两个后台缓存(back buffers)        *
'//* *   .DDSD1.lBackBufferCount = 1 <--- 2时 为三缓冲                              *
'//* *                                                                              *
'//* ********************************************************************************
Sub SetPrimarySurface() '//*  也拿表面给荧屏并且产生一个后面的缓冲 (第一个调用)
   Dim ddsd As DDSURFACEDESC2  '//*  最初的表面 (荧屏)
   On Local Error GoTo Err_OutPri
'//*  Flags 在 ddsd 中 那一个成员被用做有效 书第 116 页
    ddsd.lFlags = DDSD_BACKBUFFERCOUNT Or DDSD_CAPS    'DDSD1.lFlags = DDSD_CAPS
    ddsd.ddsCaps.lCaps = DDSCAPS_COMPLEX Or DDSCAPS_FLIP Or DDSCAPS_3DDEVICE Or DDSCAPS_PRIMARYSURFACE
    'DDSD.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX Or DDSCAPS_3DDEVICE   ' Or DDSCAPS_VIDEOMEMORY
    'DDSD.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE ' Or DDSCAPS_VIDEOMEMORY
    ddsd.lBackBufferCount = 2 '//*  书第 116 页 有关于用 内存还是显存的方法
    Set Primary = DD.CreateSurface(ddsd)
       Call Err_Msg_Log.AppendToLog("CreatePrimarySurface ... Ok", True, True) '//*  调试用过程
     Exit Sub
Err_OutPri:
   Call Err_Msg_Log.AT_Error_Run("SetPrimarySurface 设置错误:" & Err.Number, Err.Number)
   Exit Sub
End Sub

'//* **************************************************
'//* *      设置背景绘图平面的字体和颜色              *
'//* **************************************************
Sub DisplayString(Optional Color As Byte, _
   Optional Xf As Integer, Optional Yf As Integer, _
   Optional sText As String)
'//* ==========  下面是新加的 原程式
      '//* Create DrawableSurface class form backbuffer
      '//*  产生 DrawableSurface 类别模型背景缓冲
     BackBuffer.SetFontTransparency True
      Select Case (Color)
       Case 0
                BackBuffer.SetForeColor vbBlack   '&H0 黑色
       Case 1
                BackBuffer.SetForeColor vbRed '&HFF 红色
       Case 2
                BackBuffer.SetForeColor vbGreen '&HFF00 绿色
       Case 3
                BackBuffer.SetForeColor vbYellow '&HFFFF 黄色
       Case 4
                BackBuffer.SetForeColor vbBlue '&HFF0000 兰色
       Case 5
                BackBuffer.SetForeColor vbMagenta '&HFF00FF 洋红
       Case 6
                BackBuffer.SetForeColor vbCyan '&HFFFF00 青色
       Case 7
                BackBuffer.SetForeColor vbWhite
       Case Else
                BackBuffer.SetForeColor vbGreen    '//* 不选就是 绿色
'//* 这上面的过程可能会影响速度,因为用的判断
     End Select
'//*       设置背景绘图平面的字体和颜色
'//*  BackSurf.SetForeColor RGB(255, 255, 255)
'//*  Form1.Font.Name = "宋体"
     BackBuffer.SetFont g_XFont
     BackBuffer.DrawText Xf, Yf, sText, False
     'Call Err_Msg_Log.AppendToLog("设置背景绘图平面的字体和颜色", True, True)
End Sub

22

主题

209

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2005-9-7 10:14:00 | 显示全部楼层

Re:DX7下如何实现半透明?

Sub SetBackBufferSurface() '//* ''产生主要的缓冲    'Get the backbuffer
    Dim caps As DDSCAPS2
    Dim DEnum As Direct3DEnumDevices
    Dim GUID As String
   On Local Error GoTo Err_OutBuffer
   
    caps.lCaps = DDSCAPS_BACKBUFFER Or DDSCAPS_3DDEVICE  '新程式
    Set BackBuffer = Primary.GetAttachedSurface(caps)
    '    BackBuffer.GetSurfaceDesc DDSD1
'//*  -----------------------------------
    Set D3d = DD.GetDirect3D
    Set DEnum = D3d.GetDevicesEnum
    GUID = DEnum.GetGuid(DEnum.GetCount)
    Set Dev = D3d.CreateDevice(GUID, BackBuffer) 'Set Dev = D3D.CreateDevice("IID_IDirect3DHALDevice", BackBuffer)
'//*  安装那描绘选择项   双线性的材质过滤 - 变得比较好.....
'//*  进行这些目前的设定允许 blendind 工作好像它是 lightmap 。。。
    '//* you can change D3DBLEND_ONE, check the DX7 SDK for other values
'    Dev.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR '//* 这两行是边缘柔化
'    Dev.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTFN_LINEAR '//* 这两行是边缘柔化
       Dev.SetRenderState D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE 'D3DBLEND_SRCCOLOR
       Dev.SetRenderState D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE
    Call Err_Msg_Log.AppendToLog("CreateBackBufferSurface ... Ok", True, True) '//*  调试用过程
    Exit Sub
Err_OutBuffer:
   Call Err_Msg_Log.AT_Error_Run("SetBackBufferSurface 设置错误:" & Err.Number, Err.Number)
   Exit Sub
End Sub


Sub SetClipAndTransparency(Optional hWnd As Long = 0) '//*   裁剪器 过程
   If hWnd = 0 Then hWnd = gL_mFromHwnd
   ' Dim rBack As RECT
   'On Local Error GoTo Err_OutClip
    Set ClipperObj = DD.CreateClipper(0)
    'Set ClipperObj0 = DD.CreateClipper(0) '//*  这个是多的(有错)
    ClipperObj.SetHWnd hWnd
'//*  <DirectDraw原理与API参考 P101页
    Primary.SetClipper ClipperObj
    'BackBuffer.SetClipper ClipperObj'//*  这个是多的(有错)
''     Call Dx.GetWindowRect(hWnd, destRect)
   
'        rBack.Bottom = 600:rBack.Right = 800
'        Primary.BltFast 0, 0, Primary, rBack, DDBLTFAST_WAIT
    Call Err_Msg_Log.AppendToLog("设置裁剪器 始发... Ok", True, True) '//*  调试用过程
    Exit Sub
Err_OutClip:
   Call Err_Msg_Log.AT_Error_Run("裁剪器 设置错误:" & Err.Number, Err.Number)
   Exit Sub
End Sub
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 02:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表