动态画面

来源:互联网 发布:4k视频剪辑软件 编辑:程序博客网 时间:2024/04/19 09:16

动态画面
1.后备缓冲(back-buffer)
后备缓冲是指几何形状、色彩深度同主画面相同的用在动画链中的画面。
创建一个带有后备缓冲的主画面的步骤:
(1).首先,你要将DDSD_BACKBUFFERCOUNT加到dwFlags标志字段,向DirectDraw表明DDSURFACEDESC2的dwBackBufferCount字段有效,以及含有后备缓冲数目。
(2)其次,将控制标志DDSCAPS_COMPLEX和DDSCAPS_FLIP加到ddsCaps.dwCaps字段中的字DDSURFACEDESC2结构上。
(3)最后,像通常一样创建主画面。从它调用GetAttachedSurface(),获得后备缓冲。

2.页面变换
一旦创建了具有一个主画面和后备缓冲画面的复杂画面,就可以翻页了。标准动画循环需要以下几步
1.清除后备缓冲
2.对后备缓冲屏幕渲染
3.用后备缓冲画面交换主画面
4.锁定刷屏速度
5.回到第一步

注意:在交换链中,用下一个辅助画面交换主画面可以使用函数Flip()
而且,在翻动时,主画面或者背后表面都必须解锁,所以在调用Flip()翻动它们之前要确保对它们解锁了

3.一个页面交换的程序实例:
// T3D Game Console, creates a game console application

// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // just say no to MFC

#define INITGUID

#include <windows.h>   // include important windows stuff
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>

#include <ddraw.h>

// DEFINES ////////////////////////////////////////////////

// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"

#define SCREEN_WIDTH    640  // size of screen
#define SCREEN_HEIGHT   480
#define SCREEN_BPP      8    // bits per pixel

// TYPES //////////////////////////////////////////////////////

// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char  UCHAR;
typedef unsigned char  BYTE;

// MACROS /////////////////////////////////////////////////

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

#define DRAW_INIT(ddstruct) {memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize = sizeof(ddstruct);}


// GLOBALS ////////////////////////////////////////////////
HWND      main_window_handle = NULL; // globally track main window
HINSTANCE hinstance_app      = NULL; // globally track hinstance
int win_close = 0;

LPDIRECTDRAW7 lpdd = NULL;
LPDIRECTDRAWSURFACE7 lpprimary = NULL;
LPDIRECTDRAWSURFACE7 lpback = NULL;
LPDIRECTDRAWPALETTE lppaltte = NULL;
PALETTEENTRY palttee[256];
DDSURFACEDESC2 ddsd;


char buffer[80];                     // general printing buffer

// FUNCTIONS //////////////////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
          UINT msg,
                            WPARAM wparam,
                            LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT  ps;  // used in WM_PAINT
HDC    hdc; // handle to a device context
char buffer[80];        // used to print strings

// what is the message
switch(msg)
 { 
 case WM_CREATE:
        {
  // do initialization stuff here
        // return success
  return(0);
  } break;
  
 case WM_PAINT:
  {
  // simply validate the window
        hdc = BeginPaint(hwnd,&ps); 
       
        // end painting
        EndPaint(hwnd,&ps);

        // return success
  return(0);
     } break;

 case WM_DESTROY:
  {

  // kill the application, this sends a WM_QUIT message
  PostQuitMessage(0);

        // return success
  return(0);
  } break;

 default:break;

    } // end switch

// process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

///////////////////////////////////////////////////////////

int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here
 if(win_close)
  return(0);

// for now test if user is hitting ESC and send WM_CLOSE
    if (KEYDOWN(VK_ESCAPE))
 {
        SendMessage(main_window_handle,WM_CLOSE,0,0);
     win_close = 1;
 }

 DRAW_INIT(ddsd);

 if(FAILED(lpback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL)))
  return(0);

 UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface;

 if(ddsd.lPitch == SCREEN_WIDTH)
  memset(video_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);
 else
 {
        UCHAR *temp = video_buffer;

  for(int y=0;y<SCREEN_HEIGHT;y++)
  {

            memset(temp,0,SCREEN_WIDTH);

   temp += ddsd.lPitch;
  }
 }

 for(int i = 0;i<5000;i++)
 {
  int x = rand()%SCREEN_WIDTH;
  int y = rand()%SCREEN_HEIGHT;

  UCHAR color = rand()%256;

  video_buffer[x+y*ddsd.lPitch] = color;
 }

 if(FAILED(lpback->Unlock(NULL)))
        return(0);
 
 while(FAILED(lpprimary->Flip(NULL,DDFLIP_WAIT)));
  
 Sleep(500);

