posts - 131, comments - 12, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

     摘要: 1程序段:?1234567vector <int> vecInt;for (int i=0;i<500;i++){    vecInt.push_back(i);}int j= vecInt.capacity();  //j=512i = vecInt.size(); //i=500?1 &...  阅读全文

posted @ 2013-03-04 12:01 盛胜 阅读(7927) | 评论 (0)编辑 收藏

使用DateTimePicker控件一般是获 取其时间替代手工输入带来的不便,而DateTimePicker控件既可以获取日期(2010-03-05)也可以获取时间(16:27:33),要获 取日期只需要更改控件属性的格式为长日期或短日期,要获取时间则将格式更改为时间即可!

         在添加控件变量时,选择其变量类型为CDateTimeCtrl(类如m_DateCtrl);在程序中定义CTime对象用来保存获取的时间,然后可以将其转换为CString类型;具体实现:

复制代码
1        CTime time;
2 m_DateCtrl.GetTime(time);
3 CString strTime=time.Format("%Y-%m-%d") //获取到的为日期 如:2010-03-05
4
5 CTime time;
6 m_DateCtrl.GetTime(time);
7 CString strTime=time.Format("%H:%M:%S") //获取到的为时间 如:16:27:33
复制代码

VC2005中DateTimePicker控件的使用

复制代码
 1 1 显示年月日时分秒的当前时间
2 CDateTimeCtrl m_DateItmeCtrl_Time;
3 m_DateItmeCtrl_Time.SetFormat(_T("yyyy-MM-dd HH:mm:ss"));
4 CTime TimeTemp=TimeTemp.GetCurrentTime();
5 m_DateItmeCtrl_Time.SetTime(&TimeTemp);
6
7 其中HH表示24小时制,hh表示12小时制
8 2 如果声明一个控件类型为CTime的变量,那么时间将显示1970-01-01 08:00:00.
9
10 3将DateTimePicker控件声明变量类型为COleDateTime
11 COleDateTime转CString
12 CString strTime;
13 COleDateTime dtTime;
14 strTime =dtTime.Format(_T("%Y-%m-%d %H:%M:%S"));
复制代码


CString转COleDateTime(因为VS2005时间日期控件关联的Value变量默认是COleDateTime类型)

1 CString strTime =_T("2009-08-11 11:22:33");
2 COleVariant VariantTime;
3 VariantTime = strTime;
4 VariantTime.ChangeType(VT_DATE);
5 COleDateTime DataTime = VariantTime;

SetTime时 参数需要为指针

复制代码
 1   m_ctrlMachineDeliveryDate.SetTime(&CTime::GetCurrentTime()); //将控件显示当前日期
2 m_ctrlMachineInstallDate.SetTime(&CTime::GetCurrentTime());
3
4
5
6 CTime tDeliveryDate;
7 m_ctrlMachineDeliveryDate.GetTime(tDeliveryDate); //获取发货日期
8 pMachineInfoSet->m_MACHINE_DELIVERYDATE = tDeliveryDate;
9
10
11
12 CTime tDeliveryDate;
13 tDeliveryDate = pMachineInfoSet->m_MACHINE_DELIVERYDATE; //获取记录中的日期
14 m_ctrlMachineDeliveryDate.SetTime(&tDeliveryDate); //将记录中的日期赋值到DateTime控件中显示

例子:
string strTime,strYear,strMonth,strDay;
strTime = strBirthday.substr(0,10);
strYear = strTime.substr(0,4);
strMonth = strTime.substr(5,2);
strDay = strTime.substr(8,2);
CTime t(atoi(strYear.c_str()),atoi(strMonth.c_str()), atoi(strDay.c_str()),0,0,0);
m_DateBorn.SetTime(&t);
复制代码

 // 设定时间日期控件允许选择的范围

复制代码
 1  CTime tCurrentTime= CTime::GetCurrentTime();
