• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Lesson 2: Making game in C++
#1
Rainbow 
Hey again,

Click HERE for first lesson.

Today i will tell about Direct3D basics and introducting to D3D.

Introducting to Direct3D

Now i'll tell you, how to make initilization of Direct3D and Direct3D device.
Note: You must install DirectX SDK 2010, as i said in first lesson.

There's our code, which just creates empty window -
Code:
#include <windows.h>    
#include <windowsx.h>

// required
#include "stdafx.h"

// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";

// screen data
int SCREEN_WIDTH;
int SCREEN_HEIGHT;

int SCREEN_POS_X;
int SCREEN_POS_Y;

LPCWSTR WIN_TITLE;

LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int ShowCmd)
{

    // size of window
    SCREEN_WIDTH = 1024;
    SCREEN_HEIGHT = 768;
    // position of window
    SCREEN_POS_X = 0;
    SCREEN_POS_Y = 0;

    // title of the window
    WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )


    // Window creation
    MSG msg;
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
                    WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+3),
                    NULL, WIN_MAIN, NULL};

    RegisterClassEx(&wc);

    // create new window
    HWND hMainWnd = CreateWindow(WIN_MAIN,
                                WIN_TITLE,
                                WS_OVERLAPPEDWINDOW, SCREEN_POS_X, SCREEN_POS_Y, SCREEN_WIDTH, SCREEN_HEIGHT,

                                NULL, NULL, hInstance, NULL);
    // show it
    ShowWindow(hMainWnd, ShowCmd);
    UpdateWindow(hMainWnd);

    // real time loop
    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        // game loop can be there

        if(msg.message == WM_QUIT)
            break;

        // game loop can be there // recommended there
    }

   return(0);
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return(0);
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

Lets do something in it now!
Now we need to load d3d data into our window. That what i will use:

As you see, this line of code is loading d3d header and data.
Code:
#include <d3d9.h>

Also, we need to add library file.
Code:
#pragma comment (lib, "d3d9.lib")

Now we must setup global variables for d3d device and initilization.
Code:
LPDIRECT3D9 d3dinit;    // d3d interface init
LPDIRECT3DDEVICE9 d3ddevice;    // d3d device init

Lets set some functions now.
Code:
void R_Init(HWND hWnd);    // Initialize d3d device
void R_Frame(void);    // rendering
void CleanD3D(void);    // clear display before showing

You will have this code:
Code:
#include <windows.h>    
#include <windowsx.h>

// required
#include "stdafx.h"

// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";

// screen data
int SCREEN_WIDTH;
int SCREEN_HEIGHT;

int SCREEN_POS_X;
int SCREEN_POS_Y;

LPCWSTR WIN_TITLE;

#include <d3d9.h>
#pragma comment (lib, "d3d9.lib")

LPDIRECT3D9 d3dinit;    // d3d interface init
LPDIRECT3DDEVICE9 d3ddevice;    // d3d device init

void R_Init(HWND hWnd);    // Initialize d3d device
void R_Frame(void);    // rendering
void CleanD3D(void);    // clear display before showing


LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int ShowCmd)
{

    // size of window
    SCREEN_WIDTH = 1024;
    SCREEN_HEIGHT = 768;
    // position of window
    SCREEN_POS_X = 0;
    SCREEN_POS_Y = 0;

    // title of the window
    WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )


    // Window creation
    MSG msg;
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
                    WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+3),
                    NULL, WIN_MAIN, NULL};

    RegisterClassEx(&wc);

    // create new window
    HWND hMainWnd = CreateWindow(WIN_MAIN,
                                WIN_TITLE,
                                WS_OVERLAPPEDWINDOW, SCREEN_POS_X, SCREEN_POS_Y, SCREEN_WIDTH, SCREEN_HEIGHT,

                                NULL, NULL, hInstance, NULL);
    // show it
    ShowWindow(hMainWnd, ShowCmd);
    UpdateWindow(hMainWnd);

    // real time loop
    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        // game loop can be there

        if(msg.message == WM_QUIT)
            break;

        // game loop can be there // recommended there
    }

   return(0);
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return(0);
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

