DirectX study notes (-)

zhaozj2021-02-16  45

DirectX study notes (-)

Happyfire 2002/8/2

Issue: Playing a lot of games, can't help but germinate the idea of ​​playing games, so I collected N more information from online in July. July 20th started closing study at home,

I have been yesterday, my first map class has been packaged, and the victory will be pursued to 3 am, and do the map editor version 0.9. I feel a little tired in the morning (I slept for a few hours.

Oh), so I recall these days of learning experience, and the right is to rest. This process is a process from the process of programs to the game, I want to be like me.

The beginners should help, at least less detours.

I. First knowledge DirectX

Before the holiday, I read the article "Holy Sword Heroes - Heroes Savings Production Handbook". This article briefly describes the basic principles of the RPG game, which is easy to understand.

After reading this article, people think that the game production is not outless, highly recommended! However, this article does not refer to the method of DirectX programming. So do a game, but also pass DirectX.

So I spent a day, reading the "Directx Chinese Manual" of the old king, and analyzed several routines, plus a multi-week programming experience, finally had a feeling.

1. Foundation in the foundation

Since we discuss the game programming under the Windows platform, of course, you have to know what Windows programming. We use Win32 SDK (API) programming. Why

Do not need MFC? MFC is Microsoft's encapsulation of API (which is actually packaged), which is suitable for developing large commercial software with unified program architecture and interface, but its complex mechanism affects speed,

This is unbearable for game programming, so Win32API based on C / C is our inevitable choice. (I also heard that there is a game developed with VB, but that is not mainstream after all). Then

What exempted from Win32 API? I want to know the WinMain, window class, message loop, window callback function, can make a simple helloworld, as for GDI

As long as you understand, the control of Windows is basically not used. There are a lot of articles in this regard, find a few things to see. Of course, the game programming is different from general programming, so this is also

Some changes, I will mention below.

2. First DirectDraw routine

Learn DirectX, of course, learning it is the most important part of DirectDraw. DirectDraw is an efficient graphic and hardware-independent graphics provided by Microsoft's Windows platform.

Engine, it provides direct access to memory ... Ok, gossip less, come and see my first routine (this is the first routine on the manual):

// -----------------------------------

// Project: Hellodx

// File: Hellodx.cpp

// Content: First DirectDRAW application

// -----------------------------------

#include

#include

#include

// Global variable

LPDIRECTDRAW LPDD; / / DIRECTDRAW object

LPDIRECTDRAWSURFACE LPDDSPRIMARY; / / DIRECTDRAW main surface

LPDIRECTDRAWSURFACE LPDDSBACK; // Background buffer surface

Char szmsg1 [] = "My First DirectDraw program";

Char szmsg2 [] = "Press ESC Exit"; BOOL BACTIVE = True;

Hwnd hwnd;

// Function declaration

LResult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM);

Bool Initwindow (Hinstance Hinstance, INT NCMDSHOW);

Bool initddraw (void); // Initialization DirectX

Void FreedDraw (void); // Release DirectX Object

Void mainloop (void); // Game main loop

/ / -------------------------------------------------------------------------------------------- -------

// Function: WinMain ()

// Function: Win32 application portfolio function. Perform initialization work, process message loop

/ / -------------------------------------------------------------------------------------------- -------

Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance,

LPSTR LPCMDLINE, INT NCMDSHOW)

{

MSG msg;

// Initialization main window

IF (!in, ncmdshow)

Return False;

// Initialize the DirectDraw environment and implement the DirectDraw function

IF (! initddraw ()) {

MessageBox (getActiveWindow (), "Initialization DirectDraw process error!", "Error", MB_OK;

FREEDDRAW ();

DESTROYWINDOW ());

Return False;

}

While (1) {

IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_NOREMOVE)) {// If there is a message to handle the message

IF (! GetMessage (& MSG, NULL, 0, 0))

Return msg.wparam;

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

Else if (bactage) {// If the program is active, enter the game main loop

Mainloop ();

}

// Waiting for the message

Else WaitMessage ();

}

Return msg.wparam;

}

// --------------------------------------

// Function: initwindow ()

// Function: Create a main window

// --------------------------------------

Static Bool Initwindow (Hinstance Hinstance, Int Ncmdshow)

{

// hwnd hwnd; // window handle

WNDCLASS WC; // window structure

// Fill the window structure

wc.style = 0;

Wc.lpfnWndproc = WinProc;

wc.cbclsextra = 0;

wc.cbWndextra = 0;

wc.hinstance = hinstance;

Wc.hicon = loadicon (Hinstance, IDi_Application);

Wc.hcursor = loadingCursor (NULL, IDC_ARROW);

Wc.hbrbackground = (hbrush) getStockObject (Black_brush); wc.lpszMenuname = NULL;

wc.lpszclassname = "Dxhello";

// Register window class

RegisterClass (& WC);

// Create a main window

HWND = CREATEWINDOWEX (0, "Dxhello", "", WS_POPUP,

0, 0, GetSystemmetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN),

NULL, NULL, HINSTANCE, NULL;

IF (! hwnd)

Return False;

ShowWindow (HWND, NCMDSHOW);

UpdateWindow (HWND);

Return True;

}