2 CTimeSpan timespanOneMonth(30,0,0,0); //这里设置为当前日期推后30天
3 CTime tEndTime = tCurrentTime +timespanOneMonth;
4 m_ctrlADTipsDaysDate.SetRange(&tCurrentTime,&tEndTime);
5 /*
6 m_dtcTm:这个是DATE TIME PICKER控件变量
7 CTime begin_tm(1970,1,1,8,0,0),end_tm(2038,1,19,3,14,7);
8 m_dtcTm.SetRange(&begin_tm,&end_tm);
9 m_tmClock=CTime::GetCurrentTime();//设置初始值为当前时间
10 m_dtcTm.SetTime(&m_tmClock);
11 //m_dtcTm.SetFormat("yyyy-MM-dd HH'时'mm'分'"); //设置字符串格式
12 m_dtcTm.SetFormat("yyyy-MM-dd HH:mm:ss");
13 */
复制代码

posted @ 2013-03-02 15:27 盛胜 阅读(2459) | 评论 (0)编辑 收藏

     摘要: 这个例子类似于 Windows 的资源管理器,程序运行界面如图一所示:图一主要用到的类有:CListCtrl,CTreeCtrl,CImageList,CFileFind 和函数SHGetFileInfo()简述步骤如下:1、增加 TreeCtrl 的 TVS_HASBUTTONS,TVS_HASLINES、TVS_LINESATROOT Style,代码如下:1.DWORD dwSty...  阅读全文

posted @ 2013-03-01 14:01 盛胜 阅读(1190) | 评论 (0)编辑 收藏

方法一:
void CTreeTest_demoDlg::ChangeTreeItemAll(CTreeCtrl &tree, HTREEITEM hItem,BOOL bSelect) 
HTREEITEM x = tree.GetChildItem(hItem); 
if(NULL == x) return; 
do
tree.SetCheck( x, bSelect ); 
ChangeTreeItemAll(tree,x,bSelect);
}
while( ( x = tree.GetNextSiblingItem( x ) )!= NULL ); 
}

 void CTreeTest_demoDlg::OnNMClickTree(NMHDR *pNMHDR, LRESULT *pResult)
 {
  // TODO: 在此添加控件通知处理程序代码
 
  CPoint point; 
  UINT pflags; 
  GetCursorPos(&point); 
  m_ctrTree.ScreenToClient(&point); 
  HTREEITEM hitItem = m_ctrTree.HitTest( point, &pflags );
  if ( pflags & (TVHT_ONITEMSTATEICON )) 
 
 
  //if(m_bSelectDirect) // 选中父结点时他的直接孩子(儿子)结点同时被选中 
  //{ 
  // if ( m_ctrTree.GetCheck( hitItem ) )
  //
  // ChangeTreeItemDirect(m_ctrTree,hitItem,FALSE); 
  // }
  // else 
  //
  // ChangeTreeItemDirect(m_ctrTree,hitItem,TRUE); 
  // }
  //} 
//   if(m_bSelectAll) // 选中父结点时他的孩子结点以及所有后代(孙子)的节点被选中 
   
    if ( m_ctrTree.GetCheck( hitItem ) ) 
   
    ChangeTreeItemAll(m_ctrTree,hitItem,FALSE); 
   
    else 
    {
    ChangeTreeItemAll(m_ctrTree,hitItem,TRUE); 
   
    }
 
  *pResult = 0;
 }


方法二:
void CTreeTest_demoDlg::UpdateTreeCheck(const HTREEITEM hParent, const BOOL flag) 
if (m_ctrTree.ItemHasChildren(hParent)) 
HTREEITEM hNextItem; 
HTREEITEM hChildItem = m_ctrTree.GetChildItem(hParent); 
while (hChildItem != NULL) 
//递归获取当前节点下的子节点 
m_ctrTree.SetCheck(hChildItem,flag); 
UpdateTreeCheck(hChildItem,flag); 
hNextItem = m_ctrTree.GetNextItem(hChildItem, TVGN_NEXT);
hChildItem = hNextItem;
void CTreeTest_demoDlg::OnNMClickTree(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
DWORD dw = GetMessagePos();
CPoint pt(LOWORD(dw),HIWORD(dw)); //鼠标的屏幕坐标
CPoint ptClient; 
CRect rcPart;
m_ctrTree.GetWindowRect(rcPart);
ptClient.x = pt.x - rcPart.left;
ptClient.y = pt.y - rcPart.top; 
UINT uFlags;
HTREEITEM hItem = m_ctrTree.HitTest(ptClient, &uFlags); 
if ((hItem != NULL) && (uFlags & TVHT_ONITEMSTATEICON)) 
if (m_ctrTree.ItemHasChildren(hItem)) 
BOOL flag = m_ctrTree.GetCheck(hItem); //这时父节点还没有更新,需要取反 
UpdateTreeCheck(hItem,!flag); 
}
m_ctrTree.Select(hItem, TVGN_CARET);
*pResult = 0;
}