// return success or failure or your own return code here
return(1);

} // end Game_Main

////////////////////////////////////////////////////////////

int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here
 if(FAILED(DirectDrawCreateEx(NULL,(void **)&lpdd,IID_IDirectDraw7,NULL)))
  return(0);

 if(FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_ALLOWMODEX|DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)))
  return(0);

 if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
  return(0);

 DRAW_INIT(ddsd);

 ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;

 ddsd.dwBackBufferCount = 1;

 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;

 if(FAILED(lpdd->CreateSurface(&ddsd,&lpprimary,NULL)))
  return(0);

 ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

 if(FAILED(lpprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpback)))
  return(0);

 for(int color = 1;color<255;color++)
 {
  palttee[color].peRed = rand()%256;
  palttee[color].peGreen = rand()%256;
  palttee[color].peBlue = rand()%256;

  palttee[color].peFlags = PC_NOCOLLAPSE;
 }

 palttee[0].peRed = 0;
 palttee[0].peGreen = 0;
 palttee[0].peBlue = 0;

 palttee[0].peFlags = PC_NOCOLLAPSE;

 palttee[255].peRed = 255;
 palttee[255].peGreen = 255;
 palttee[255].peBlue = 255;

 palttee[255].peFlags = PC_NOCOLLAPSE;

 if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT|DDPCAPS_ALLOW256|DDPCAPS_INITIALIZE,palttee,&lppaltte,NULL)))
  return(0);

 if(FAILED(lpprimary->SetPalette(lppaltte)))
  return(0);


// return success or failure or your own return code here
return(1);

} // end Game_Init

/////////////////////////////////////////////////////////////

int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
// this is called after the game is exited and the main event
// loop while is exited, do all you cleanup and shutdown here
    if(lpdd)
 {
  lpdd->Release();
  lpdd = NULL;
 }

 if(lppaltte)
 {
  lppaltte->Release();
  lppaltte = NULL;
 }
 if(lpprimary)
 {
  lpprimary->Release();
  lppaltte = NULL;
 }
 if(lpback)
 {
  lpback->Release();
  lpback = NULL;
 }


// return success or failure or your own return code here
return(1);

} // end Game_Shutdown

// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
     HINSTANCE hprevinstance,
     LPSTR lpcmdline,
     int ncmdshow)
{

WNDCLASSEX winclass; // this will hold the class we create
HWND    hwnd;  // generic window handle
MSG     msg;   // generic message
HDC        hdc;      // graphics device context

// first fill in the window class stucture
winclass.cbSize         = sizeof(WNDCLASSEX);
winclass.style   = CS_DBLCLKS | CS_OWNDC |
                          CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra  = 0;
winclass.cbWndExtra  = 0;
winclass.hInstance  = hinstance;
winclass.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor  = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

// save hinstance in global
hinstance_app = hinstance;

// register the window class
if (!RegisterClassEx(&winclass))
 return(0);

// create the window
if (!(hwnd = CreateWindowEx(NULL,                  // extended style
                            WINDOW_CLASS_NAME,     // class
          "T3D Game Console Version 1.0", // title
          WS_POPUP | WS_VISIBLE,
           0,0,   // initial x,y
          SCREEN_WIDTH,SCREEN_HEIGHT,  // initial width, height
          NULL,   // handle to parent
          NULL,   // handle to menu
          hinstance,// instance of this application
          NULL))) // extra creation parms
return(0);

// save main window handle
main_window_handle = hwnd;

// initialize game here
Game_Init();

// enter main event loop
while(TRUE)
 {
    // test if there is a message in queue, if so get it
 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {
    // test if this is a quit
       if (msg.message == WM_QUIT)
           break;
 
    // translate any accelerator keys
    TranslateMessage(&msg);

    // send the message to the window proc
    DispatchMessage(&msg);
    } // end if
   
       // main game processing goes here
       Game_Main();
      
 } // end while

// closedown game here
Game_Shutdown();

// return to Windows like this
return(msg.wParam);

} // end WinMain

///////////////////////////////////////////////////////////
 

原创粉丝点击