March 9, 2021
Hot Topics:

DirectX - An Overview - Part 2

  • By Tommy Cason
  • Send Email »
  • More Articles »

Gradients are great for title screens, high score screens or even backdrops to presentations and more conventional apps. There are more than a few ways to accomplish this through various API calls slightly creative coding, however, since we are talking about DirectDraw, lets examine a fairly painless way to make a gradient:

'(DECLARATIONS)Option ExplicitDim binit As BooleanDim dx As New DirectX7Dim dd As DirectDraw7Dim Mainsurf As DirectDrawSurface7Dim primary As DirectDrawSurface7Dim backbuffer As DirectDrawSurface7Dim ddsd1 As DDSURFACEDESC2Dim ddsd2 As DDSURFACEDESC2Dim ddsd3 As DDSURFACEDESC2Dim ddsd4 As DDSURFACEDESC2Dim brunning As BooleanDim CurModeActiveStatus As BooleanDim bRestore As BooleanPrivate Type Colour      'This is part of the gradient thing. It defines a new data type 'called Colour, like an 'integer datatype.R As Integer        'This datatype has .R .G .B sub properties.G As IntegerB As IntegerEnd TypeDim S As ColourDim E As Colour        'These 2 are used by the gradient feature, If you'type S. the little drop down menu'will have R,G,B in itSub blt()On Local Error GoTo errOutIf binit = False Then Exit SubDim ddrval As LongStatic i As IntegerDim rMain As RECTStatic tLast As SingleStatic fps As Single'this will keep us from trying to blt in case 'we lose the surfaces (alt-tab)bRestore = FalseDo Until ExModeActiveDoEventsbRestore = TrueLoopDoEventsIf bRestore ThenbRestore = Falsedd.RestoreAllSurfacesInitSurfaces 'must init the surfaces again if they were lostEnd IfrMain.Bottom = ddsd2.lHeightrMain.Right = ddsd2.lWidth'The gradient is drawn onto the MainSurf, which is then copied here:ddrval = backbuffer.BltFast(0, 0, Mainsurf, rMain, DDBLTFAST_WAIT)'Calculate the frame rateIf i = 30 ThenIf tLast <> 0 Then fps = 30 / (Timer - tLast)tLast = Timeri = 0End Ifi = i + 1Call backbuffer.DrawText(10, 10, 640x480x16 Frames per Second  + _Format$(fps, #.0), False)Call backbuffer.DrawText(10, 30, Click Screen to Exit, False)'flip the back buffer to the screenprimary.Flip Nothing, DDFLIP_WAITerrOut:End SubSub EndIt()Call dd.RestoreDisplayModeCall dd.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL)EndEnd SubFunction ExModeActive() As BooleanDim TestCoopRes As LongTestCoopRes = dd.TestCooperativeLevelIf (TestCoopRes = DD_OK) ThenExModeActive = TrueElseExModeActive = FalseEnd IfEnd FunctionSub Gradient(SR As Single, _              SG As Single, _              SB As Single, _              ER As Single, _              EG As Single, _              EB As Single, _              SurfaceWidth As Integer, _              SurfaceHeight As Integer)'Make sure this is all on the same line. Youll'understand these variables later.On Error Resume NextS.R = SR: S.G = SG: S.B = SB  '}E.R = ER: E.G = EG: E.B = EB  '}This just converts the 'variables passed to the sub into the Colour 'dataTypes.Dim d As Colour 'D is the step between colours.d.R = (E.R - S.R) / SurfaceHeightd.G = (E.G - S.G) / SurfaceHeightd.B = (E.B - S.B) / SurfaceHeight'^^ this code works out the difference between each line: 'ie add 0.25 R for each line it draws.Dim c As Colour c.R = S.R: c.G = S.G: c.B = S.B 'This is just a copy of the Start Colour.Dim x As IntegerFor x = 0 To SurfaceHeightMainsurf.SetForeColor RGB(c.R, c.G, c.B)  'Set the forecolour to the colour the gradient needs.Mainsurf.DrawLine 0, x, SurfaceWidth, x 'See above about drawing lines on a DD surface.c.R = c.R + d.Rc.G = c.G + d.Gc.B = c.B + d.BNext xEnd SubSub Init()On Local Error GoTo errOutSet dd = dx.DirectDrawCreate()Me.Show'indicate that we dont need to change display depthCall dd.SetCooperativeLevel(Me.hWnd, DDSCL_FULLSCREEN OrDDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE)    'Make this on the same line.Call dd.SetDisplayMode(640, 480, 24, 0, DDSDM_DEFAULT) 'Note: in 8Bit mode gradients will look terrible, 'in 24/32 bit they will be completely smooth. Youve got to 'see it to believe it!ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNTddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP OrDDSCAPS_COMPLEXddsd1.lBackBufferCount = 1Set primary = dd.CreateSurface(ddsd1)Dim caps As DDSCAPS2caps.lCaps = DDSCAPS_BACKBUFFERSet backbuffer = primary.GetAttachedSurface(caps)backbuffer.GetSurfaceDesc ddsd4backbuffer.SetFontTransparency Truebackbuffer.SetForeColor vbGreenInitSurfacesbinit = Truebrunning = TrueDo While brunningbltDoEventsLoop errOut:EndIt End Sub Sub InitSurfaces()Set Mainsurf = Nothingddsd2.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTHddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAINddsd2.lWidth = 640 ddsd4.lWidthddsd2.lHeight = 480 ddsd4.lHeightSet Mainsurf = dd.CreateSurface(ddsd2) 'This creates a surface without abitmap, if nothing is drawn'here you get a copy 'of the windows desktop - messed up thoughGradient 0, 0, 0, 255, 0, 0, 640, 480'    PARAMETERS:'    The first 3 are the start colour, an RGB value: in this case 0,0,0'    The next 3 are the end colour, an RGB value: in this case 255,0,0'    The next 2 are the surfaces height & Width: 640x480. 'If you only want part of the screen to be a gradient change these to 'suit your box.End Sub'These bits just link everything together. Youve seen these before.Private Sub Form_Click()    EndItEnd SubPrivate Sub Form_Load()    InitEnd SubPrivate Sub Form_Paint()    bltEnd Sub

Page 3 of 4

This article was originally published on November 20, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date