zoukankan      html  css  js  c++  java
  • DDraw笔记高彩模式

    高彩模式

    除了8位的,还有16位、24位、32位等。高于8位的模式都不再采用调色板模式。下面介绍几种编码模式。

    16位模式下有几种编码方案

    Alpha.5.5.5:这种模式用D15位存储一个Alpha(透明度),其余15位均匀分配给红色5位,绿色5位,蓝色5位。

    X5.5.5与Alpha.5.5.5类似,只是最高位没有使用。

    5.6.5这个是16色彩最常用的模式。5位分配给红,6位分配给绿,5位分配给蓝

    下面是构造他们的宏:

    // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)

    #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))

     

    // this builds a 16 bit color value in 5.6.5 format (green dominate mode)

    #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))

     

    源代码下载

    // ------------------------------------------------------------------------- 
    // 文件名 : 7_1.cpp
    // 创建者 : 方煜宽
    // 邮箱 : fangyukuan@gmail.com
    // 创建时间 : 2010-12-9 0:52
    // 功能描述 : 16位模式,RGB565
    // 对于像素位深度大于8的页面,不需要使用调色板
    // -------------------------------------------------------------------------
    #define INITGUID

    #include
    <windows.h>
    #include
    <ddraw.h>


    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    HWND main_window_handle
    = NULL; // 全局的windows窗口句柄
    LPDIRECTDRAW7 lpdd = NULL; // ddraw 接口指针
    DDSURFACEDESC2 ddsd; // ddraw 显示表面 描述结构
    LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // ddraw 主显示表面
    LPDIRECTDRAWSURFACE7 lpddsback = NULL; // ddraw 从显示表面

    #define SCREEN_WIDTH 640 // 屏幕宽
    #define SCREEN_HEIGHT 480 // 屏幕高
    #define SCREEN_BPP 16 // 深度
     

    #define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct, 0, sizeof(ddstruct)); ddstruct.dwSize = sizeof(ddstruct);
    }
     // this builds a 16 bit color value in 5.6.5 format (green dominate mode)
    #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
     // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
    #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
     #define KEYDOWN(vk_code) ((::GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEYUP(vk_code) ((::GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
    
    
     

    /*
    每个像素16位,用此函数前先锁住表面。
    */
    inline
    void Plot_Pixel_Faster16(int x, int y,
    int red, int green, int blue,
    USHORT
    *video_buffer, int lpitch16)
    {
    USHORT pixel
    = _RGB16BIT565(red,green,blue);
    video_buffer[x
    + y*lpitch16] = pixel;
    }
    int Game_Init(void *parms = NULL, int num_parms = 0)
    {
    if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
    return 0;

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

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

    memset(
    &ddsd,0,sizeof(ddsd));
    ddsd.dwSize
    = sizeof(ddsd);

    ddsd.dwFlags
    = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps
    = DDSCAPS_PRIMARYSURFACE;

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

    // 不需要调色板了
    // 对于像素位深度大于8的页面,不需要使用调色板

    return 1;
    }
    int Game_Shutdown(void *parms = NULL, int num_parms = 0)
    {
    if (lpddsprimary)
    {
    lpddsprimary
    ->Release();
    lpddsprimary
    = NULL;
    }

    if (lpdd)
    {
    lpdd
    ->Release();
    lpdd
    = NULL;
    }
    return 1;
    }
    int Game_Main(void *parms = NULL, int num_parms = 0)
    {
    if (KEYDOWN(VK_ESCAPE))
    SendMessage(main_window_handle, WM_CLOSE,
    0, 0);

    DDRAW_INIT_STRUCT(ddsd);

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

    int lpitch16 = (int)(ddsd.lPitch >> 1);
    USHORT
    *video_buffer = (USHORT *)ddsd.lpSurface;

    for (int index=0; index < 1000; index++)
    {
    int red = rand() % 256;
    int green = rand() % 256;
    int blue = rand() % 256;
    int x = rand() % 640;
    int y = rand() % 480;

    Plot_Pixel_Faster16(x, y, red, green, blue, video_buffer, lpitch16);
    }

    if (FAILED(lpddsprimary->Unlock(NULL)))
    return 0;

    return 1;
    }
    int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd)
    {
    HWND hwnd;
    MSG msg;
    TCHAR lpszClassName[]
    = TEXT("kuan");

    WNDCLASS wc;
    wc.style
    = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc
    = WndProc;
    wc.cbClsExtra
    = 0;
    wc.cbWndExtra
    = 0;
    wc.hInstance
    = hInstance;
    wc.hIcon
    = ::LoadIcon(NULL,IDI_APPLICATION);
    wc.hCursor
    = ::LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground
    = (HBRUSH)::GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName
    = NULL;
    wc.lpszClassName
    = lpszClassName;

    RegisterClass(
    &wc);

    hwnd
    = CreateWindow(lpszClassName,
    TEXT(
    "fangyukuan"),
    WS_POPUP
    | WS_VISIBLE,
    0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
    NULL,
    NULL,
    hInstance,
    NULL);
    main_window_handle
    = hwnd;

    Game_Init();
    while(TRUE)
    {
    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    if (msg.message == WM_QUIT)
    break;

    ::TranslateMessage(
    &msg);
    ::DispatchMessage(
    &msg);
    }
    Game_Main();

    }
    Game_Shutdown();

    return msg.wParam;
    }

    LRESULT CALLBACK WndProc(HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
    {
    switch(message)
    {
    case WM_LBUTTONDOWN:
    {
    ::MessageBeep(
    0);
    }
    break;
    case WM_DESTROY:
    ::PostQuitMessage(
    0);
    break;
    default:
    return ::DefWindowProc(hwnd,message,wParam,lParam);
    }
    return 0;
    }

    32位模式下有几种编码方案

    Alpha(8).8.8.8:用8位表示透明信息。红色、绿色、蓝色,各有用8位。每个像素都用32位来表示,这是奔腾处理器最快的内存寻址方式。

    X(8).8.8:最高8位没有使用。其它的跟Alpha(8).8.8.8一样。

      

    下面是构造他们的宏:

    // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)

    #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))

     

    源代码下载

    // ------------------------------------------------------------------------- 
    // 文件名 : 7_3.cpp
    // 创建者 : 方煜宽
    // 邮箱 : fangyukuan@gmail.com
    // 创建时间 : 2010-12-11 22:05
    // 功能描述 : 32位真彩模式
    //
    // -------------------------------------------------------------------------
    #define INITGUID

    #include
    <windows.h>
    #include
    <ddraw.h>


    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    HWND main_window_handle
    = NULL; // 全局的windows窗口句柄
    LPDIRECTDRAW7 lpdd = NULL; // ddraw 接口指针
    DDSURFACEDESC2 ddsd; // ddraw 显示表面 描述结构
    LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // ddraw 主显示表面
    LPDIRECTDRAWSURFACE7 lpddsback = NULL; // ddraw 从显示表面

    #define SCREEN_WIDTH 640 // 屏幕宽
    #define SCREEN_HEIGHT 480 // 屏幕高
    #define SCREEN_BPP 32 // 深度
     
      

    #define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
     // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
    #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
    #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

    inline void Plot_Pixel_32(int x, int y,
    int alpha,int red, int green, int blue,
    UINT
    *video_buffer, int lpitch32)
    {
    UINT pixel
    = _RGB32BIT(alpha,red,green,blue);
    video_buffer[x
    + y*lpitch32] = pixel;
    }
    int Game_Init(void *parms = NULL, int num_parms = 0)
    {
    if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
    return 0;

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

    // set display mode to 640x480x16
    if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
    return 0;

    memset(
    &ddsd,0,sizeof(ddsd));
    ddsd.dwSize
    = sizeof(ddsd);
    ddsd.dwFlags
    = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps
    = DDSCAPS_PRIMARYSURFACE;

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

    // 不需要调色板了
    // 对于像素位深度大于8的页面,不需要使用调色板

    return 1;

    }
    int Game_Shutdown(void *parms = NULL, int num_parms = 0)
    {
    // now the primary surface
    if (lpddsprimary)
    {
    lpddsprimary
    ->Release();
    lpddsprimary
    = NULL;
    }

    // now blow away the IDirectDraw4 interface
    if (lpdd)
    {
    lpdd
    ->Release();
    lpdd
    = NULL;
    }
    return 1;
    }
    int Game_Main(void *parms = NULL, int num_parms = 0)
    {
    if (KEYDOWN(VK_ESCAPE))
    SendMessage(main_window_handle, WM_CLOSE,
    0, 0);

    DDRAW_INIT_STRUCT(ddsd);

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

    int lpitch32 = (int)(ddsd.lPitch >> 2);
    UINT
    *video_buffer = (UINT *)ddsd.lpSurface;

    for (int index=0; index < 1000; index++)
    {
    int red = rand() % 256;
    int green = rand() % 256;
    int blue = rand() % 256;
    int x = rand() % 640;
    int y = rand() % 480;

    Plot_Pixel_32(x, y,
    0, red, green, blue, video_buffer, lpitch32);
    }

    if (FAILED(lpddsprimary->Unlock(NULL)))
    return 0;

    return 1;
    }
    int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nShowCmd)
    {
    HWND hwnd;
    MSG msg;
    TCHAR lpszClassName[]
    = TEXT("kuan");

    WNDCLASS wc;
    wc.style
    = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc
    = WndProc;
    wc.cbClsExtra
    = 0;
    wc.cbWndExtra
    = 0;
    wc.hInstance
    = hInstance;
    wc.hIcon
    = ::LoadIcon(NULL,IDI_APPLICATION);
    wc.hCursor
    = ::LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground
    = (HBRUSH)::GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName
    = NULL;
    wc.lpszClassName
    = lpszClassName;

    RegisterClass(
    &wc);

    hwnd
    = CreateWindow(lpszClassName,
    TEXT(
    "fangyukuan"),
    WS_POPUP
    | WS_VISIBLE,
    0,0,SCREEN_WIDTH,SCREEN_HEIGHT,
    NULL,
    NULL,
    hInstance,
    NULL);
    main_window_handle
    = hwnd;

    Game_Init();
    while(TRUE)
    {
    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    if (msg.message == WM_QUIT)
    break;

    ::TranslateMessage(
    &msg);
    ::DispatchMessage(
    &msg);
    }
    Game_Main();

    }
    Game_Shutdown();

    return msg.wParam;
    }

    LRESULT CALLBACK WndProc(HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
    {
    switch(message)
    {
    case WM_LBUTTONDOWN:
    {
    ::MessageBeep(
    0);
    }
    break;
    case WM_DESTROY:
    ::PostQuitMessage(
    0);
    break;
    default:
    return ::DefWindowProc(hwnd,message,wParam,lParam);
    }
    return 0;
    }

    获取像素格式

    想知道任意表面的像素格式,可以用下面函数获取
    IDIRECTDRAWSURFACE7::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat);

    对DDPIXELFORMAT结构我们感兴趣的有以下三个:

    DWORD dwSize;          // 结构大小
    DWORD dwFlags;         // 描述表面的标志,见下表
    DWORD dwRGBBitCount;   // RGB的位数

    DDPIXELFORMAT. dwFlags的有效标志 

    描述

    DDPF_ALPHA

    像素格式描述一个只有alpha的表面

    DDPF_ALPHAPIXELS

    画面有alpha信息的像素格式

    DDPF_LUMINANCE

    像素格式中有单一透明或者透明alpha分量的画面

    DDPF_PALETTEINDEXED1

    画面是1位色彩索引

    DDPF_PALETTEINDEXED2

    画面是2位色彩索引

    DDPF_PALETTEINDEXED4

    画面是4位色彩索引

    DDPF_PALETTEINDEXED8

    画面是8位色彩索引

    DDPF_PALETTEINDEXEDTO8

    画面是1位、2位、4位色彩索引到8位调色板

    DDPF_RGB

    像素格式中的RGB数据有效

    DDPF_ZBUFFER

    像素格式 描述 一个Z缓冲画面

    DDPF_ZPIXELS

    画面在像素中含有Z信息

    比较重要标志是:

    DDPF_PALETTEINDEXED8:说明表面租用 8位调色板模式。

    DDPF_RGB:说明表面采用RGB模式,其格式可以通过测试dwRGBBitCount值获得。

    DDPIXELFORMAT ddpixel;
    LPDIRECTDRAWSURFACE7 lpdds_primary;
    memset(
    &ddpixel, 0, sizeof(ddpixel));
    ddpixel.dwSize
    = sizeof(ddpixel);
    lpdds_primary
    ->GetPixelFormat(&ddpixel);
    if (ddpixel.dwFlags & DDPF_RGB)
    {
    switch(ddpixel.dwRGBBitCount)
    {
    case 15: // must be 5.5.5 mode
    break;
    case 16: // must be 5.6.5 mode
    break;
    case 24: // must be 8.8.8 mode
    break;
    case 32: // must be alpha(8).8.8.8 mode
    break;
    default:
    break;
    }
    }
    else if (ddpixel.dwFlags & DDPF_PALETTEINDEXED8)
    {
    // 256 color palettized mode
    }
    else
    {

    }

    2011.05.22

    转载请保留下面链接

    标题 http://www.cnblogs.com/fangyukuan/archive/2011/05/22/2053556.html

  • 相关阅读:
    第6 章 : 应用编排与管理:Deployment
    第5 章 : 应用编排与管理:核心原理
    第4 章 : 理解 Pod 和容器设计模式
    第3 章 : Kubernetes 核心概念
    第2 章 : 容器基本概念
    第1 章 : 第一堂“云原生”课
    阿里云原生技术公开课程-讲师记录及视频链接
    Shell中的(),{}几种语法用法-单独总结
    折腾kubernetes各种问题汇总-<1>
    Kubernetes中Deployment部署故障排除
  • 原文地址:https://www.cnblogs.com/fangyukuan/p/2053556.html
Copyright © 2011-2022 走看看