posted @ 2013-02-28 16:50 盛胜 阅读(681) | 评论 (0)编辑 收藏

TreeCtrl的扩展类,可以改节点字体颜色和背景色
类下载:http://www.codeproject.com/treectrl/simptree.asp
  其中有CSimpleTreeCtrl类和MyNewTreeCtrl类两个
  CSimpleTreeCtrl类继承自CTreeCtrl,而MyNewTreeCtrl类继承自CSimpleTreeCtrl类
  生成MyNewTreeCtrl的对象,加载到主面板中。
  比CTreeCtrl控件好用的地方在:插入节点很直观,可以改变某节点的颜色和背景色,可以很方便的得到父节点和子节点
  getNumChildren:得到子节点的个数
  addChild:在自己下面增加子节点
  getChild ( int i ):得到子节点i
  getParent():得到父节点
  InsertItem( item, parent ):在parent后插入item
  setTextColor:设置字体颜色
  setBkColor:设置背景颜色
  
  示例:
  (1)
  
   CSimpleTreeCtrl::TreeCtrlItem* item = new MyNewTreeCtrl::NewTreeCtrlItem ( name );
   item->setName(name);
   if( red == "true")
   item->setTextColor(#ff0000);
   item->setBkColor(#ffffff);
   m_Tree.InsertItem(item,NULL);
  
  
  (2)
   CSimpleTreeCtrl::TreeCtrlItem* item = new MyNewTreeCtrl::NewTreeCtrlItem ( name );
   item->setName(name);
   if( god == "true")
   item->setTextColor(#ff0000);
   item->setBkColor(#ffffff);
   m_Tree.InsertItem(item,fatherHand); 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static char *color[]={"white","black","red","blue","yellow","cyan","purple","green"};
HICON hIcon[8];
int n;
//CImageList m_list;
m_list.Create(16,16,0,8,8);
hIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON_WHITE);
hIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON_BLACK);
hIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON_RED);
hIcon[3]=AfxGetApp()->LoadIcon(IDI_ICON_BLUE);
hIcon[4]=AfxGetApp()->LoadIcon(IDI_ICON_YELLOW);
hIcon[5]=AfxGetApp()->LoadIcon(IDI_ICON_CYAN);
hIcon[6]=AfxGetApp()->LoadIcon(IDI_ICON_PURPLE);
hIcon[7]=AfxGetApp()->LoadIcon(IDI_ICON_GREEN);
for(n=0;n<8;n++)
m_list.Add(hIcon[n]);

////////////////////////////////////////////////////////
CTreeCtrl *pTree=(CTreeCtrl *) GetDlgItem(IDC_TREE);

pTree->SetImageList(&m_list,TVSIL_NORMAL); //设置图片列表
TV_INSERTSTRUCT tvinsert;    //创建待加入的TV_INSERTSTRUCT的结构
tvinsert.hParent=NULL;       //无父节点
tvinsert.hInsertAfter=TVI_LAST;  //插入到本层最后
tvinsert.item.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
//掩码,图标、选选中图标、文字
tvinsert.item.hItem=NULL;//句柄为空
tvinsert.item.state=0;   //状态
tvinsert.item.stateMask=0;//状态为掩码
tvinsert.item.cchTextMax=6;//最大文字长度
tvinsert.item.iSelectedImage=1;//选中图标索引
tvinsert.item.cChildren=0;   //唯有子节点
tvinsert.item.lParam=0;     //自定义数据


pTree->SetBkColor(#383838);
pTree->SetTextColor(#dedede);
//创建第一层
tvinsert.item.iImage=5;     //一般图标
tvinsert.item.pszText="father";//插入第一层的一个节点“father”
HTREEITEM hDad=pTree->InsertItem(&tvinsert);
tvinsert.item.pszText="mother";//插入第一层的第二个节点“mother”
HTREEITEM hMom=pTree->InsertItem(&tvinsert);
//创建第二层
tvinsert.hParent=hDad;            //父节点为"father"
tvinsert.item.iImage=3;               //一般图标
tvinsert.item.pszText="david";          // 插入第二层father的第一个节点son
pTree->InsertItem(&tvinsert);         
tvinsert.item.pszText="lili";          // 插入第二层father的第一个节点son
pTree->InsertItem(&tvinsert); 
tvinsert.item.pszText="kate";          // 插入第二层father的第一个节点son
pTree->InsertItem(&tvinsert);         
tvinsert.item.pszText="jime";          // 插入第二层father的第一个节点son
pTree->InsertItem(&tvinsert);  


tvinsert.hParent=hMom;                   //父节点为hMom
tvinsert.item.iImage=4;                 // 
tvinsert.item.pszText="david";          // 插入第二层mother的第一个节点son
pTree->InsertItem(&tvinsert);         
tvinsert.item.pszText="lili";          // 插入第二层mother的第一个节点son
pTree->InsertItem(&tvinsert); 
tvinsert.item.pszText="kate";          // 插入第二层mother的第一个节点son
pTree->InsertItem(&tvinsert);         
tvinsert.item.pszText="jime";          // 插入第二层mother的第一个节点son

HTREEITEM hOther=pTree->InsertItem(&tvinsert);
//创建第三层
tvinsert.hParent=hOther;   //父节点为jime
tvinsert.item.iImage=7;

tvinsert.item.pszText="tom";          // 插入第二层hOther的第一个节点tom
pTree->InsertItem(&tvinsert);         
tvinsert.item.pszText="baidi";          // 插入第二层hOther的第一个节点baidu
pTree->InsertItem(&tvinsert);

posted @ 2013-02-28 13:41 盛胜 阅读(1450) | 评论 (0)编辑 收藏

在MFC类库提供了CWnd::OnCtlColor函数,在工作框架的子窗口被重画时将调用该成员函数.因此可以重载WM_CTLCOLOR消息的响应函数.此函数的原型:

  afx_msg HBRUSH OnCtlColor(CDC *pDC,CWnd *pWnd,UINT nCtlColor);
           参数nCtlColor用于指定控件的类型,可以是:
           .CTLCOLOR_BTN                按钮控件
           .CTLCOLOR_DLG                对话框
           .CTLCOLOR_EDIT               编辑框
           .CTLCOLOR_LISTBOX            列表控件
           .CTLCOLOR_MSGBOX             消息控件
           .CTLCOLOR_SCROLLBAR 滚动条控件
           .CTLCOLOR_STATIC             静态控件
[程序实现]
           假设你已有了名为My的对话框工程.你有了一个STATIC的控件,ID为IDC_STATIC1.
  HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
           {
        HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  
        // TODO: Change any attributes of the DC here
           if (nCtlColor==CTLCOLOR_STATIC)

              {
                    pDC->SetTextColor(RGB(255,0,0));
  //字体颜色
                    pDC->SetBkColor(RGB(0, 0, 255));   //字体背景色  

                }
       
 // TODO: Return a different brush if the default is not desired
        return hbr;
           }


如果要指定某个特定控件可以这样写:ID为IDC_STATIC1

if (pWnd->GetDlgCtrlID()==IDC_STATIC1)
{
       pDC->SetTextColor
(
RGB(255,0,0));  //设置字体颜色
       pDC->SetBkMode(TRANSPARENT); //设置字体背景为透明
// TODO: Return a different brush if the default is not desired
  return (HBRUSH)::GetStockObject(BLACK_BRUSH);  // 设置背景色
}
else
return hbr;

【注】

BLACK_BRUSH:黑色

WHITE_BRUSH:白色

GRAY_BRUSH:灰色

NULL_BRUSH:透明

HOLLOW_BRUSH :透明

 

http://hi.baidu.com/sicceer/blog/item/1f3ac41f27f5007ef724e4f2.html

posted @ 2013-02-28 10:44 盛胜 阅读(1448) | 评论 (0)编辑 收藏

一键解决沙盘报错:初始化Start.exe进程失败

Tags:, Posted in WindowsFun,宅技术7 条留言

相信用SandBox3.4X版本的沙盘的同学可能遇到过这种问题。

神马是沙盘?

之前曾经介绍过。就是一个帮你运行怀疑或者有可能生成木马病毒的程序的软件。

 

这个好东西一直妥妥的,突然有一天出错了。可能你以为是大姨妈,但后来你发现,每次都报错,不会每天大姨妈吧?

错误

所谓“好软件如女朋友”,总不能你同居的女朋友每天大姨妈吧。是病,得治。

导致这个问题的原因的:打了KB2393802补丁(后面称③补丁)。

SandBox原作者tzuk:

Aha, I think I understand now. 
The old updates, KB979683 and KB981852 install a new version of the Windows kernel in Windows XP. 
Sandboxie looks for a record of either of these two updates, to adjust itself to this new kernel version. 
I assume the newest update KB2393802 also installs this same new version of the Windows kernel. 
So the problem happens for people who haven’t had KB979683 or KB981852 installed at all. 
And then install this latest update KB2393802. In this case there is a new version of the Windows XP kernel but Sandboxie is not aware of this. 
I will fix Sandboxie to look for a record of KB2393802, just like it does for the two older updates.

按照原作者的话,就是:

旧的版本更新,KB979683补丁(后面称为①补丁)跟KB981852补丁(②补丁)为XP安装了一个新内核。沙盘自动寻找前面两个补丁记录调整自己到相应的内核。如果之前安装了①和②在安装③补丁,沙盘也会自动调整到新的内核。 
问题就在于,之前没有打①②补丁的机器直接打③补丁,沙盘不能调整过来。(看来③补丁为XP又安装了一个新的内核)

网上很多人都说卸载③补丁,但会带来什么样的影响,没有人能明确指出③补丁究竟为系统带来什么样影响,会不会不安全?不过大部分人是删除了,没办法,年轻人,冲动嘛。

在SandBox的官网上,我们找到更为简洁的解决方法:

Create registry key 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\Windows XP\SP4\KB979683

创建一个以补丁①名字命名的键。感觉像是蛊惑一下沙盘读取注册表的那个机制。得承认的是,这个可以解决问题……

posted @ 2013-02-26 19:30 盛胜 阅读(4523) | 评论 (0)编辑 收藏

OpenGL可以把纹理映射到指定的图形的表面上。简单一点的,就是给平面映射纹理,比如一个四边形,一个长方体的6个面,都可以指定位图作为纹理映射到各个面上。

关于将一个位图作为纹理映射到某个或者多个面上,可以学习Jeff Molofee的OpenGL系列教程。

对于指定的多个纹理,要根据自己的需要映射到不同的面上,需要对位图创建一个数组,用来存储位图的名称,然后在初始化OpenGL的时候,可以读取这些位图,然后生成多个纹理存储到一个纹理数组中,接着就可以指定绘制的某个面,对该指定的面进行纹理映射。

下面,在的Jeff Molofee教程的第六课的基础上,实现对6个面分别进行不同的纹理映射。

准备工作就是制作6幅不同的位图,如图所示:


关键代码及其说明如下。

创建全局纹理数组

GLuint texture[6];   // 创建一个全局的纹理数组,用来存储将位图转换之后得到的纹理,对应于立方体的6个面

加载位图文件

加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下:

AUX_RGBImageRec *LoadBMP(char *Filename)    // 根据位图文件的名称进行加载
{
FILE *File=NULL;        // 文件指针

if (!Filename)         // 如果没有指定位图文件名称就返回NULL
{
   return NULL;         
}

File=fopen(Filename,"r");       // 根据指定的位图文件名称,打开该位图文件

if (File)           // 如果位图文件存在
{
   fclose(File);         // 因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位图文件
   return auxDIBImageLoad(Filename);   // 其实,只需要一个真正存在的位图文件的名称,实现加载位图文件,并返回一个指针
}

return NULL;          // 位图文件加载失败就返回NULL
}

上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下所示:

/*
** RGB Image Structure
*/

typedef struct _AUX_RGBImageRec {
    GLint sizeX, sizeY;
    unsigned char *data;
} AUX_RGBImageRec;

首先,AUX_RGBImageRec类型是一个RGB图像结构类型。该结构定义了三个成员:

sizeX —— 图像的宽度;
sizeY —— 图像的高度;
data; —— 图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。

AUX_RGBImageRec类型的变量描述了一幅图像的特征。

上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR)或者auxRGBImageLoadA(LPCSTR),可以在该库文件中找到它的定义,如下所示:

/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */
#ifdef UNICODE
#define auxRGBImageLoad auxRGBImageLoadW
#else
#define auxRGBImageLoad auxRGBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);

#ifdef UNICODE
#define auxDIBImageLoad auxDIBImageLoadW
#else
#define auxDIBImageLoad auxDIBImageLoadA
#endif
AUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);
AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);