Okay, now we need to setup and initialize Direct3D stuff.

D3D stuff initialization

We'll use R_Init method now.
Let me explain you some stuff that you will need.

This line of code CREATES d3d stuffs. ( D3D_SDK_VERSION is in d3d includes )
Code:
d3dinit = Direct3DCreate9(D3D_SDK_VERSION);    // interface creationism

The following lines of code are parameters for d3d device.
You can set height and weight there too.
As you can see, there are new parameter, now you can toggle fullscreen.
Code:
    // presentation parameters
    D3DPRESENT_PARAMETERS d3dparams;

    d3dparams.Windowed = TRUE;    // fullscreen toggle
    d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;  
    d3dparams.hDeviceWindow = hWnd;    // get owner and set d3d to the window

The following lines, "merges" Direct3D stuff to our window.
Code:
d3dinit->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd, // window owner // our created window before
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dparams, // presentation parameters
                      &d3ddevice); // initialized device

This code you must get
Code:
// init Direct3D
void R_Init(HWND hWnd)
{
    d3dinit = Direct3DCreate9(D3D_SDK_VERSION);    // interface creationism

    // presentation parameters
    D3DPRESENT_PARAMETERS d3dparams;

    d3dparams.Windowed = TRUE;    // fullscreen toggle
    d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;  
    d3dparams.hDeviceWindow = hWnd;    // get owner and set d3d to the window

    d3dinit->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd, // window owner
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dparams, // presentation parameters
                      &d3ddevice); // initialized device
}

Now you need to load this method.
Put this in WinMain method after ShowWindow method.
If you will put this before ShowWindow, program will crash or just now show.

Now we need to setup renderer.
We will use R_Frame method.
I will explain now, again, what do we need.

'Clear' clears current window to any color before rendering.
Code:
// clear current window
    d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

'BeginScene' starts rendering current scene in window. ( Must be before your stuff )
Code:
d3ddevice->BeginScene();    // starts rendering current scene

'EndScene' ends rendering current scene in window. ( Must be AFTER your stuff )
Code:
d3ddevice->EndScene();    // stops rendering current scene

// 'Present' SHOW final scene
Code:
d3ddevice->Present(NULL, NULL, NULL, NULL);    // shows current scene

Note: Your rendering stuff must be between 'BeginScene' and 'EndScene'
There's final code of R_Frame
Code:
// Render
// this is the function used to render a single frame
void R_Frame(void)
{
    // clear current window
    d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

    d3ddevice->BeginScene();    // starts rendering current scene

    // your rendering stuff will be there

    d3ddevice->EndScene();    // stops rendering current scene

    d3ddevice->Present(NULL, NULL, NULL, NULL);    // shows current scene
}

Now we need to enable rendering.
As you remember ( maybe not, lol ), we created realtime loop. Put R_Frame(); in end of looping.

Well, there's last function, CleanD3D.
It uses to destroy Direct3D stuff. Uses on program quitting.
Code:
// Clean d3d
void CleanD3D(void)
{
    d3ddevice->Release();    // destroys d3d device
    d3dinit->Release();    // destroys d3d stuffs
}

Put this after realtime loop. ( Well, program quits after loop )
Code:
CleanD3D();

If you will launch it now, it will just crash. We need to clear memory of D3D Presenation Parameters, since PP doesn't have release method and couldn't be destroyed.
We will use ZeroMemory method.
There's line of code;
Code:
ZeroMemory(&d3dparams, sizeof(d3dparams));    // clear d3d parameters
Put it before d3dparams initialization. ( in R_Init )
Example:
Code:
// init Direct3D
void R_Init(HWND hWnd)
{
    d3dinit = Direct3DCreate9(D3D_SDK_VERSION);    // interface creationism

    // presentation parameters
    D3DPRESENT_PARAMETERS d3dparams;

    ZeroMemory(&d3dparams, sizeof(d3dparams));    // clear d3d parameters

    d3dparams.Windowed = TRUE;    // windowed mode
    d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;   // you can get all swap effects in google
    d3dparams.hDeviceWindow = hWnd;    // get owner and set d3d to the window

    d3dinit->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd, // window owner
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dparams, // presentation parameters
                      &d3ddevice); // initialized device
}

