这一个DEMO费了两天时间了,不能再拖延下去了,故决定今天晚上完成它,原来的代码都已经进行过了,就是下图的一图案,没啥好解释的
这个DEMO主要说明了8位调色板索引(即256色)的绘制,步骤为
1,创建调色板
2,创建主表面
3,关联调色板和主表面
4,锁定内存,绘制,解锁
5,释放资源
书上的C语言代码就不复制过来了,意义不大。主要看分类,首先,弄两个成员变量,调色板和主表面,
终于松了一口气啊,在另外一台电脑上,老是报错,但是这个笔记本上没事,浪费了时间。
现在看下与上节不同的地方
在
首先在类DDRAW_Interface::INITDRAW()
加上调色板变量 PALETTEENTRY palette[256]; // color palette,
然后,加上调色板的各个数值
// build up the palette data array
for (int color=1; color < 255; color++)
{
// fill with random RGB values
palette[color].peRed = rand()%256;
palette[color].peGreen = rand()%256;
palette[color].peBlue = rand()%256;
// set flags field to PC_NOCOLLAPSE
palette[color].peFlags = PC_NOCOLLAPSE;
} // end for color
// now fill in entry 0 and 255 with black and white
palette[0].peRed = 0;
palette[0].peGreen = 0;
palette[0].peBlue = 0;
palette[0].peFlags = PC_NOCOLLAPSE;
palette[255].peRed = 255;
palette[255].peGreen = 255;
palette[255].peBlue = 255;
palette[255].peFlags = PC_NOCOLLAPSE;
然后,声明一个调色板对象为类的成员变量,并创建之
LPDIRECTDRAWPALETTE m_lpddpal; // a pointer to the created dd palette
构造函数中赋予初值为NULL
m_lpddsprimary = NULL; // dd primary surface
在INITDRAW()中,根据调色板创建调色板对象
// create the palette object
if (FAILED( m_lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 |
DDPCAPS_INITIALIZE,
palette,&m_lpddpal, NULL)))
{
// error
return(0);
} // end if
下一步创建主页面,就是显示页面。原来的代码中,是吧ddsd设置为全局变量,这里我觉得不妥,因为这只是局部变量而已,更容易混淆
加上主页面成员变量
LPDIRECTDRAWSURFACE7 m_lpddsprimary; // dd primary surface
构造函数中赋初值
m_lpddsprimary = NULL; // dd primary surface
在INITDDRAW()创建主页面
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
// clear ddsd and set size
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
// enable valid fields
ddsd.dwFlags = DDSD_CAPS;
// request primary surface
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// create the primary surface
if (FAILED(m_lpdd->CreateSurface(&ddsd, &m_lpddsprimary, NULL)))
{
// error
return(0);
} // end if
并关联主页面和调色板
// finally attach the palette to the primary surface
if (FAILED(m_lpddsprimary->SetPalette(m_lpddpal)))
{
// error
return(0);
} // end if
最后释放资源
DDRAW_Interface::~DDRAW_Interface()
{
// now the primary surface
if (m_lpddsprimary)
{
m_lpddsprimary->Release();
m_lpddsprimary = NULL;
} // end if
if (m_lpddpal)
{
m_lpddpal->Release();
m_lpddpal = NULL;
} // end if
if( m_lpdd )
{
m_lpdd->Release();
m_lpdd = NULL;
}
}
由于下一步要调用渲染了,所以,要返回一个主页面,故加上一个返回主页面的函数
LPDIRECTDRAWSURFACE7 DDRAW_Interface::getPrimarySurface()
{
return m_lpddsprimary;
}
下面,进行绘制像素了,在main.cpp的
GAME_MAIN()中,绘制即可
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
if (FAILED(ddraw->getPrimarySurface()->Lock(NULL, &ddsd,
DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
NULL)))
{
// error
return(0);
} // end if
// now ddsd.lPitch is valid and so is ddsd.lpSurface
// make a couple aliases to make code cleaner, so we don't
// have to cast
int mempitch = (int)ddsd.lPitch;
UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface;
// plot 1000 random pixels with random colors on the
// primary surface, they will be instantly visible
for (int index=0; index < 1000; index++)
{
// select random position and color for 640x480x8
UCHAR color = rand()%256;
int x = rand()%640;
int y = rand()%480;
// plot the pixel
video_buffer[x+y*mempitch] = color;
} // end for index
// now unlock the primary surface
if (FAILED(ddraw->getPrimarySurface()->Unlock(NULL)))
return(0);
现在就要和T3DLIB1进行对照了,看看作者的引擎在这部分怎么写的,我该如何改进,
先看调色板数据结构,加入了一个#define MAX_COLORS_PALETTE 256
PALETTEENTRY palette[MAX_COLORS_PALETTE]; // color palette
对于调色板数据结构还有预先设定好的文件,这里暂时不考虑,因为这个DEMO只是暂时用描述数据结构。
看看调色板指针lpddpal
不过,对于是否全屏,这里有解释不同
// load and attach the palette, test for windowed mode
if (screen_windowed)
{
// in windowed mode, so the first 10 and last 10 entries have
// to be slightly modified as does the call to createpalette
// reset the peFlags bit to PC_EXPLICIT for the "windows" colors
for (index=0; index < 10; index++)
palette[index].peFlags = palette[index+246].peFlags = PC_EXPLICIT;
// now create the palette object, but disable access to all 256 entries
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
palette,&lpddpal,NULL)))
return(0);
} // end
else
{
// in fullscreen mode, so simple create the palette with the default palette
// and fill in all 256 entries
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
palette,&lpddpal,NULL)))
return(0);
} // end if
主表面没什么异样,所以,只要目前改一下是否窗口模式时,创建的调色板模式即可。
总结,
主要讲了怎么显示8位256色索引的DEMO,第7章应该讲16色和24位了,
PS:继续SHADOWMAP,拖得时间太长了,主要是脑子太笨了。哎