/ / -------------------------------------------------------------------------------------------- -

// Function: WinProc ()

// Function: Handle the main window message

/ / -------------------------------------------------------------------------------------------- -

Lresult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)

{

Switch (Message) {

Case WM_ActivateApp:

BACTIVE = WPARAM;

Break;

Case WM_KeyDown: // Key Message

Switch (wparam) {

Case vk_escape:

Postmessage (hwnd, wm_close, 0, 0);

Break;

}

Break;

Case WM_SETCURSOR:

SetCursor (NULL);

Return True;

Case WM_DESTROY: // Exit Message

FREEDDRAW ();

PostquitMessage (0);

Break;

}

// Call the default message processing process

Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM);

}

/ / -------------------------------------------------------------------------------------------- ----------------

// Function: initddraw ()

// Features: Initialize the DirectDraw environment and implement it. Include: Create a DirectDRAW object,

// Set the display mode, create the main surface

/ / -------------------------------------------------------------------------------------------- ----------------

Bool initddraw (void)

{

DDSurfaceDesc DDSD; / / Surface Description

DDSCAPS DDSCAPS;

// HDC HDC; // Equipment Environment Handle

// Create a DirectDraw object

IF (DirectDrawCreate (NULL, & LPDD, NULL)! = DD_OK)

Return False;

// Get exclusive and full screen mode

IF (LPDD-> SetCoopeRarativeAVelevel (getActiveWindow (), DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)! = DD_OK)

Return False;

/ / Set display mode

IF (LPDD-> SetDisplayMode (640, 480, 8)! = DD_OK)

Return False;

// Fill the main surface information

Ddsd.dwsize = sizeof (ddsd); ddsd.dwflags = ddsd_caps | DDSD_BACKBUFFERCOUNT;

DDSD.DDSCAPS.DWCAPS = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

DDSD.DWBACKBUFFERCOUNT = 1;

// Create a main surface object

IF (LPDD-> CreateSurface (& DDSD, & LPDDSPRIMARY, NULL)! = DD_OK)

Return False;

/ / Extract the background cache surface pointer

DDSCAPS.DWCAPS = DDSCAPS_BACKBUFFER;

IF (LPDDSPRIMARY-> GetAttachedSurface (& DDSCAPS, & LPDDSBACK)! = DD_OK)

Return False;

Return True;

}

/ / -------------------------------------------------------------------------------------------- -------

// Function: freeddraw ()

// Features: Release all DirectDraw objects

/ / -------------------------------------------------------------------------------------------- -------

Void FreedDraw (Void)

{

IF (LPDD! = null) {

IF (LPDDSPRIMARY! = NULL) {

LPDDSPRIMARY-> Release ();

LPDDSPRIMARY = NULL;

}

LPDD-> Release ();

LPDD = NULL;

}

}

/ / -------------------------------------------------------------------------------------------- -------

// Function: mainloop ()

// Function: Game main loop

/ / -------------------------------------------------------------------------------------------- -------

Void Mainloop (Void)

{

Static I = 0;

HDC HDC;

// Operation on the background buffer surface

IF (LPDDSBACK-> Getdc (& HDC) == DD_OK) {

SetBkcolor (HDC, RGB (0 i, 255-i, 0 I));

SetTextColor (HDC, RGB (0 i, 0 i, 255-I));

Textout (HDC, 220, 200, SZMSG1, LSTRLEN (SZMSG1));

Textout (HDC, 280, 220, Szmsg2, Lstrlen (Szmsg2));

LPDDSBACK-> ReleaseDC (HDC);

i = 10;

IF (i> 255) i = 0;

}

IF (lpddsprimary-> flip (null, 0)! = DD_OK) {// Once flip, two knots of the two surfaces are exchanged! LPDDSPRIMARY points to the background surface, so

FREEDDRAW (); // You will see the words written on the back surface of the background, and LPDDSBACK points to the original front desk main surface.

PostquitMessage (0); // drop it to the background

}

}

3. Explanation of routines

Looking at this procedure for the first time, I can feel a bit complicated, let's take a look at what this program can do. Construction of a name Hellodx in VC 6.0

Win32 Application Engineering, create a blank CPP file hellodx.cpp, paste this broken code. Don't worry, but also add the DirectDraw library to the project. The method is to select Setting in the menu Project, open the Project Setting dialog, add DDRaw.lib to the object / library module inside the right LINK selection card, and determine it.

Let's run the program below, what did you see?