宏auxDIBImageLoad实现的功能就是:根据指定的位图名称,将该位图的信息加载到内存中,以便用来创建成为纹理。

创建纹理并加载纹理

用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:

int LoadGLTextures()         // 根据加载的位图创建纹理
{
int Status=FALSE;         // 指示纹理创建是否成功的标志

AUX_RGBImageRec *TextureImage[6];     // 创建一个纹理图像数组,这里指定数组大小为6

memset(TextureImage,0,sizeof(void *)*6);          // 初始化纹理图像数组,为其分配内存

char *pictures[] = {// 创建一个位图名称数组,对应6幅位图
   "Data/No1.bmp",
   "Data/No2.bmp",
   "Data/No3.bmp",
   "Data/No4.bmp",
   "Data/No5.bmp",
   "Data/No6.bmp"
};
for(int i=0; i<6; i++)// 遍历位图名称数组,根据位图名称分别生成
{
   if (TextureImage[i]=LoadBMP(pictures[i]))// 加载位图i成功,修改状态标志变量Status为TRUE
   {
    Status=TRUE;         

   glGenTextures(1, &texture[i]);     // 为第i个位图创建纹理
   glBindTexture(GL_TEXTURE_2D, texture[i]);// 将生成的纹理的名称绑定到指定的纹理上
   glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
   }

   if (TextureImage[i])         // 释放位图数组占用的内存空间
   {
    if (TextureImage[i]->data)       
    {
     free(TextureImage[i]->data);    
    }

    free(TextureImage[i]);        
   }
}
return Status;          // 创建纹理并加载,返回成功或者失败的标志Status
}

