c++ - DirectX7 SetPalette always failed -
i'm learning directx, want bind palette primarysurface, process failed. give code below:
#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 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)); (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; **// failed set palette 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; (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; } i don't know why failed setpalette primary surface. set displaymode 640*480*32, palette 256-color, reason? consult msdn, createpalette can create 2bit, 4bit, 8bit palettes. can 32-bit display mode compatible 8bit palette? problem?
i grateful if give me advice. thanks.
anything greater 8-bit mode (16, 24, 32) direct color modes , data in frame buffer actual color, there no palette there in 8-bit indexed color mode.
to make example work is, change screen_bpp 8. problem in modern versions of windows may find palette doesn't stick , gets set system palette. there workarounds might try listed here: "exclusive" directdraw palette isn't exclusive
if want use 32-bit mode there no palette , must set color directly rather using index palette. copy palette color frame buffer in example:
if (failed(lpddbacksurface->lock(null, &ddsd, ddlock_surfacememoryptr | ddlock_wait, null))) return 0; uint *videobuffer = (uint*)ddsd.lpsurface; (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;
Comments
Post a Comment