高彩模式
除了8位的,还有16位、24位、32位等。高于8位的模式都不再采用调色板模式。下面介绍几种编码模式。
16位模式下有几种编码方案
Alph
X
下面是构造他们的宏:
// this builds a 16 bit color value in
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
// this builds a 16 bit color value in
#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)
// -------------------------------------------------------------------------
// 文件名 : 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).
X(8).8.8:最高8位没有使用。其它的跟Alpha(8).
下面是构造他们的宏:
// this builds a 32 bit color value in
#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)
// -------------------------------------------------------------------------
// 文件名 : 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