上述函数是创建和加载纹理的核心实现。

1、glGenTextures函数

其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:

void glGenTextures(
GLsizein,         
GLuint *textures  
);

函数参数的含义:

n—— 生成的纹理的名称的个数;

textures—— 生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元素的内存地址。

函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。

2、glBindTexture函数

glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。该函数的声明如下所示:

void glBindTexture(
GLenumtarget,  
GLuinttexture  
);

函数参数的含义:

target—— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;

texture—— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。

3、glTexImage2D函数

调用glTexImage2D函数,用来指定二维纹理图像。该函数的声明如下所示:

void glTexImage2D(
GLenumtarget,       
GLintlevel,         
GLintcomponents,    
GLsizeiwidth,       
GLsizeiheight,      
GLintborder,        
GLenumformat,       
GLenumtype,         
const GLvoid*pixels
);

函数参数的含义:

target—— 指定目标纹理,必须为GL_TEXTURE_2D;

level—— 指定图像级别的编号,0表示基本图像,其它可以参考MSDN;

components—— 纹理中颜色组件的编号,可是是1或2或3或4;

width—— 纹理图像的宽度;

height—— 纹理图像的高度;

border—— 纹理图像的边框宽度,必须是0或1;

format—— 指定像素数据的格式,一共有9个取值:GL_COLOR_INDEX、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_RGB、GL_RGBA、GL_BGR_EXT、GL_BGRA_EXT、GL_LUMINANCE、GL_LUMINANCE_ALPHA ,具体含义可以参考MSDN;

