
2008年11月25日
- 准备一张图片,格式为BMP,长宽为64像素、128像素或256像素。
- 声明一个变量来存放纹理。
GLuint texture[1];
- 用LoadBMP()载入图片,返回一个指向AUX_RGBImageRec的指针。
AUX_RGBImageRec* texture_image[1];
memset(texture_image, 0, sizeof(void*));
texture_image[0] = LoadBMP(“winxp.bmp”);
- 创建一个纹理,并指定纹理的属性。
glGenTextures(1, &texture[0]);
glBindTextrue(GL_TEXTURE_2D, texture[0]);
- 生成纹理。
glTexImage2D(GL_TEXTURE_2D, 0, 3, texture_image[0]->sizeX, texture_image[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_image[0]->data;
- 设置当图片大于(小于)纹理大小时的显示方式。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- 使纹理有效。
glEnable(GL_TEXTURE_2D);
- 在画的过程中,如果有多个纹理,需要使用glBindTexture(GL_TEXTURE_2D, texture[0])选择纹理。
posted @
2008-11-25 01:34 彭小虎(Tigerkin) 阅读(87) |
评论 (0) |
编辑

2008年11月17日
写了个俄罗斯方块,逻辑算法部分中规中矩,棋盘主要采用二维数组的数据结构,而每种方块样式都是Block类的一个对象,方便扩充;界面部分采用了DialogBox,用GDI画,同时还使用双缓冲技术防止画面闪烁。考虑到可以在RC文件里设计程序界面,所以采用了Dialogbox作为主界面,于是麻烦便来了:DialogBox无法接受WM_KEYDOWN中的VK_UP,VK_DOWN等,也就是说上下左右按键没法用。。试了几种办法,都不行,干脆换成了home,end,page up,page down键。玩的时候很不方便~等我再查查资料再改吧,先把这个有残缺的1.0版本发上来。
程序截图:
下载地址:可执行文件,源代码
posted @
2008-11-17 00:57 彭小虎(Tigerkin) 阅读(91) |
评论 (3) |
编辑

2008年10月28日
很久没更新了。。发一个自己写的String类,可以自己指定使用ANSI还是UNICODE。这里下载
class String
{
private:
wchar_t* wdata;
char* data;
public:
CharSet cs;
String(CharSet _cs = USE_UNICODE, int size = 0); // 默认使用UNICODE,不分配内存(size为0)
String(const String& str, CharSet _cs = USE_ORIG); // 必须是引用
String(const char* str, CharSet _cs = USE_UNICODE);
String(const wchar_t* str, CharSet _cs = USE_UNICODE);
~String();
// 可以从外部直接获得字符串在内存中的地址(小心使用~~)
char* AnsiStr();
wchar_t* UnicodeStr();
String& operator =(const String& str);
String& operator =(const char* str);
String& operator =(const wchar_t* str);
String operator +(const String& str);
String operator +(const char* str);
String operator +(const wchar_t* str);
String& operator +=(const String& str);
String& operator +=(const char* str);
String& operator +=(const wchar_t* str);
int Find(const String& str);
int Find(const char* str);
int Find(const wchar_t* str);
String SubStr(int start, int length);
void Swap(String& str);
int Length() const;
void Clear();
};
posted @
2008-10-28 20:37 彭小虎(Tigerkin) 阅读(65) |
评论 (0) |
编辑

2008年8月16日
我要在MSDN里搜Windows API DrawText函数,如图:

Google: 第一条就是。

Live Search: 找了半天没找到
posted @
2008-08-16 12:22 彭小虎(Tigerkin) 阅读(106) |
评论 (1) |
编辑
以往写Windows程序,用的较多的是Delphi的VCL,MFC用的很少,总觉得不习惯,相比MFC我倒宁愿用清新简单的Windows API。呵呵。于是乎,我萌生了一个想法,自己来封装Windows API。开始动手。。
首先我找了一个比较简单的Window API程序,试着把他转换成面向对象的形式。程序尽管简单,但刚上来一个棘手的问题就出现了。。消息机制的封装。
我们都知道,Windows中比如点击按钮,移动窗口等等的交互操作都是由消息机制来完成的。每做一个动作,例如点击一个按钮,Windows便会产生一个相应的消息,在这里就是BN_CLICKED,假设点击按钮后会弹出一个窗口,里面显示若干文字,而这些点击按钮后产生的效果就需要由我们程序员来编写。体现在Windows API中便是“消息处理函数”,如下:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case BN_CLICKED:
//相关代码
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
每次都要写这么多case的确是挺麻烦的,于是我想用面向对象的方法解决他。
class MessageMap
{
public:
int count; // 消息映射的数目
Message* message[10]; // 可以存放10对消息映射
template <typename T>
void Add(MessageType 消息名称, T* 对应的处理函数); // 增加一对消息映射
};
template <typename T>
class Message
{
public:
MessageType 消息名称;
T* 对应的处理函数;
void Run()
{
对应的处理函数();
}
};
enum MessageType{
}
这样做其实是有问题的,请看这一段:
class MessageMap
{
public:

Message* message[10]; // 由于Message是模板类,这里应该提供模板参数。这样就失去了模板的作用。
// 我们使用模板就是为了能让他存储不同的函数指针。

};
想一想,如何用一个统一的接口来调用不同的函数?对了,那就是多态。
我们可以增加一个抽象的接口类来提供调用接口,而具体实现的类则由他派生。
class MessageInterface


{
public:
MessageType type;

virtual ~MessageInterface()
{}
virtual void Run() = 0;
};

template <typename T>
class Message : public MessageInterface


{
public:
T* classPtr;
void (T::* funcPtr)();
Message(MessageType _type, T* _classPtr, void (T::* _funcPtr)()) : classPtr(_classPtr), funcPtr(_funcPtr)

{
type = _type;
}
virtual void Run()

{
if (classPtr)

{
(classPtr->*funcPtr)(); // 注意调用函数指针时括号的用法
}
}
};

class MessageMap


{
public:
int count;
MessageMap()

{
count = 0;
Add(DESTROY, this, &MessageMap::OnDestroy);
}
MessageInterface* message[10];
void OnDestroy()

{
PostQuitMessage(0);
}
template <typename T>
void Add(MessageType type, T* classPtr, void (T::* funcPtr)())

{
message[count++] = new Message<T>(type, classPtr, funcPtr);
}
};
问题解决了!哈哈,测试成功!
具体的代码在这里,结构什么的还很不完善,仅仅是处理了消息机制而已,当作演示吧。
posted @
2008-08-16 11:23 彭小虎(Tigerkin) 阅读(372) |
评论 (1) |
编辑

2008年8月7日
今天接到leader布置的一个任务,从TextBox继承一个新的控件并为其增加一些功能,其中一个功能如下:
Add a property: FormatString, when the text box lost focus, the content will be replace with string.Format(FormatString, actualContent),我在做第二个:“当textbox失去焦点时自动格式化文本”的地方遇到了问题。。。
简单起见,简化成“当textbox失去焦点时改变文本内容”。
一种方法是:
重写OnLeave()方法,如下:
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
this.Text = "Override OnLeave";
}
另一种是给Leave事件增加一个订阅者:
private void NewReceiver(object sender, EventArgs e)
{
this.text = "NewReceiver";
Invalidate();
}
//constructor
public MyTextBox()
{
this.Leave += new EventHandler(NewReceiver);
}
经测试,均可运行。
现在,把两段代码和在一起,并注释掉第一种方法:
protected override void OnLeave(EventArgs e)
{
base.OnLeave(e);
//this.Text = "Override OnLeave";
}
private void NewReceiver(object sender, EventArgs e)
{
this.text = "NewReceiver";
Invalidate();
}
//constuctor
public MyTextBox()
{
this.Leave += new EventHandler(NewReceiver);
}
运行程序,测试,显示NewReceiver。
接下来再把base.OnLeave(e)注释掉:
protected override void OnLeave(EventArgs e)
{
//base.OnLeave(e);
//this.Text = "Override OnLeave";
}
private void NewReceiver(object sender, EventArgs e)
{
this.text = "NewReceiver";
Invalidate();
}
//constuctor
public MyTextBox()
{
this.Leave += new EventHandler(NewReceiver);
}
运行,发现文本框失去焦点后不会改变内容,仍未空。由此,第二种方法失效了。为何?我们来看一下base.OnLeave()的内容:
protected virtual void OnLeave(EventArgs e)
{
EventHandler handler = (EventHandler) base.Events[EventLeave];
if (handler != null)
{
handler(this, e);
}
}
原来,注释掉这段以后,handler(this, e)无法得到执行,也就没法激发事件,文本框内容当然也就没法改变了。
由此,我猜测,C#的事件触发过程大致是这样的:
文本框失去焦点 --> 触发Leave事件 --> 调用OnLeave()函数(这里是因为什么机制调用的?) --> 调用base.OnLeave() --> 再次触发Leave事件 --> 调用NewReceiver() --> 返回,执行this.text = "Override OnLeave"。
红色字,大家谁知道的,帮我解个惑吧~~
posted @
2008-08-07 19:22 彭小虎(Tigerkin) 阅读(740) |
评论 (8) |
编辑

2008年7月30日
摘要: 一,公钥私钥1,公钥和私钥成对出现2,公开的密钥叫公钥,只有自己知道的叫私钥3,用公钥加密的数据只有对应的私钥可以解密4,用私钥加密的数据只有对应的公钥可以解密5,如果可以用公钥解密,则必然是对应的私钥加的密6,如果可以用私钥解密,则必然是对应的公钥加的密明白了?假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们,然后我告诉大家,1是我的公钥。我有一个文件,不能...
阅读全文
posted @
2008-07-30 11:16 彭小虎(Tigerkin) 阅读(926) |
评论 (0) |
编辑

2008年3月16日
摘要: classString{public:String(constchar*str="");~String();String(constString&another){constchar*str=another.m_data;//可以正常访问/**//*省略*/private:char*m_data;};c++里,类的访问权限是class level,不是object level的。访问权限只...
阅读全文
posted @
2008-03-16 19:29 彭小虎(Tigerkin) 阅读(108) |
评论 (1) |
编辑

2008年3月8日
摘要: 很有用的,所以把它记下来1 CString,int,string,char*之间的转换string 转 CStringCString.format("%s", string.c_str());char 转 CStringCString.format("%s", char*);char 转 stringstring s(char *);string 转 char *char *p = string....
阅读全文
posted @
2008-03-08 23:50 彭小虎(Tigerkin) 阅读(7284) |
评论 (4) |
编辑