6_3调色板和主表面(2013.2.22)

这一个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,拖得时间太长了,主要是脑子太笨了。哎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值