type—— 像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, and GL_FLOAT;

pixels—— 内存中像素数据的指针。

4、glTexParameteri函数

glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:

void glTexParameterf(
GLenumtarget,
GLenumpname,
GLfloatparam
);

void glTexParameteri(
GLenumtarget,
GLenumpname,
GLintparam   
);

函数参数的含义:

target—— 目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;

pname—— 用来设置纹理映射过程中像素映射的问题等,取值可以为:GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTER、GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_T,详细含义可以查看MSDN;

param—— 实际上就是pname的值,可以参考MSDN。

另外,该类函数还有两个:

void glTexParameterfv(
GLenumtarget,        
GLenumpname,         
const GLfloat*params
);

void glTexParameteriv(
GLenumtarget,      
GLenumpname,       
const GLint*params
);

上述程序中调用如下:

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过滤,按照指定的方式进行显示,可能会过滤掉显示不正常的纹理像素。

纹理映射过程

纹理映射的过程是在DrawGLScene函数中实现的,也就是在绘制图形的过程中,直接进行我呢里映射,或者称为,为指定的平面贴纹理,DrawGLScene函数实现如下所示:

int DrawGLScene(GLvoid)         
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();         
glTranslatef(0.0f,0.0f,-5.0f);

glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);


  // Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]);//   选择第一个纹理texture[0],进行贴纹理