Compile it, Run it, and .. Ta-Da! You will see blue window now! You created your game world! Lets make some parameters now ( color of window, etc ).

Changing clear color, fullscreen toggling, etc

Lets change window clearing color now. You can see, in R_Frame method, Clear function. I think you have noticed, that, theres D3DCOLOR_XRGB. It is RGB gamma. Lets change colors now!
Code:
D3DCOLOR_XRGB(0, 0, 255)

Also you can use D3DCOLOR_RGBA ( alpha included, but it is useless ).
Lets create variables for it. As you noticed, color data is bytes. But you can use integer also.
Code:
// d3d data
int D3D_COLOR_R;
int D3D_COLOR_G;
int D3D_COLOR_B;

Now, we can setup window mode toggling. It is Boolean type.
Code:
d3dparams.Windowed = TRUE;    // window mode toggle
And you can set it in WinMain or R_Init method. Well, i've created R_Prepare method to prepare all stuffs.
( I've moved all window stuff to it also ).
Add this into header, or just in cpp file.
Code:
void R_Prepare(void);

The following code, that i have
Code:
// ===== Prepare stuff ===== //
void R_Prepare(void)
{
    // mode
    SCREEN_WINDOWED = TRUE;

    // size of window
    SCREEN_WIDTH = 1024;
    SCREEN_HEIGHT = 768;
    // position of window
    SCREEN_POS_X = 0;
    SCREEN_POS_Y = 0;

    // title of the window
    WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )

    // d3d clear color data
        // blueness
    D3D_COLOR_R = 0;
    D3D_COLOR_G = 40;
    D3D_COLOR_B = 120;
}

Updated lines of code
Code:
d3dparams.Windowed = SCREEN_WINDOWED;    // window mode toggle
( R_Init )
Code:
d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(D3D_COLOR_R, D3D_COLOR_G, D3D_COLOR_B), 1.0f, 0);
( R_Frame )

( I recomment you to use Black color, ( it's 0, 0, 0 )

Compile it, Run it.

Done code:
Code:
#include <windows.h>    
#include <windowsx.h>

// required
#include "stdafx.h"

// class
LPCWSTR WIN_MAIN = L"MAIN_WINDOW";

// screen data
int SCREEN_WIDTH;
int SCREEN_HEIGHT;

int SCREEN_POS_X;
int SCREEN_POS_Y;

bool SCREEN_WINDOWED;

LPCWSTR WIN_TITLE;

// d3d data
int D3D_COLOR_R;
int D3D_COLOR_G;
int D3D_COLOR_B;

#include <d3d9.h>
#pragma comment (lib, "d3d9.lib")

LPDIRECT3D9 d3dinit;    // d3d interface init
LPDIRECT3DDEVICE9 d3ddevice;    // d3d device init

void R_Init(HWND hWnd);    // Initialize d3d device
void R_Frame(void);    // rendering
void CleanD3D(void);    // clear display before showing
void R_Prepare(void);

LRESULT CALLBACK WindowProc(HWND hWnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int ShowCmd)
{

    R_Prepare();

    // Window creation
    MSG msg;
    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
                    WindowProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+3),
                    NULL, WIN_MAIN, NULL};

    RegisterClassEx(&wc);

    // create new window
    HWND hMainWnd = CreateWindow(WIN_MAIN,
                                WIN_TITLE,
                                WS_OVERLAPPEDWINDOW, SCREEN_POS_X, SCREEN_POS_Y, SCREEN_WIDTH, SCREEN_HEIGHT,

                                NULL, NULL, hInstance, NULL);
    // show it
    ShowWindow(hMainWnd, ShowCmd);

    // INIT DIRECT3D
    R_Init(hMainWnd); // Initialize d3d stuff
    
    UpdateWindow(hMainWnd);

    // real time loop
    while(TRUE)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        // game loop can be there

        if(msg.message == WM_QUIT)
            break;

        // game loop can be there // recommended there
        R_Frame();
    }

    CleanD3D();

   return(0);
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return(0);
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

