News   Articles   Sources   Code libraries    RSS

Language:

English   Russia  

Current filter:

All   C#   C++   C  



Log in:

Name
Pass

Register

Network Security Developer

Initializing Direct3D. Part 1.


Language:C++
Category:Multimedia
Date: 2009-01-12
Author:Network Security Developer
Attachment:Download

In this article we will take a look at initializing Direct3D. To make the discussion more interesting an example application will be created and then its capabilities will be considered.

Select the File | New | Project menu sequence, and in the left pane, select the New Project dialog window open Visual C++ Projects | Win32. In the right pane, select the Win32 Project item. Specify the name of the project in the Name field and the path in the folder, in which you want to store it in the Location field.

 Create a new Direct3D project
Create a new Direct3D project

Click the OK button to open the Win32 Application Wizard window. Click the Application Settings tab, and select the Windows application radio button in the Application type group. Leave all checkboxes untouched. Click the Finish button to create a basic application. Don't forget to include the necessary libraries in the project properties. For more information read Installing and Configuring DirectX. Now clean the project of all unnecessary code. First of all, remove the code of creating and sowing the Help dialog box.

The perfect location for initializing Direct3D is right after the InitInstance function, which creates and displays the window. But first you must decide how the initialization process will be implemented. Because this is one-time operation, performed only at the start of the application, it can be implemented as a separate universal function.

Because the Direct3D initialization code for several Direct3D applications at your work or home experience may be identical, it can be contained in a module. Start by creating the dxfunc.cpp file for the source code of functions. And the related dxfunc.h header file. The contents of the dxfunc.h header file are:

#ifndef _DDFUNC_H_
#define _DDFUNC_H_

#include "ddraw.h"

// Функция инициализации Direct3D
HRESULT DXDDInit(IDirectDraw7 **ppiDD, 
        IDirectDrawSurface7 **primsurf,
        IDirectDrawSurface7 **backsurf,
        HWND hWnd, 
        DWORD iWidth,
        DWORD iHeight,
        WORD iColors,
        BOOL &bFullScreen
   );

#endif

In the file, the DX3DInit Direct3D initialization function is declared. Its parameters are the following:

  • ppiD3D9 of the IDirect3D9 type – a pointer for storing version 9 of the IDirect3D interface
  • ppiD3DDevice of the IDirect3DDevice9 type – a pointer to the pointer for storing version 9 of the IDirect3DDevice interface.
  • hWnd – the window, in which the Direct3D scene will be displayed.
  • iWidth and iHeight – the width and height of the window
  • bFullScene – a parameter specifying whether the program should be run in the full-screen mode. If the value is true, the program switches into the full-screen mode right away; otherwise, the user is allowed to choose the necessary mode. Direct3D applications are most often created to run in the full-screen mode without window mode support. It's because these two modes operate somewhat differently. Thus, if this parameter is true, the window mode will not be offered.

Write the code for calling the Direct3D initialization function in the DirectX skeleton, and then the function itself. In the main module, declare two variables for storing the created IDirect3D9 interface and the IDirect3DDevice9 device:

IDirect3D9 *pD3D = NULL;
IDirect3DDevice9 *pD3DDevice = NULL;

The initialization function is called in the InitInstance function after creating the window but before displaying and refreshing the main window:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   if (DX3DInit(&pD3D, &pD3DDevice, hWnd, 800, 600, FALSE)!=S_OK)
   {
     MessageBox(hWnd, "Initialization error", "Error", MB_OK);	   
     return FALSE;
   }

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

   return TRUE;
}

Why must the function be called exactly in this place? You are creating a universal initialization function, which will be called with the help of a dialog window regardless of whether or not initialization should be performed the full screen mode. You must take into account that after the Direct3D initialization all dialog windows will be displayed incorrectly, if they are displayed at all. This problem is not difficult to solve; the window should simply be displayed before any Direct3D initialization.

But there is another problem: why display and redraw an initialized window? This makes no sense, because during the Direct3D initialization the window's parameters change and the 3D scene will have to be redrawn. Even though these are one-time operations, processor time is wasted on the preliminary window redrawing.

If your program is supposed to work in both the window and the full-screen modes, this is only a plus. For example, on my wide-screen notebook some graphics programs don't appear well in the full screen mode. This problem is taken care of by running them in the window mode, since the powerful video card allows this. But if a program does not offer the window mode, the image is stretched a bit horizontally.

Now let's consider the contents of the dxfunc.cpp file:

#include "dxfunc.h"

HRESULT DX3DInit(IDirect3D9 **ppiD3D9, 
                IDirect3DDevice9 **ppiD3DDevice9,
                HWND hWnd, 
				DWORD iWidth,
				DWORD iHeight,
				BOOL bFullScreen)
{
  if((*ppiD3D9 = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
    return E_FAIL;

  D3DPRESENT_PARAMETERS d3dpp;
  ZeroMemory(&d3dpp, sizeof(d3dpp));

  d3dpp.BackBufferWidth = iWidth;
  d3dpp.BackBufferHeight = iHeight;

  int  iRes;
  if (!bFullScreen)
      iRes=MessageBox(hWnd, "Use fullscreen mode?", "Screen", MB_YESNO | MB_ICONQUESTION);
  else
	  iRes = IDYES;


  if(iRes == IDYES)
  {
    //////////////////////////////////////////////////////////
    // Full screen
    //////////////////////////////////////////////////////////
    d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
    d3dpp.SwapEffect       = D3DSWAPEFFECT_FLIP;
    d3dpp.Windowed         = FALSE;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  } 
  else 
  {
    //////////////////////////////////////////////////////////
    //  Window Mode
    //////////////////////////////////////////////////////////
    RECT wndRect;
    RECT clientRect;
    GetWindowRect(hWnd, &wndRect);
    GetClientRect(hWnd, &clientRect);	  

    iWidth  = iWidth + (wndRect.right-wndRect.left)  - (clientRect.right-clientRect.left);
    iHeight = iHeight + (wndRect.bottom-wndRect.top) - (clientRect.bottom-clientRect.top);

    MoveWindow(hWnd, wndRect.left, wndRect.top, iWidth, iHeight, TRUE);

    // get pixel format
    D3DDISPLAYMODE d3ddm;
    (*ppiD3D9)->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

    // set parameters
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed         = TRUE;
  }
  
  DWORD Flags= D3DCREATE_MIXED_VERTEXPROCESSING;

  HRESULT hRes;
  if(FAILED(hRes = (*ppiD3D9)->CreateDevice(
	  D3DADAPTER_DEFAULT, 
	  D3DDEVTYPE_HAL, hWnd, Flags, 
	  &d3dpp, ppiD3DDevice9)))
	  return hRes;

  float Aspect = (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight;
  D3DXMATRIX matProjection;
  D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4.0f, Aspect, 0.001f, 1000.0f);
  (*ppiD3DDevice9)->SetTransform(D3DTS_PROJECTION, &matProjection);

  (*ppiD3DDevice9)->SetRenderState(D3DRS_LIGHTING, FALSE);

  return S_OK;
}

To be continued...

Download Attachment


Send your comment

Your name:
Vote:
Title:
Comment:
Protection code:





Submit an article   Submit a file

Copyright © HackishCode.com 2008. All rights reserved
WEB Design and WEB Development by WEB consulting company ProfWebDev.com
www.hackishcode.com