Let's analyze the structure of this program first, first it is a typical Win32 API program, which is composed of two blocks of Winmain and WinProc. But a little bit a bit is, it is for the news

The loop processing uses the PEEK mode:

While (1) {

IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_NOREMOVE)) {// If there is a message to handle the message

IF (! GetMessage (& MSG, NULL, 0, 0))

Return msg.wparam;

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

Else if (bactage) {// If the program is active, enter the game main loop

Mainloop ();

}

// Waiting for the message

Else WaitMessage ();

}

Function peekMessage determines if there is a message in the message queue, if there is a message, if there is no judgment, if the program is activated, if activation enters the game main loop, if not

Don't do anything, wait for the message. This loop continues until the window receives the WM_Quit message. Before entering this loop, we initialize the window (registration window)

Class, create a window), pay attention to the window style is WS_POPUP when the window is created, so that the window border title bar will appear. And the size of the window is specified as display

The size of the screen, because we have to implement the full screen DirectDraw programming. After the initialization window we initialize the DirectDraw environment and established the DirectDraw object (below

The detailed explanation will be described in this way, you can use DirectDraw to perform graphic output.

Here is our protagonist DirectDraw. You must notice the global variable declaration of the beginning of the program:

LPDIRECTDRAW LPDD; / / DIRECTDRAW object

LPDIRECTDRAWSURFACE LPDDSPRIMARY; / / DIRECTDRAW main surface

LPDIRECTDRAWSURFACE LPDDSBACK; // Background buffer surface

This lpdirectdraw is the type of DirectDraw object (we have a good time as a type, in fact it is a COM interface, this I don't understand :)), the program

There is at least one LPDirectDraw type object, which is the basis for establishing other objects, and the objects of the two LPDirectDrawSurface types are called a DirectDraw surface. LPDD corresponds to

With your graphics card, LPDDSPRIMARY, LPDDSBACK such as a piece of area in the memory (or main). You can specify its type when you build the DirectDraw surface. Here

LPDDSPRIMARY is the main surface, and the front desk you can see (it is displayed on the screen), and LPDDSBack is a background buffer surface, which is attached to LPDDSPRIMARY. of course

You can also create a main surface without a backburden (the first routine of the manual), or you can create a main surface with multiple background buffers. Here I introduce the most commonly used main surfaces with a buffer. Before establishing the main surface, we must first create the DirectDraw object, which is the LPDD here, see the contents of the initddraw function. Function DirectDrawCreate (NULL,

& lpdd, null creates an LPDirectDraw object, and the specific usage of this function can check the relevant information. I will not go out. Set up the DirectDraw environment after establishing LPDD,

Specifically, it is the exclusive and full screen mode and setting display mode. Note that the third parameter 8 of SetDisplayMode is not color 8 colors, but the color depth is 8 bits, that is, 256 colors. After that

Establish the main surface, first to fill in a DDSurfaceDesc surface description structure,

DDSD.DDSCAPS.DWCAPS = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX points to the surface to be created is the main surface, and can be fill (later),

It is a buffered complex surface; ddsd.dwBackBuffercount = 1 indicates a buffer surface number of 1. It is generally filled, and the specific information can be checked. Fill it, you can pass LPDD

The CreateSurface method creates the main surface. Then it is the back surface ... How is the code here? We are not filling in the DDSurfaceDesc structure.

CreateSurface creates a background surface! Because the background buffer surface is linked together with the main surface, the main surface creates it automatically created it, and what we want to get its pointer

To apply it! Using lpddsprimary-> getattachedsurface, understand the attachedssurface here!

At all the surface creation, it can be used to operate. (By the way, there is another surface called the surface of the surface, it does not be displayed directly on the screen directly, it

The role is to store the image, then copy the image to the background surface, that is, BLT, huh, then say ...)

Where are we use DirectDraw? Of course, in the game module, it is Mainloop in this program (MAINLOOP, which is the easiest). In Mainloop

Inside, we first get the equipment environment handle on the background surface, and then write a few words with the GDI of Windows. Then then use the FLIP method of the main surface, interchange the pointer of the front and back surfaces.

This way you will see the words you just wrote. Since MAINLOOP is constantly performing, and we change the color of characters through static variables I, so you can see the charming characters.

. About FLIP must understand, in fact, the pointer is swapped, so very fast! After flip, lpddsprimary points to the background surface, so you will see the words written on the back surface of the background.

, While lpddsback points to the original front desk main surface to take it to the background (change the color is written once), then flip go back, you will change the word color. understand

Is it? Something more, we set up LPDD to full screen mode, only in this mode can only use flip, if it is a window mode, it can only be BLT (BLT is copy).

Don't forget to release the DirectDraw objects and surface objects until the program ends, where you don't release the background surface because I am released with the main surface.

转载请注明原文地址:https://www.9cbs.com/read-27941.html

New Post(0)