IT-Consultant: José Roca (PBWIN 10+/PBCC 6+) (Archive only) > DirectX
DirectX 9 Examples
José Roca:
Microsoft DirectX graphics provides a set of APIs that you can use to create games and other high-performance multimedia applications. DirectX graphics includes support for high-performance 2-D and 3-D graphics.
José Roca:
The following example demonstrates how to initialize Direct3D.
--- Code: ---' ########################################################################################
' Microsoft Windows
' File: CW_DX9_Initialization.bas
' Contents: DX9 example
' Description: Demonstrates how to initialize Direct3D.
' Compilers: PBWIN 10.02+, PBCC 6.02+
' Headers: Windows API headers 2.04+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk
' ########################################################################################
' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
' DirectX End-User Runtimes (June 2010)
' http://www.microsoft.com/download/en/confirmation.aspx?id=8109
$D3DX_DLLNAME = "d3dx9_43.dll" ' --> change as needed
#INCLUDE ONCE "D3DX9.INC"
$WindowCaption = "Direct3D (DX9) - Initialization"
GLOBAL pDX9 AS IDX9
' =======================================================================================
' DX9 class
' =======================================================================================
CLASS CDX9
INSTANCE m_pD3D AS IDirect3D9
INSTANCE m_pD3DDevice AS IDirect3DDevice9
INSTANCE m_d3ddm AS D3DDISPLAYMODE
INSTANCE m_d3dpp AS D3DPRESENT_PARAMETERS
' =====================================================================================
INTERFACE IDX9 : INHERIT IUnknown
' =====================================================================================
' =====================================================================================
' Initializes DirectX9
' =====================================================================================
METHOD InitD3D (BYVAL hwnd AS DWORD) AS LONG
LOCAL hr AS LONG
' // Creates an IDirect3D9 object and returns an interface to it
m_pD3D = Direct3DCreate9(%D3D_SDK_VERSION)
' // TO DO: Respond to failure of Direct3DCreate9
IF ISNOTHING(m_pD3D) THEN EXIT METHOD
' // Retrieves the current display mode of the adapter
LOCAL d3ddm AS D3DDISPLAYMODE
hr = m_pD3D.GetAdapterDisplayMode(%D3DADAPTER_DEFAULT, m_d3ddm)
' // TO DO: Respond to failure of GetAdapterDisplayMode
IF hr <> %D3D_OK THEN EXIT METHOD
hr = m_pD3D.CheckDeviceFormat(%D3DADAPTER_DEFAULT, %D3DDEVTYPE_HAL, _
d3ddm.Format, %D3DUSAGE_DEPTHSTENCIL, _
%D3DRTYPE_SURFACE, %D3DFMT_D16)
IF FAILED(hr) THEN
IF hr = %D3DERR_NOTAVAILABLE THEN
' // POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
EXIT METHOD
END IF
END IF
' // Do we support hardware vertex processing? if so, use it.
' // If not, downgrade to software.
LOCAL dCaps AS D3DCAPS9
IF FAILED(m_pD3D.GetDeviceCaps(%D3DADAPTER_DEFAULT, _
%D3DDEVTYPE_HAL, dCaps)) THEN
' // TO DO: Respond to failure of GetDeviceCaps
EXIT METHOD
END IF
LOCAL dwBehaviorFlags AS DWORD
IF dCaps.VertexProcessingCaps <> 0 THEN
dwBehaviorFlags = %D3DCREATE_HARDWARE_VERTEXPROCESSING
ELSE
dwBehaviorFlags = %D3DCREATE_SOFTWARE_VERTEXPROCESSING
END IF
' // Everything checks out - create a simple, windowed device.
' // Creates a device to represent the display adapter
m_d3dpp.Windowed = %TRUE
m_d3dpp.SwapEffect = %D3DSWAPEFFECT_DISCARD
m_d3dpp.BackBufferFormat = m_d3ddm.Format
m_d3dpp.EnableAutoDepthStencil = %TRUE
m_d3dpp.AutoDepthStencilFormat = %D3DFMT_D16
m_d3dpp.PresentationInterval = %D3DPRESENT_INTERVAL_IMMEDIATE
hr = m_pD3D.CreateDevice (%D3DADAPTER_DEFAULT, %D3DDEVTYPE_HAL, hwnd, _
%D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp, m_pD3DDevice)
' // TO DO: Respond to failure of CreateDevice
IF hr <> %D3D_OK THEN EXIT METHOD
' // Return success
METHOD = %TRUE
END METHOD
' =====================================================================================
' =====================================================================================
' Renders the scene
' =====================================================================================
METHOD RenderD3DScene
m_pD3DDevice.Clear(0, BYVAL %NULL, %D3DCLEAR_TARGET OR %D3DCLEAR_ZBUFFER, _
D3DCOLOR_COLORVALUE(0.0!,0.0!,1.0!,1.0!), 1.0!, 0)
m_pD3DDevice.BeginScene
' // Render geometry here...
m_pD3DDevice.EndScene
m_pD3DDevice.Present(BYVAL %NULL, BYVAL %NULL, %NULL, BYVAL %NULL)
END METHOD
' =====================================================================================
END INTERFACE
END CLASS
' =======================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the CWindow class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create an instance of the DX9 class
pDX9 = CLASS "CDX9"
IF ISNOTHING(pDX9) THEN EXIT FUNCTION
' // Create the main window
LOCAL hwnd AS DWORD
hwnd = pWindow.CreateWindow(%NULL, $WindowCaption, 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Change the class style to remove flicker
pWindow.ClassStyle = %CS_DBLCLKS
' // Set the client size
pWindow.SetClientSize 600, 400
' // Center the window
pWindow.CenterWindow
' // Initialize DX9
IF ISFALSE pDX9.InitD3D(hwnd) THEN EXIT FUNCTION
' // Set the timer
SetTimer(hwnd, 1, 0, %NULL)
' // Show the window
ShowWindow hwnd, nCmdShow
UpdateWindow hwnd
' // Message loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
' // Kill the timer
KillTimer(hwnd, 1)
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure callback
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
STATIC pWindow AS IWindow ' // Reference to the IWindow interface
SELECT CASE wMsg
CASE %WM_CREATE
' // Get a reference to the IWindow interface from the CREATESTRUCT structure
pWindow = CWindow_GetObjectFromCreateStruct(lParam)
EXIT FUNCTION
CASE %WM_SYSCOMMAND
' // Disable the Windows screensaver
IF (wParam AND &HFFF0) = %SC_SCREENSAVE THEN EXIT FUNCTION
' // Close the window
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_TIMER
' // Render the scene
pDX9.RenderD3DScene
EXIT FUNCTION
CASE %WM_KEYDOWN
SELECT CASE LO(WORD, wParam)
CASE %VK_ESCAPE
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END SELECT
CASE %WM_DESTROY
' // Destroy the class
pDX9 = NOTHING
' // Close the application by sending a WM_QUIT message
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
--- End code ---
José Roca:
Demonstrates how to perform alpha-blending in the frame-buffer. The sample renders a textured cube which is alpha-blended into the frame-buffer in such a way as to create a translucent effect.
--- Code: ---' ########################################################################################
' Microsoft Windows
' File: CW_DX9_AlphaBlendingFrameBuffer.bas
' Contents: DX9 example
' Description: Demonstrates how to perform alpha-blending in the frame-buffer. The sample
' renders a textured cube which is alpha-blended into the frame-buffer in such a way as to
' create a translucent effect.
' Compilers: PBWIN 10.02+, PBCC 6.02+
' Headers: Windows API headers 2.04+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk
' Adapted from dx9_alpha_blending_framebuffer.cpp, by Kevin Harris, 25 Mar 2005,
' downloadable at http://www.codesampler.com/dx9src/dx9src_4.htm#dx9_alpha_blending_framebuffer
' Control Keys: b - Toggle blending
' ########################################################################################
' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
' DirectX End-User Runtimes (June 2010)
' http://www.microsoft.com/download/en/confirmation.aspx?id=8109
$D3DX_DLLNAME = "d3dx9_43.dll" ' --> change as needed
#INCLUDE ONCE "D3DX9.INC"
$WindowCaption = "Direct3D (DX9) - Alpha Blending with the Frame Buffer"
%D3DFVF_CUSTOMVERTEX = %D3DFVF_XYZ OR %D3DFVF_TEX1
TYPE Vertex
x AS SINGLE
y AS SINGLE
z AS SINGLE
tu AS SINGLE
tv AS SINGLE
END TYPE
' ========================================================================================
' Fills a Vertex structure
' ========================================================================================
MACRO FillVertex (v, x_, y_, z_, tu_, tv_)
v.x = x_ : v.y = y_ : v.z = z_ : v.tu = tu_ : v.tv = tv_
END MACRO
' ========================================================================================
GLOBAL pDX9 AS IDX9
' =======================================================================================
' DX9 class
' =======================================================================================
CLASS CDX9
INSTANCE m_pD3D AS IDirect3D9
INSTANCE m_pD3DDevice AS IDirect3DDevice9
INSTANCE m_d3ddm AS D3DDISPLAYMODE
INSTANCE m_d3dpp AS D3DPRESENT_PARAMETERS
INSTANCE m_pVertexBuffer AS IDirect3DVertexBuffer9
INSTANCE m_pTexture AS IDirect3DTexture9
INSTANCE m_bBlending AS LONG
INSTANCE m_quadVertices () AS Vertex
' ====================================================================================
' Initializes the vertex array
' ====================================================================================
CLASS METHOD Create
m_bBlending = -1
DIM m_quadVertices(23) AS INSTANCE Vertex
FillVertex(m_quadVertices( 0), -1.0!, 1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 1), 1.0!, 1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 2), -1.0!, -1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices( 3), 1.0!, -1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices( 4), -1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 5), -1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices( 6), 1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 7), 1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices( 8), -1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 9), 1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(10), -1.0!, 1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(11), 1.0!, 1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(12), -1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(13), -1.0!, -1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(14), 1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(15), 1.0!, -1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(16), 1.0!, 1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(17), 1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(18), 1.0!, -1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(19), 1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(20), -1.0!, 1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(21), -1.0!, -1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(22), -1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(23), -1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
END METHOD
' ====================================================================================
' =====================================================================================
INTERFACE IDX9 : INHERIT IUnknown
' =====================================================================================
' =====================================================================================
' Initializes DirectX9
' =====================================================================================
METHOD InitD3D (BYVAL hwnd AS DWORD) AS LONG
LOCAL hr AS LONG
' // Creates an IDirect3D9 object and returns an interface to it
m_pD3D = Direct3DCreate9(%D3D_SDK_VERSION)
IF ISNOTHING(m_pD3D) THEN EXIT METHOD
' // Retrieves the current display mode of the adapter
hr = m_pD3D.GetAdapterDisplayMode(%D3DADAPTER_DEFAULT, m_d3ddm)
IF hr <> %D3D_OK THEN EXIT METHOD
' // Creates a device to represent the display adapter
m_d3dpp.Windowed = %TRUE
m_d3dpp.SwapEffect = %D3DSWAPEFFECT_DISCARD
m_d3dpp.BackBufferFormat = m_d3ddm.Format
m_d3dpp.EnableAutoDepthStencil = %TRUE
m_d3dpp.AutoDepthStencilFormat = %D3DFMT_D16
m_d3dpp.PresentationInterval = %D3DPRESENT_INTERVAL_IMMEDIATE
hr = m_pD3D.CreateDevice (%D3DADAPTER_DEFAULT, %D3DDEVTYPE_HAL, hwnd, _
%D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp, m_pD3DDevice)
IF hr <> %D3D_OK THEN EXIT METHOD
'// Create the device objects
ME.CreateDeviceObjects
' // Return success
METHOD = %TRUE
END METHOD
' =====================================================================================
' =====================================================================================
' Loads the texture and creates the vertex buffers
' =====================================================================================
METHOD CreateDeviceObjects () AS LONG
' // Loads the texture
D3DXCreateTextureFromFile(m_pD3DDevice, ".\Resources\Glass.bmp", m_pTexture)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MINFILTER, %D3DTEXF_LINEAR)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MAGFILTER, %D3DTEXF_LINEAR)
' // Creates a vertex buffer
LOCAL nSize AS LONG
LOCAL pVertices AS Vertex PTR
nSize = (UBOUND(m_quadVertices) - LBOUND(m_quadVertices) + 1) * SIZEOF(Vertex)
m_pD3DDevice.CreateVertexBuffer(nSize, 0, %D3DFVF_CUSTOMVERTEX, %D3DPOOL_DEFAULT, m_pVertexBuffer, %NULL)
m_pVertexBuffer.Lock(0, nSize, pVertices, 0)
MoveMemory BYVAL pVertices, BYVAL VARPTR(m_quadVertices(0)), nSize
m_pVertexBuffer.Unlock
' // Sets a device render-state parameter
m_pD3DDevice.SetRenderState(%D3DRS_LIGHTING, %FALSE)
' // Builds a left-handed perspective projection matrix based on a field of view
LOCAL matProj AS D3DXMATRIX
D3DXMatrixPerspectiveFovLH(matProj, D3DXToRadian(45.0!), 600.0! / 400.0!, 0.1!, 100.0!)
' // Sets a device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_PROJECTION, matProj)
' // Return success
METHOD = %S_OK
END METHOD
' =====================================================================================
' =====================================================================================
' Renders the scene
' =====================================================================================
METHOD RenderD3DScene
LOCAL hr AS LONG
STATIC fXrot AS SINGLE
STATIC fYrot AS SINGLE
STATIC fZrot AS SINGLE
STATIC fElpasedTime AS SINGLE
STATIC dCurrentTime AS DOUBLE
STATIC dLastTime AS DOUBLE
dCurrentTime = timeGetTime
fElpasedTime = (dCurrentTime - dLastTime) * 0.001
dLastTime = dCurrentTime
fXrot = fXrot + 10.1! * fElpasedTime
fYrot = fYrot + 10.2! * fElpasedTime
fZrot = fZrot + 10.3! * fElpasedTime
' // Clears the surface
m_pD3DDevice.Clear(0, BYVAL %NULL, %D3DCLEAR_TARGET OR %D3DCLEAR_ZBUFFER, _
D3DCOLOR_COLORVALUE(0.0!,0.0!,0.0!,1.0!), 1.0!, 0)
LOCAL matWorld AS D3DXMATRIX
LOCAL matTrans AS D3DXMATRIX
LOCAL matRot AS D3DXMATRIX
' // Builds a matrix using the specified offsets
D3DXMatrixTranslation(matTrans, 0.0!, 0.0!, 5.0!)
' // Builds a matrix with a specified yaw, pitch, and roll
D3DXMatrixRotationYawPitchRoll(matRot, D3DXToRadian(fXrot), D3DXToRadian(fYrot), D3DXToRadian(fZrot))
' // Determines the product of the two matrices
D3DXMatrixMultiply(matWorld, matRot, matTrans)
' // Sets the device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_WORLD, matWorld)
' // Begins the scene
m_pD3DDevice.BeginScene
IF ISTRUE m_bBlending THEN
' // Sets the device render-state parameters
m_pD3DDevice.SetRenderState(%D3DRS_CULLMODE, %D3DCULL_NONE)
m_pD3DDevice.SetRenderState(%D3DRS_ZENABLE, %FALSE)
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %TRUE)
m_pD3DDevice.SetRenderState(%D3DRS_SRCBLEND, %D3DBLEND_SRCALPHA)
m_pD3DDevice.SetRenderState(%D3DRS_DESTBLEND, %D3DBLEND_ONE)
ELSE
' // Sets the device render-state parameters
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %FALSE)
m_pD3DDevice.SetRenderState(%D3DRS_ZENABLE, %TRUE)
END IF
' // Assigns the texture to a stage for the device
m_pD3DDevice.SetTexture(0, m_pTexture)
' // Binds a vertex buffer to a device data stream
m_pD3DDevice.SetStreamSource(0, m_pVertexBuffer, 0, SIZEOF(Vertex))
' // Sets the current vertex stream declaration
m_pD3DDevice.SetFVF(%D3DFVF_CUSTOMVERTEX)
' // Renders a sequence of nonindexed, geometric primitives of the
' // specified type from the current set of data input streams.
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
' // Ends the scene
m_pD3DDevice.EndScene
' // Presents the contents of the next buffer in the sequence of back buffers owned by the device
hr = m_pD3DDevice.Present(BYVAL %NULL, BYVAL %NULL, %NULL, BYVAL %NULL)
IF hr = %D3DERR_DEVICELOST THEN
' // The application can determine what to do on encountering a lost device
' // by querying the return value of the TestCooperativeLevel method.
hr = m_pD3DDevice.TestCooperativeLevel
IF hr = %D3DERR_DEVICENOTRESET THEN
' // Invalidate the device objects
m_pVertexBuffer = NOTHING
m_pTexture = NOTHING
' // Reset the type, size, and format of the swap chain
m_pD3DDevice.Reset(m_d3dpp)
' // Recreate the device objects
ME.CreateDeviceObjects
END IF
END IF
END METHOD
' =====================================================================================
' ====================================================================================
' Processes keystrokes
' ====================================================================================
METHOD ProcessKeys (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG)
SELECT CASE wMsg
CASE %WM_CHAR
SELECT CASE wParam
CASE 66, 98 ' B, b
m_bBlending = NOT m_bBlending
CASE %VK_ESCAPE
SendMessage hwnd, %WM_CLOSE, 0, 0
END SELECT
END SELECT
END METHOD
' ====================================================================================
END INTERFACE
END CLASS
' =======================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI Aware
' SetProcessDPIAware
' // Create an instance of the DX9 class
pDX9 = CLASS "CDX9"
IF ISNOTHING(pDX9) THEN EXIT FUNCTION
' // Create an instance of the CWindow class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
LOCAL hwnd AS DWORD
hwnd = pWindow.CreateWindow(%NULL, $WindowCaption, 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Change the class style to remove flicker
pWindow.ClassStyle = %CS_DBLCLKS
' // Set the client size
pWindow.SetClientSize 600, 400
' // Center the window
pWindow.CenterWindow
' // Initialize DX9
IF ISFALSE pDX9.InitD3D(hwnd) THEN EXIT FUNCTION
' // Set the timer
SetTimer(hwnd, 1, 0, %NULL)
' // Show the window
ShowWindow hwnd, nCmdShow
UpdateWindow hwnd
' // Message loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
' // Kill the timer
KillTimer(hwnd, 1)
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure callback
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
SELECT CASE wMsg
CASE %WM_SYSCOMMAND
' // Disable the Windows screensaver
IF (wParam AND &HFFF0) = %SC_SCREENSAVE THEN EXIT FUNCTION
' // Close the window
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_TIMER
' // Render the scene
pDX9.RenderD3DScene
EXIT FUNCTION
CASE %WM_CHAR
pDX9.ProcessKeys hwnd, wMsg, wParam, lParam
EXIT FUNCTION
CASE %WM_DESTROY
' // Destroy the class
pDX9 = NOTHING
' // Close the application by sending a WM_QUIT message
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
--- End code ---
José Roca:
Demonstrates how to perform alpha-blending using a material. This alpha-blending technique is widely used to make entire objects fade out of existence over some amount of time.
--- Code: ---' ########################################################################################
' Microsoft Windows
' File: CW_DX9_AlphaBlendingMaterial.bas
' Contents: DX9 example
' Description: Demonstrates how to perform alpha-blending using a material.
' This alpha-blending technique is widely used to make entire objects fade out of
' existence over some amount of time.
' Compilers: PBWIN 10.02+, PBCC 6.02+
' Headers: Windows API headers 2.04+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk
' Adapted from dx9_alpha_blending_material.cpp by Kevin Harris, 04/04/05, available at
' http://www.codesampler.com/dx9src/dx9src_4.htm#dx9_alpha_blending_material
' Control Keys: b - Toggle blending
' a - Reduce alpha on the materials Diffuse color
' A - Increase alpha on the materials Diffuse color
' ########################################################################################
' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
' DirectX End-User Runtimes (June 2010)
' http://www.microsoft.com/download/en/confirmation.aspx?id=8109
$D3DX_DLLNAME = "d3dx9_43.dll" ' --> change as needed
#INCLUDE ONCE "D3DX9.INC"
$WindowCaption = "Direct3D (DX9) - Alpha Blending with a Material"
%FVF_Flags = %D3DFVF_XYZ OR %D3DFVF_NORMAL OR %D3DFVF_TEX1
TYPE Vertex
x AS SINGLE
y AS SINGLE
z AS SINGLE
nx AS SINGLE
ny AS SINGLE
nz AS SINGLE
tu AS SINGLE
tv AS SINGLE
END TYPE
' ========================================================================================
' Fills a Vertex structure
' ========================================================================================
MACRO FillVertex (v, x_, y_, z_, nx_, ny_, nz_, tu_, tv_)
v.x = x_ : v.y = y_ : v.z = z_ : v.nx = nx_ : v.ny = ny_ : v.nz = nz_ : v.tu = tu_ : v.tv = tv_
END MACRO
' ========================================================================================
GLOBAL pDX9 AS IDX9
' =======================================================================================
' DX9 class
' =======================================================================================
CLASS CDX9
INSTANCE m_pD3D AS IDirect3D9
INSTANCE m_pD3DDevice AS IDirect3DDevice9
INSTANCE m_d3ddm AS D3DDISPLAYMODE
INSTANCE m_d3dpp AS D3DPRESENT_PARAMETERS
INSTANCE m_pVertexBuffer AS IDirect3DVertexBuffer9
INSTANCE m_pTexture AS IDirect3DTexture9
INSTANCE m_alphaMaterial AS D3DMATERIAL9
INSTANCE m_bBlending AS LONG
INSTANCE m_quadVertices () AS Vertex
INSTANCE m_fDistance AS SINGLE
INSTANCE m_fSpinX AS SINGLE
INSTANCE m_fSpinY AS SINGLE
' ====================================================================================
' Initializes the vertex array
' ====================================================================================
CLASS METHOD Create
m_bBlending = -1
m_fDistance = 4.5!
DIM m_quadVertices(23) AS INSTANCE Vertex
' // Front Face
FillVertex(m_quadVertices( 0), -1.0!, 1.0!, -1.0!, 0.0!, 0.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 1), 1.0!, 1.0!, -1.0!, 0.0!, 0.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 2), -1.0!, -1.0!, -1.0!, 0.0!, 0.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices( 3), 1.0!, -1.0!, -1.0!, 0.0!, 0.0!, -1.0!, 1.0!, 1.0!)
' // Back Face
FillVertex(m_quadVertices( 4), -1.0!, 1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 5), -1.0!, -1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices( 6), 1.0!, 1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 7), 1.0!, -1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 0.0!, 1.0!)
' // Top Face
FillVertex(m_quadVertices( 8), -1.0!, 1.0!, 1.0!, 0.0!, 1.0!, 0.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 9), 1.0!, 1.0!, 1.0!, 0.0!, 1.0!, 0.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(10), -1.0!, 1.0!, -1.0!, 0.0!, 1.0!, 0.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(11), 1.0!, 1.0!, -1.0!, 0.0!, 1.0!, 0.0!, 1.0!, 1.0!)
' // Bottom Face
FillVertex(m_quadVertices(12), -1.0!, -1.0!, 1.0!, 0.0!, -1.0!, 0.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(13), -1.0!, -1.0!, -1.0!, 0.0!, -1.0!, 0.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(14), 1.0!, -1.0!, 1.0!, 0.0!, -1.0!, 0.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(15), 1.0!, -1.0!, -1.0!, 0.0!, -1.0!, 0.0!, 1.0!, 0.0!)
' // Right Face
FillVertex(m_quadVertices(16), 1.0!, 1.0!, -1.0!, 1.0!, 0.0!, 0.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(17), 1.0!, 1.0!, 1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(18), 1.0!, -1.0!, -1.0!, 1.0!, 0.0!, 0.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(19), 1.0!, -1.0!, 1.0!, 1.0!, 0.0!, 0.0!, 1.0!, 1.0!)
' // Left Face
FillVertex(m_quadVertices(20), -1.0!, 1.0!, -1.0!, -1.0!, 0.0!, 0.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(21), -1.0!, -1.0!, -1.0!, -1.0!, 0.0!, 0.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(22), -1.0!, 1.0!, 1.0!, -1.0!, 0.0!, 0.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(23), -1.0!, -1.0!, 1.0!, -1.0!, 0.0!, 0.0!, 0.0!, 1.0!)
END METHOD
' ====================================================================================
' =====================================================================================
INTERFACE IDX9 : INHERIT IUnknown
' =====================================================================================
' =====================================================================================
' Initializes DirectX9
' =====================================================================================
METHOD InitD3D (BYVAL hwnd AS DWORD) AS LONG
LOCAL hr AS LONG
' // Creates an IDirect3D9 object and returns an interface to it
m_pD3D = Direct3DCreate9(%D3D_SDK_VERSION)
IF ISNOTHING(m_pD3D) THEN EXIT METHOD
' // Retrieves the current display mode of the adapter
hr = m_pD3D.GetAdapterDisplayMode(%D3DADAPTER_DEFAULT, m_d3ddm)
IF hr <> %D3D_OK THEN EXIT METHOD
' // Creates a device to represent the display adapter
m_d3dpp.Windowed = %TRUE
m_d3dpp.SwapEffect = %D3DSWAPEFFECT_DISCARD
m_d3dpp.BackBufferFormat = m_d3ddm.Format
m_d3dpp.EnableAutoDepthStencil = %TRUE
m_d3dpp.AutoDepthStencilFormat = %D3DFMT_D16
m_d3dpp.PresentationInterval = %D3DPRESENT_INTERVAL_IMMEDIATE
hr = m_pD3D.CreateDevice (%D3DADAPTER_DEFAULT, %D3DDEVTYPE_HAL, hwnd, _
%D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp, m_pD3DDevice)
IF hr <> %D3D_OK THEN EXIT METHOD
'// Create the device objects
ME.CreateDeviceObjects
' // Return success
METHOD = %TRUE
END METHOD
' =====================================================================================
' =====================================================================================
' Loads the texture and creates the vertex buffers
' =====================================================================================
METHOD CreateDeviceObjects () AS LONG
' // Loads the texture
D3DXCreateTextureFromFile(m_pD3DDevice, ".\Resources\Glass.bmp", m_pTexture)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MINFILTER, %D3DTEXF_LINEAR)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MAGFILTER, %D3DTEXF_LINEAR)
' // Creates a vertex buffer
LOCAL nSize AS LONG
LOCAL pVertices AS Vertex PTR
nSize = (UBOUND(m_quadVertices) - LBOUND(m_quadVertices) + 1) * SIZEOF(Vertex)
m_pD3DDevice.CreateVertexBuffer(nSize, 0, %FVF_Flags, %D3DPOOL_DEFAULT, m_pVertexBuffer, %NULL)
m_pVertexBuffer.Lock(0, nSize, pVertices, 0)
MoveMemory BYVAL pVertices, BYVAL VARPTR(m_quadVertices(0)), nSize
m_pVertexBuffer.Unlock
' // Sets a device render-state parameter
m_pD3DDevice.SetRenderState(%D3DRS_LIGHTING, %TRUE)
' // Builds a left-handed perspective projection matrix based on a field of view
LOCAL matProj AS D3DXMATRIX
D3DXMatrixPerspectiveFovLH(matProj, D3DXToRadian(45.0!), 600.0! / 400.0!, 0.1!, 100.0!)
' // Sets a device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_PROJECTION, matProj)
' // Set up our alpha material...
m_alphaMaterial.Diffuse.r = 1.0!
m_alphaMaterial.Diffuse.g = 1.0!
m_alphaMaterial.Diffuse.b = 1.0!
m_alphaMaterial.Diffuse.a = 0.5!
m_pD3DDevice.SetMaterial(m_alphaMaterial)
' // Set light 0 to be a pure white directional light
LOCAL light0 AS D3DLIGHT9
light0.Type = %D3DLIGHT_DIRECTIONAL
light0.Direction.x = 0.0!
light0.Direction.y = 0.0!
light0.Direction.z = 1.0!
light0.Diffuse.r = 1.0!
light0.Diffuse.g = 1.0!
light0.Diffuse.b = 1.0!
light0.Diffuse.a = 1.0!
m_pD3DDevice.SetLight(0, light0)
m_pD3DDevice.LightEnable(0, %TRUE)
' // Return success
METHOD = %S_OK
END METHOD
' =====================================================================================
' =====================================================================================
' Renders the scene
' =====================================================================================
METHOD RenderD3DScene
LOCAL hr AS LONG
' // Clears the surface
m_pD3DDevice.Clear(0, BYVAL %NULL, %D3DCLEAR_TARGET OR %D3DCLEAR_ZBUFFER, _
D3DCOLOR_COLORVALUE(0.35!,0.53!,0.7!,1.0!), 1.0!, 0)
LOCAL matWorld AS D3DXMATRIX
LOCAL matTrans AS D3DXMATRIX
LOCAL matRot AS D3DXMATRIX
' // Builds a matrix using the specified offsets
D3DXMatrixTranslation(matTrans, 0.0!, 0.0!, m_fDistance)
' // Builds a matrix with a specified yaw, pitch, and roll
D3DXMatrixRotationYawPitchRoll(matRot, D3DXToRadian(m_fSpinX), D3DXToRadian(m_fSpinY), 0.0!)
' // Determines the product of the two matrices
D3DXMatrixMultiply(matWorld, matRot, matTrans)
' // Sets the device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_WORLD, matWorld)
' // Begins the scene
m_pD3DDevice.BeginScene
IF ISTRUE m_bBlending THEN
' // Sets the device render-state parameters
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %TRUE)
m_pD3DDevice.SetMaterial(m_alphaMaterial)
' // Use material's alpha
m_pD3DDevice.SetRenderState(%D3DRS_DIFFUSEMATERIALSOURCE, %D3DMCS_MATERIAL)
m_pD3DDevice.SetTextureStageState(0, %D3DTSS_ALPHAARG1, %D3DTA_DIFFUSE)
m_pD3DDevice.SetTextureStageState(0, %D3DTSS_ALPHAOP, %D3DTOP_SELECTARG1)
' // Use alpha for transparency
m_pD3DDevice.SetRenderState(%D3DRS_SRCBLEND, %D3DBLEND_SRCALPHA)
m_pD3DDevice.SetRenderState(%D3DRS_DESTBLEND, %D3DBLEND_INVSRCALPHA)
ELSE
' // Sets the device render-state parameters
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %FALSE)
END IF
' // Render the cube
m_pD3DDevice.SetTexture(0, m_pTexture)
m_pD3DDevice.SetStreamSource(0, m_pVertexBuffer, 0, SIZEOF(Vertex))
m_pD3DDevice.SetFVF(%FVF_Flags)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
' // Ends the scene
m_pD3DDevice.EndScene
' // Presents the contents of the next buffer in the sequence of back buffers owned by the device
hr = m_pD3DDevice.Present(BYVAL %NULL, BYVAL %NULL, %NULL, BYVAL %NULL)
IF hr = %D3DERR_DEVICELOST THEN
' // The application can determine what to do on encountering a lost device
' // by querying the return value of the TestCooperativeLevel method.
hr = m_pD3DDevice.TestCooperativeLevel
IF hr = %D3DERR_DEVICENOTRESET THEN
' // Invalidate the device objects
m_pVertexBuffer = NOTHING
m_pTexture = NOTHING
' // Reset the type, size, and format of the swap chain
m_pD3DDevice.Reset(m_d3dpp)
' // Recreate the device objects
ME.CreateDeviceObjects
END IF
END IF
END METHOD
' =====================================================================================
' ====================================================================================
' Processes keystrokes
' ====================================================================================
METHOD ProcessKeys (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG)
SELECT CASE wMsg
CASE %WM_CHAR
SELECT CASE wParam
CASE 66, 98 ' B, b
m_bBlending = NOT m_bBlending
CASE 97 ' a
m_alphaMaterial.Diffuse.a = m_alphaMaterial.Diffuse.a - 0.1!
CASE 65 ' A
m_alphaMaterial.Diffuse.a = m_alphaMaterial.Diffuse.a + 0.1!
END SELECT
CASE %WM_KEYDOWN
SELECT CASE LO(WORD, wParam)
CASE %VK_ESCAPE
SendMessage hwnd, %WM_CLOSE, 0, 0
CASE 38 ' // Up Arrow Key
m_fDistance = m_fDistance - 0.1!
CASE 40 ' // Down Arrow Key
m_fDistance = m_fDistance + 0.1!
END SELECT
END SELECT
END METHOD
' ====================================================================================
' ====================================================================================
' Processes mouse
' ====================================================================================
METHOD ProcessMouse (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG)
STATIC ptLastMousePosit AS POINT
STATIC ptCurrentMousePosit AS POINT
STATIC bMousing AS LONG
SELECT CASE wMsg
CASE %WM_LBUTTONDOWN
ptLastMousePosit.x = LO(WORD, lParam)
ptCurrentMousePosit.x = LO(WORD, lParam)
ptLastMousePosit.y = HI(WORD, lParam)
ptCurrentMousePosit.y = HI(WORD, lParam)
bMousing = %TRUE
CASE %WM_LBUTTONUP
bMousing = %FALSE
CASE %WM_MOUSEMOVE
ptCurrentMousePosit.x = LO(WORD, lParam)
ptCurrentMousePosit.y = HI(WORD, lParam)
IF bMousing THEN
m_fSpinX = m_fSpinX - (ptCurrentMousePosit.x - ptLastMousePosit.x)
m_fSpinY = m_fSpinY - (ptCurrentMousePosit.y - ptLastMousePosit.y)
END IF
ptLastMousePosit.x = ptCurrentMousePosit.x
ptLastMousePosit.y = ptCurrentMousePosit.y
END SELECT
END METHOD
' ====================================================================================
END INTERFACE
END CLASS
' =======================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI Aware
' SetProcessDPIAware
' // Create an instance of the DX9 class
pDX9 = CLASS "CDX9"
IF ISNOTHING(pDX9) THEN EXIT FUNCTION
' // Create an instance of the CWindow class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
LOCAL hwnd AS DWORD
hwnd = pWindow.CreateWindow(%NULL, $WindowCaption, 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Change the class style to remove flicker
pWindow.ClassStyle = %CS_DBLCLKS
' // Set the client size
pWindow.SetClientSize 600, 400
' // Center the window
pWindow.CenterWindow
' // Initialize DX9
IF ISFALSE pDX9.InitD3D(hwnd) THEN EXIT FUNCTION
' // Set the timer
SetTimer(hwnd, 1, 0, %NULL)
' // Show the window
ShowWindow hwnd, nCmdShow
UpdateWindow hwnd
' // Message loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
' // Kill the timer
KillTimer(hwnd, 1)
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure callback
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
SELECT CASE wMsg
CASE %WM_SYSCOMMAND
' // Disable the Windows screensaver
IF (wParam AND &HFFF0) = %SC_SCREENSAVE THEN EXIT FUNCTION
' // Close the window
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_TIMER
' // Render the scene
pDX9.RenderD3DScene
EXIT FUNCTION
CASE %WM_CHAR, %WM_KEYDOWN, %WM_KEYUP
pDX9.ProcessKeys hwnd, wMsg, wParam, lParam
EXIT FUNCTION
CASE %WM_LBUTTONDOWN, %WM_LBUTTONUP, %WM_MOUSEMOVE
pDX9.ProcessMouse hwnd, wMsg, wParam, lParam
EXIT FUNCTION
CASE %WM_DESTROY
' // Destroy the class
pDX9 = NOTHING
' // Close the application by sending a WM_QUIT message
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
--- End code ---
José Roca:
Demonstrates how to perform alpha blending using the alpha channel of a standard .tga texture. For proper alpha blending, the sample uses a cull-mode sorting trick to ensure the sides of the textured cube get rendered in back-to-front order.
--- Code: ---' ########################################################################################
' Microsoft Windows
' File: CW_DX9_AlphaBlendingTexture.bas
' Contents: DX9 example
' Description: Demonstrates how to perform alpha blending using the alpha channel of a
' standard .tga texture. For proper alpha blending, the sample uses a cull-mode sorting trick
' to ensure the sides of the textured cube get rendered in back-to-front order.
' Compilers: PBWIN 10.02+, PBCC 6.02+
' Headers: Windows API headers 2.04+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk
' Adapted from dx9_alpha_blending_texture.cpp by Kevin Harris, 03/27/05, available at
' http://www.codesampler.com/dx9src/dx9src_4.htm#dx9_alpha_blending_texture
' Control Keys: b - Toggle blending
' s - Toggle usage of cull-mode sorting trick
' Up Arrow - Move the test cube closer
' Down Arrow - Move the test cube away
' ########################################################################################
' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1
#INCLUDE ONCE "CWindow.inc"
' DirectX End-User Runtimes (June 2010)
' http://www.microsoft.com/download/en/confirmation.aspx?id=8109
$D3DX_DLLNAME = "d3dx9_43.dll" ' --> change as needed
#INCLUDE ONCE "D3DX9.INC"
$WindowCaption = "Direct3D (DX9) - Texture Alpha Blending"
%FVF_Flags = %D3DFVF_XYZ OR %D3DFVF_TEX1
TYPE Vertex
x AS SINGLE
y AS SINGLE
z AS SINGLE
tu AS SINGLE
tv AS SINGLE
END TYPE
' ========================================================================================
' Fills a Vertex structure
' ========================================================================================
MACRO FillVertex (v, x_, y_, z_, tu_, tv_)
v.x = x_ : v.y = y_ : v.z = z_ : v.tu = tu_ : v.tv = tv_
END MACRO
' ========================================================================================
GLOBAL pDX9 AS IDX9
' =======================================================================================
' DX9 class
' =======================================================================================
CLASS CDX9
INSTANCE m_pD3D AS IDirect3D9
INSTANCE m_pD3DDevice AS IDirect3DDevice9
INSTANCE m_d3ddm AS D3DDISPLAYMODE
INSTANCE m_d3dpp AS D3DPRESENT_PARAMETERS
INSTANCE m_pVertexBuffer AS IDirect3DVertexBuffer9
INSTANCE m_pTexture AS IDirect3DTexture9
INSTANCE m_alphaMaterial AS D3DMATERIAL9
INSTANCE m_bBlending AS LONG
INSTANCE m_quadVertices () AS Vertex
INSTANCE m_fDistance AS SINGLE
INSTANCE m_fSpinX AS SINGLE
INSTANCE m_fSpinY AS SINGLE
INSTANCE m_bSortUsingCullModeTrick AS LONG
' ====================================================================================
' Initializes the vertex array
' ====================================================================================
CLASS METHOD Create
m_bBlending = -1
m_bSortUsingCullModeTrick = -1
m_fDistance = 4.5!
DIM m_quadVertices(23) AS INSTANCE Vertex
FillVertex(m_quadVertices( 0), -1.0!, 1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 1), 1.0!, 1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 2), -1.0!, -1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices( 3), 1.0!, -1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices( 4), -1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices( 5), -1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices( 6), 1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 7), 1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices( 8), -1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices( 9), 1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(10), -1.0!, 1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(11), 1.0!, 1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(12), -1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(13), -1.0!, -1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(14), 1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(15), 1.0!, -1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(16), 1.0!, 1.0!, -1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(17), 1.0!, 1.0!, 1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(18), 1.0!, -1.0!, -1.0!, 0.0!, 1.0!)
FillVertex(m_quadVertices(19), 1.0!, -1.0!, 1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(20), -1.0!, 1.0!, -1.0!, 1.0!, 0.0!)
FillVertex(m_quadVertices(21), -1.0!, -1.0!, -1.0!, 1.0!, 1.0!)
FillVertex(m_quadVertices(22), -1.0!, 1.0!, 1.0!, 0.0!, 0.0!)
FillVertex(m_quadVertices(23), -1.0!, -1.0!, 1.0!, 0.0!, 1.0!)
END METHOD
' ====================================================================================
' =====================================================================================
INTERFACE IDX9 : INHERIT IUnknown
' =====================================================================================
' =====================================================================================
' Initializes DirectX9
' =====================================================================================
METHOD InitD3D (BYVAL hwnd AS DWORD) AS LONG
LOCAL hr AS LONG
' // Creates an IDirect3D9 object and returns an interface to it
m_pD3D = Direct3DCreate9(%D3D_SDK_VERSION)
IF ISNOTHING(m_pD3D) THEN EXIT METHOD
' // Retrieves the current display mode of the adapter
hr = m_pD3D.GetAdapterDisplayMode(%D3DADAPTER_DEFAULT, m_d3ddm)
IF hr <> %D3D_OK THEN EXIT METHOD
' // Creates a device to represent the display adapter
m_d3dpp.Windowed = %TRUE
m_d3dpp.SwapEffect = %D3DSWAPEFFECT_DISCARD
m_d3dpp.BackBufferFormat = m_d3ddm.Format
m_d3dpp.EnableAutoDepthStencil = %TRUE
m_d3dpp.AutoDepthStencilFormat = %D3DFMT_D16
m_d3dpp.PresentationInterval = %D3DPRESENT_INTERVAL_IMMEDIATE
hr = m_pD3D.CreateDevice (%D3DADAPTER_DEFAULT, %D3DDEVTYPE_HAL, hwnd, _
%D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp, m_pD3DDevice)
IF hr <> %D3D_OK THEN EXIT METHOD
'// Create the device objects
ME.CreateDeviceObjects
' // Return success
METHOD = %TRUE
END METHOD
' =====================================================================================
' =====================================================================================
' Loads the texture and creates the vertex buffers
' =====================================================================================
METHOD CreateDeviceObjects () AS LONG
' // Loads the texture
D3DXCreateTextureFromFile(m_pD3DDevice, ".\Resources\Radiation_Box.tga", m_pTexture)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MINFILTER, %D3DTEXF_LINEAR)
m_pD3DDevice.SetSamplerState(0, %D3DSAMP_MAGFILTER, %D3DTEXF_LINEAR)
' // Creates a vertex buffer
LOCAL nSize AS LONG
LOCAL pVertices AS Vertex PTR
nSize = (UBOUND(m_quadVertices) - LBOUND(m_quadVertices) + 1) * SIZEOF(Vertex)
m_pD3DDevice.CreateVertexBuffer(nSize, 0, %FVF_Flags, %D3DPOOL_DEFAULT, m_pVertexBuffer, %NULL)
m_pVertexBuffer.Lock(0, nSize, pVertices, 0)
MoveMemory BYVAL pVertices, BYVAL VARPTR(m_quadVertices(0)), nSize
m_pVertexBuffer.Unlock
' // Sets a device render-state parameter
m_pD3DDevice.SetRenderState(%D3DRS_LIGHTING, %FALSE)
m_pD3DDevice.SetRenderState(%D3DRS_CULLMODE, %D3DCULL_NONE)
' // Builds a left-handed perspective projection matrix based on a field of view
LOCAL matProj AS D3DXMATRIX
D3DXMatrixPerspectiveFovLH(matProj, D3DXToRadian(45.0!), 600.0! / 400.0!, 0.1!, 100.0!)
' // Sets a device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_PROJECTION, matProj)
' // Return success
METHOD = %S_OK
END METHOD
' =====================================================================================
' =====================================================================================
' Renders the scene
' =====================================================================================
METHOD RenderD3DScene
LOCAL hr AS LONG
' // Clears the surface
m_pD3DDevice.Clear(0, BYVAL %NULL, %D3DCLEAR_TARGET OR %D3DCLEAR_ZBUFFER, _
D3DCOLOR_COLORVALUE(0.35!,0.53!,0.7!,1.0!), 1.0!, 0)
LOCAL matWorld AS D3DXMATRIX
LOCAL matTrans AS D3DXMATRIX
LOCAL matRot AS D3DXMATRIX
' // Builds a matrix using the specified offsets
D3DXMatrixTranslation(matTrans, 0.0!, 0.0!, m_fDistance)
' // Builds a matrix with a specified yaw, pitch, and roll
D3DXMatrixRotationYawPitchRoll(matRot, D3DXToRadian(m_fSpinX), D3DXToRadian(m_fSpinY), 0.0!)
' // Determines the product of the two matrices
D3DXMatrixMultiply(matWorld, matRot, matTrans)
' // Sets the device transformation-related state
m_pD3DDevice.SetTransform(%D3DTS_WORLD, matWorld)
' // Begins the scene
m_pD3DDevice.BeginScene
' // Transparency sorting for our cube...
' //
' // If you have a single transparent object, or multiple transparent objects
' // which do not overlap in screen space (i.e., each screen pixel is touched
' // by at most one of the transparent objects), there's a sorting short-cut
' // which can be used under certain conditions.
' //
' // If your transparent objects are closed, convex, and viewed from the
' // outside, culling may be used to draw the back-facing polygons prior to
' // the front-facing polygons. This will accomplish the same thing
' // as sorting your objects or polygons into back-to-front order.
' // Fortunately for us, our cube is a perfect candidate for this sorting
' // trick.
' //
' // On the other hand, If we can't use the cull-mode sorting trick, we would
' // need to sort our objects manually, which would require us to transform
' // the geometry into eye-space so we could compare their final position
' // along the z axis. Only then, could we could render them in the proper
' // back-to-front order for alpha blending.
' //
' // Also, if transparent objects intersect in any way, the individual
' // triangles of the objects touching will have to be sorted and drawn
' // individually from back-to-front. And is some rare cases, triangles that
' // intersect each other may have to be broken into smaller triangles so they
' // no longer intersect or blending artifacts will persist regardless of our
' // sorting efforts.
' //
' // It’s plain to see, transparency sorting can become a big, hairy mess real quick.
' //
' // http://www.opengl.org/resources/tutorials/sig99/advanced99/notes/node204.html
IF ISTRUE m_bBlending THEN
' // Use the texture's alpha channel to blend it with whatever’s already in the frame-buffer.
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %TRUE)
m_pD3DDevice.SetRenderState(%D3DRS_SRCBLEND, %D3DBLEND_SRCALPHA)
m_pD3DDevice.SetRenderState(%D3DRS_DESTBLEND, %D3DBLEND_INVSRCALPHA)
m_pD3DDevice.SetTexture(0, m_pTexture)
m_pD3DDevice.SetStreamSource(0, m_pVertexBuffer, 0, SIZEOF(Vertex))
m_pD3DDevice.SetFVF(%FVF_Flags)
IF m_bSortUsingCullModeTrick THEN
' // Use the cull-mode sorting trick for convex non-overlapping geometry.
' // Render the cube but only render the back-facing polygons.
m_pD3DDevice.SetRenderState(%D3DRS_CULLMODE, %D3DCULL_CW)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
' // Render the cube again, but this time we only render the front-facing polygons.
m_pD3DDevice.SetRenderState(%D3DRS_CULLMODE, %D3DCULL_CCW)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
ELSE
' // Do no sorting and hope for the best. From certain viewing
' // positions the cube's sides will appear sorted correctly, but this
' // is typically rare and the cube will not look right most of the
' // time.
m_pD3DDevice.SetRenderState(%D3DRS_CULLMODE, %D3DCULL_NONE)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
END IF
ELSE
' // Render the cube, but do no blending...
m_pD3DDevice.SetRenderState(%D3DRS_ALPHABLENDENABLE, %FALSE)
m_pD3DDevice.SetRenderState(%D3DRS_ZENABLE, %TRUE)
m_pD3DDevice.SetTexture(0, m_pTexture)
m_pD3DDevice.SetStreamSource(0, m_pVertexBuffer, 0, SIZEOF(Vertex))
m_pD3DDevice.SetFVF(%FVF_Flags)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 0, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 4, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 8, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 12, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 16, 2)
m_pD3DDevice.DrawPrimitive(%D3DPT_TRIANGLESTRIP, 20, 2)
END IF
' // Ends the scene
m_pD3DDevice.EndScene
' // Presents the contents of the next buffer in the sequence of back buffers owned by the device
hr = m_pD3DDevice.Present(BYVAL %NULL, BYVAL %NULL, %NULL, BYVAL %NULL)
IF hr = %D3DERR_DEVICELOST THEN
' // The application can determine what to do on encountering a lost device
' // by querying the return value of the TestCooperativeLevel method.
hr = m_pD3DDevice.TestCooperativeLevel
IF hr = %D3DERR_DEVICENOTRESET THEN
' // Invalidate the device objects
m_pVertexBuffer = NOTHING
m_pTexture = NOTHING
' // Reset the type, size, and format of the swap chain
m_pD3DDevice.Reset(m_d3dpp)
' // Recreate the device objects
ME.CreateDeviceObjects
END IF
END IF
END METHOD
' =====================================================================================
' ====================================================================================
' Processes keystrokes
' ====================================================================================
METHOD ProcessKeys (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG)
SELECT CASE wMsg
CASE %WM_CHAR
SELECT CASE wParam
CASE 66, 98 ' B, b
m_bBlending = NOT m_bBlending
CASE 83, 115 ' S, s
m_bSortUsingCullModeTrick = NOT m_bSortUsingCullModeTrick
END SELECT
CASE %WM_KEYDOWN
SELECT CASE LO(WORD, wParam)
CASE %VK_ESCAPE
SendMessage hwnd, %WM_CLOSE, 0, 0
CASE 38 ' // Up Arrow Key
m_fDistance = m_fDistance - 0.1!
CASE 40 ' // Down Arrow Key
m_fDistance = m_fDistance + 0.1!
END SELECT
END SELECT
END METHOD
' ====================================================================================
' ====================================================================================
' Processes mouse
' ====================================================================================
METHOD ProcessMouse (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG)
STATIC ptLastMousePosit AS POINT
STATIC ptCurrentMousePosit AS POINT
STATIC bMousing AS LONG
SELECT CASE wMsg
CASE %WM_LBUTTONDOWN
ptLastMousePosit.x = LO(WORD, lParam)
ptCurrentMousePosit.x = LO(WORD, lParam)
ptLastMousePosit.y = HI(WORD, lParam)
ptCurrentMousePosit.y = HI(WORD, lParam)
bMousing = %TRUE
CASE %WM_LBUTTONUP
bMousing = %FALSE
CASE %WM_MOUSEMOVE
ptCurrentMousePosit.x = LO(WORD, lParam)
ptCurrentMousePosit.y = HI(WORD, lParam)
IF bMousing THEN
m_fSpinX = m_fSpinX - (ptCurrentMousePosit.x - ptLastMousePosit.x)
m_fSpinY = m_fSpinY - (ptCurrentMousePosit.y - ptLastMousePosit.y)
END IF
ptLastMousePosit.x = ptCurrentMousePosit.x
ptLastMousePosit.y = ptCurrentMousePosit.y
END SELECT
END METHOD
' ====================================================================================
END INTERFACE
END CLASS
' =======================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Set process DPI Aware
' SetProcessDPIAware
' // Create an instance of the DX9 class
pDX9 = CLASS "CDX9"
IF ISNOTHING(pDX9) THEN EXIT FUNCTION
' // Create an instance of the CWindow class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
LOCAL hwnd AS DWORD
hwnd = pWindow.CreateWindow(%NULL, $WindowCaption, 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
' // Change the class style to remove flicker
pWindow.ClassStyle = %CS_DBLCLKS
' // Set the client size
pWindow.SetClientSize 600, 400
' // Center the window
pWindow.CenterWindow
' // Initialize DX9
IF ISFALSE pDX9.InitD3D(hwnd) THEN EXIT FUNCTION
' // Set the timer
SetTimer(hwnd, 1, 0, %NULL)
' // Show the window
ShowWindow hwnd, nCmdShow
UpdateWindow hwnd
' // Message loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
TranslateMessage uMsg
DispatchMessage uMsg
WEND
' // Kill the timer
KillTimer(hwnd, 1)
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main window procedure callback
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
SELECT CASE wMsg
CASE %WM_SYSCOMMAND
' // Disable the Windows screensaver
IF (wParam AND &HFFF0) = %SC_SCREENSAVE THEN EXIT FUNCTION
' // Close the window
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_TIMER
' // Render the scene
pDX9.RenderD3DScene
EXIT FUNCTION
CASE %WM_CHAR, %WM_KEYDOWN, %WM_KEYUP
pDX9.ProcessKeys hwnd, wMsg, wParam, lParam
EXIT FUNCTION
CASE %WM_LBUTTONDOWN, %WM_LBUTTONUP, %WM_MOUSEMOVE
pDX9.ProcessMouse hwnd, wMsg, wParam, lParam
EXIT FUNCTION
CASE %WM_DESTROY
' // Destroy the class
pDX9 = NOTHING
' // Close the application by sending a WM_QUIT message
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
--- End code ---
Navigation
[0] Message Index
[#] Next page
Go to full version