gpt4 book ai didi

c++ - DirectX7 SetPalette 总是失败

转载 作者:太空宇宙 更新时间:2023-11-04 11:50:20 34 4
gpt4 key购买 nike

我正在学习 DirectX,我想将调色板绑定(bind)到 PrimarySurface,但过程总是失败。我在下面给出我的代码:

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32
#define MAX_COLORS_PALETTE 256

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

LPDIRECTDRAW7 lpdd = NULL;
LPDIRECTDRAWSURFACE7 lpddPrimarySurface = NULL;
LPDIRECTDRAWPALETTE lpddPalette = NULL;
PALETTEENTRY palette[256];

// Omit the unneccessary content

int GameInit()
{
if (FAILED(DirectDrawCreateEx(NULL, (void**)&lpdd, IID_IDirectDraw7, NULL)))
return 0;
if (FAILED(lpdd->SetCooperativeLevel(g_GameHwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return 0;
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
return 0;

DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

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

ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddPrimarySurface->GetAttachedSurface(&ddsd.ddsCaps, &lpddBackSurface)))
return 0;

memset(palette, 0, MAX_COLORS_PALETTE * sizeof(PALETTEENTRY));

for (int index = 0; index < MAX_COLORS_PALETTE; index++)
{
if (index < 64)
palette[index].peRed = index * 4;
else if (index >= 64 && index < 128)
palette[index].peGreen = (index - 64) * 4;
else if (index >= 128 && index < 192)
palette[index].peBlue = (index - 128) * 4;
else if (index >= 192 && index < 256)
palette[index].peRed = palette[index].peGreen = palette[index].peBlue = (index - 192) * 4;

palette[index].peFlags = PC_NOCOLLAPSE;
}

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

**// I always failed to set palette to primary surface here....**
if (FAILED(lpddPrimarySurface->SetPalette(lpddPalette)))
{
MessageBox(NULL, "Failed", NULL, MB_OK);
return 0;
}

DDRAW_INIT_STRUCT(ddsd);

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

UINT *videoBuffer = (UINT*)ddsd.lpSurface;

for (int y = 0; y < SCREEN_HEIGHT; y++)
{
memset((void*)videoBuffer, y % 256, SCREEN_WIDTH * sizeof(UINT));
videoBuffer += ddsd.lPitch >> 2;
}

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


return 1;
}

不知道为什么总是SetPalette到primary surface失败。我设置DisplayMode为640*480*32,我的调色板只有256色,是这个原因吗?但是我查阅了MSDN,CreatePalette只能创建2Bit、4Bit、8Bit的调色板。 32 位显示模式可以与 8 位调色板兼容吗?问题出在哪里?

如果有人能给我一些建议,我将不胜感激。谢谢。

最佳答案

任何大于 8 位模式(16、24、32)的都是直接颜色模式,帧缓冲区中的数据是实际颜色,因此没有像 8 位索引颜色模式那样的调色板.

要使您的示例按原样工作,请将 SCREEN_BPP 更改为 8。问题是在现代版本的 Windows 中,您可能会发现您的调色板不固定,它会被设置回系统调色板。此处列出了一些您可以尝试的解决方法:"Exclusive" DirectDraw palette isn't actually exclusive

如果您想使用 32 位模式,则没有调色板,您必须直接设置颜色,而不是使用调色板中的索引。在您的示例中,您可以执行类似的操作以将调色板颜色复制到帧缓冲区中:

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

UINT *videoBuffer = (UINT*)ddsd.lpSurface;

for (int y = 0; y < SCREEN_HEIGHT; y++)
{
const PALETTEENTRY& p = palette[y%256];
UINT color = (p.peRed << 16) | (p.peGreen << 8) | p.peBlue;
for(int x = 0; x < SCREEN_WIDTH; ++x)
{
videoBuffer[x] = color;
}
videoBuffer += ddsd.lPitch / sizeof(UINT);
}

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

关于c++ - DirectX7 SetPalette 总是失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18619107/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com