glBegin(GL_QUADS);
  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();

  // Back Face
glBindTexture(GL_TEXTURE_2D, texture[1]);//   选择第二个纹理texture[1],进行贴纹理
glBegin(GL_QUADS);
   glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
   glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glEnd();

  // Top Face
glBindTexture(GL_TEXTURE_2D, texture[2]);//   选择第三个纹理texture[2],进行贴纹理
glBegin(GL_QUADS);
   glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
   glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
   glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();

  // Bottom Face
glBindTexture(GL_TEXTURE_2D, texture[3]);//   选择第四个纹理texture[3],进行贴纹理
glBegin(GL_QUADS);
   glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
   glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();

  // Right face
glBindTexture(GL_TEXTURE_2D, texture[4]);//   选择第五个纹理texture[4],进行贴纹理
glBegin(GL_QUADS);
   glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
   glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glEnd();

  // Left Face
glBindTexture(GL_TEXTURE_2D, texture[5]);//   选择第六个纹理texture[5],进行贴纹理
glBegin(GL_QUADS);
   glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
   glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();

xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;
return TRUE;          
}

因为,通过前面的过程,已经将位图加载并创建和加载纹理成功,纹理数组已经存在于内存之中,调用上述函数实现纹理映射,即,从内存中取出指定的纹理,将其映射到立方体的指定的面上。

上述函数中调用了glTexCoord2f函数,设置纹理坐标,该函数的声明如下所示:

void glTexCoord2f(
GLfloats,
GLfloatt
);

glTexCoord2f 的第一个参数是X坐标,当s=0.0f 时是纹理的左侧,s=0.5f 时是纹理的中点,s=1.0f 时是纹理的右侧。 glTexCoord2f 的第二个参数是Y坐标,t=0.0f 是纹理的底部,t=0.5f 是纹理的中点, t=1.0f 是纹理的顶部。

上述函数在为前面那个面映射纹理的时候调用如下:

   // Front Face
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
   glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
   glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
   glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();

其中:

glTexCoord2f(0.0f, 0.0f);表示将纹理texture[0]的左下角坐标(0.0f, 0.0f)映射到立方体前面那个面的顶点(-1.0f, -1.0f, 1.0)上;

glTexCoord2f(1.0f, 0.0f);表示将纹理texture[0]的右下角坐标(1.0f, 0.0f)映射到立方体前面那个面的顶点(1.0f, -1.0f, 1.0f)上;

glTexCoord2f(1.0f, 1.0f);表示将纹理texture[0]的右上角坐标(1.0f, 1.0f)映射到立方体前面那个面的顶点(1.0f, 1.0f, 1.0f)上;

glTexCoord2f(0.0f, 1.0f);表示将纹理texture[0]的左上角坐标(0.0f, 1.0f)映射到立方体前面那个面的顶点(-1.0f, 1.0f, 1.0f)上。