// ===== Prepare stuff ===== //
void R_Prepare(void)
{
    // mode
    SCREEN_WINDOWED = TRUE;

    // size of window
    SCREEN_WIDTH = 1024;
    SCREEN_HEIGHT = 768;
    // position of window
    SCREEN_POS_X = 0;
    SCREEN_POS_Y = 0;

    // title of the window
    WIN_TITLE = L"Windowed program ^_^"; // L prefix is required ( C++ basics )

    // d3d clear color data
    // blueness
    D3D_COLOR_R = 0;
    D3D_COLOR_G = 40;
    D3D_COLOR_B = 120;
}

// ===== Direct3D stuff ===== //

// init Direct3D
void R_Init(HWND hWnd)
{
    d3dinit = Direct3DCreate9(D3D_SDK_VERSION);    // interface creationism

    // presentation parameters
    D3DPRESENT_PARAMETERS d3dparams;

    ZeroMemory(&d3dparams, sizeof(d3dparams));    // clear d3d parameters

    d3dparams.Windowed = SCREEN_WINDOWED;    // window mode toggle
    d3dparams.SwapEffect = D3DSWAPEFFECT_DISCARD;   // available: D3DSWAPEFFECT_FLIP, D3DSWAPEFFECT_COPY
    d3dparams.hDeviceWindow = hWnd;    // get owner and set d3d to the window

    d3dinit->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd, // window owner
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dparams, // presentation parameters
                      &d3ddevice); // initialized device
}

// Render
// this is the function used to render a single frame
void R_Frame(void)
{
    // clear current window
    d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(D3D_COLOR_R, D3D_COLOR_G, D3D_COLOR_B), 1.0f, 0);

    d3ddevice->BeginScene();    // starts rendering current scene

    // your rendering stuff will be there

    d3ddevice->EndScene();    // stops rendering current scene

    d3ddevice->Present(NULL, NULL, NULL, NULL);    // shows current scene
}

// Clean d3d
void CleanD3D(void)
{
    d3ddevice->Release();    // destroys d3d device
    d3dinit->Release();    // destroys d3d stuffs
}

You will see something like that:
[Image: nkfWg.png]

End of tutorial, in next tutorial i'll tell about text/vertex creating.

Thanks for reading :p
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
  Reply
#2
Dat global Variables Undecided
[Image: compiling.png][Image: aLKA8og_460sa.gif]
  Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What game have you bought in the last week? RaZ 12 7,210 12-05-2013, 16:29
Last Post: Nekochan
  Making an apocalyptic themed Minecraft map AZUMIKKEL 54 25,827 08-31-2013, 02:54
Last Post: AZUMIKKEL
  [GAME]The Letter Game Bandarigoda123 65 26,743 08-08-2013, 21:05
Last Post: AZUMIKKEL
  [Release] AntiRage for Infected Game Mode yokai134 17 13,208 08-04-2013, 22:22
Last Post: yokai134
  ESTRANGED best indie game I've seen so far Arteq 0 2,322 08-03-2013, 14:03
Last Post: Arteq
  [HELP] bo2 - FD1 - dis-attach the console from the game masis 8 5,420 07-17-2013, 23:01
Last Post: surtek
Smile [Release] Map & Game Type Changer Plugin (Fixed) 30mba 31 20,055 07-10-2013, 16:27
Last Post: 26hz
  Selling steam account for a game! Strentin 3 3,842 06-18-2013, 07:49
Last Post: xfxtroll
  Making a Heli's angles match my angles? akillj 1 2,459 06-16-2013, 15:01
Last Post: Yamato
  Help Using chat outside in game Bandarigoda123 1 2,826 06-09-2013, 12:46
Last Post: Nekochan

Forum Jump:


Users browsing this thread: 2 Guest(s)