这样,纹理texture[0]就被映射到了立方体前面那个面上。

纹理映射结果

为了使立方体能够运动起来,对立方体进行累的旋转变换,而且,定义了三个全局变量:

GLfloat xrot;    // 沿着x旋转的变量
GLfloat yrot;    // 沿着y旋转的变量
GLfloat zrot;   // 沿着z旋转的变量

初始化都为0,然后,在每次调用DrawGLScene函数的时候,改变x、y、z的分量值,在DrawGLScene函数中如下所示:

xrot+=0.3f;
yrot+=0.2f;
zrot+=0.4f;

在DrawGLScene函数中还要执行旋转变换:

glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
glRotatef(zrot,0.0f,0.0f,1.0f);

每次重绘都在改变旋转轴,所以我们绘制的立方体能够动起来,看到各个进行纹理映射的面的效果,如图所示




posted @ 2013-02-20 09:52 盛胜 阅读(2994) | 评论 (0)编辑 收藏

     摘要: VC用ADO访问数据库全攻略,介绍了VC用ADO来访问数据库的各个对象及各方法,很经典,也很实用,很值得一看。 正文 一、ADO概述 ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE. DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速...  阅读全文

posted @ 2013-02-18 08:50 盛胜 阅读(10416) | 评论 (0)编辑 收藏

//方案— 优点:仅使用C标准库;缺点:只能精确到秒级
#include <time.h> 
#include <stdio.h> 
int main( void ) 
    time_t t = time(0); 
    char tmp[64]; 
    strftime( tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",localtime(&t) ); 
    puts( tmp ); 
    return 0; 
}
size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm *timeptr);
根据格式字符串生成字符串。
struct tm *localtime(const time_t *timer);
取得当地时间,localtime获取的结果由结构tm返回
返回的字符串可以依下列的格式而定:
%a 星期几的缩写。Eg:Tue 
%A 星期几的全名。 Eg: Tuesday
%b 月份名称的缩写。 
%B 月份名称的全名。 
%c 本地端日期时间较佳表示字符串。 
%d 用数字表示本月的第几天 (范围为 00 至 31)。日期
%H 用 24 小时制数字表示小时数 (范围为 00 至 23)。 
%I 用 12 小时制数字表示小时数 (范围为 01 至 12)。 
%j 以数字表示当年度的第几天 (范围为 001 至 366)。 
%m 月份的数字 (范围由 1 至 12)。
%M 分钟。 
%p 以 ''AM'' 或 ''PM'' 表示本地端时间。 
%S 秒数。 
%U 数字表示为本年度的第几周,第一个星期由第一个周日开始。 
%W 数字表示为本年度的第几周,第一个星期由第一个周一开始。 
%w 用数字表示本周的第几天 ( 0 为周日)。 
%x 不含时间的日期表示法。 
%X 不含日期的时间表示法。 Eg: 15:26:30
%y 二位数字表示年份 (范围由 00 至 99)。 
%Y 完整的年份数字表示,即四位数。 Eg:2008
%Z(%z) 时区或名称缩写。Eg:中国标准时间 
%% % 字符。

//方案二 优点:能精确到毫秒级;缺点:使用了windows API 
#include <windows.h> 
#include <stdio.h> 
int main( void ) 
SYSTEMTIME sys; 
GetLocalTime( &sys ); 
printf( "%4d/%02d/%02d %02d:%02d:%02d.%03d 星期%1d/n",sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute, sys.wSecond,sys.wMilliseconds,sys.wDayOfWeek); 
return 0;
}
//方案三,优点:利用系统函数,还能修改系统时间
//此文件必须是c++文件
#include<stdlib.h>
#include<iostream>
using namespace std;
void main()
{
    system("time");
}
//方案四,将当前时间折算为秒级,再通过相应的时间换算即可
//此文件必须是c++文件
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
time_t now_time;
now_time = time(NULL);
cout<<now_time;
return 0;
}

posted @ 2013-02-17 10:31 盛胜 阅读(2208) | 评论 (0)编辑 收藏

仅列出标题
共14页: 1 2 3 4 5 6 7 8 9 Last