本文基础:

C#+OpenGL编程之OpenGL 纹理载入

C#+OpenGL编程之OpenGL 多重纹理

小桃子The Tao FrameworkTao提供的所有库都是完全开源的。其中的多数库都可以免费用在商业项目中,该框架较其它框架实现更简单、容易,代码也简洁易读。

很遗憾的是这个框架已经不再开发了,作为程序猿不得不想点其他的框架了。

下面的课程,我们将使用另外一个框架,OpenGL DotNet 官方网站:http://www.taylaninan.com/opengl-dotnet

作为我们的开发框架,比起 小桃子的后继者OpenTK更接近C代码风格,要知道,做什么事都要跟随大流。现在市面上的游戏引擎都是C或者C++,而很多OpenGL教程也是基于C或者C++,标新立异等于在装酷。

首先我们实现最早的基础实例吧:

using System;
using System.Collections.Generic;
using System.Text;
using OpenGLDotNet; namespace OpenGLTK
{
///OpenGLDotNet需要修改
///glut32.dll ->freeglut.dll
///GLUT最初是《OpenGL红皮书(第二版)》[注2]中的示例程序。自那以后,GLUT简单、跨平台的特点,使其在各种实际应用中广泛应用。
///目前最后版本GLUT v3.7的历史可追溯至1998年8月,且该项目似乎已经被废弃。它的许可证禁止任何人发布修改后的库代码。
///毋庸置疑GLUT已经很老了,真的需要改善。此外,GLUT的许可证与一些软件发行不兼容(如XFree86的)。
///一个轻量级的,开源的,跨平台的library。支持OpenGL及OpenGL ES,用来管理窗口,读取输入,处理事件等。因为OpenGL没有窗口管理的功能,所以很多热心的人写了工具来支持这些功能,比如早期的glut,现在的freeglut等。
///修改代码位置 GLU.Functions.cs ///找不到glu32.dll解决方法:
///glu32.dll 改为->GLU32.dll,具体文件名大小写可以去 系统目录搜索这个文件我的是server2012
///修改代码位置 GLUT.Functions.cs ///tao->OpenGLDotNet 需要修改的地方
///函数去掉glu和gl部分,例如
///GL.glPopMatrix();->GL.PopMatrix();
///Gl.gl->GL.
///Gl.GL_->GL.GL_
/// Glu.glu->GLU.
///当然你可以修改源代码private ->public
///修改代码位置 GL.CoreDelegates.cs /// <summary>
/// 第二章 Opengl程序框架 C# by 大师♂罗莊
///
/// </summary>
class Examplefirst : IDisposable
{
String title = "第二章 Opengl程序框架";
///窗口大小
internal int windowWidth, windowHeight; //当前帧
internal float currentTime, startTime; //鼠标位置
internal int mouseX, mouseY, button, state;
//键盘按下 internal byte key;
public Examplefirst()
{
GLConfig.Init(, , title, , , , );
GL.Init(true);
GLUT.KeyboardFunc(Keyboard);
GLUT.MouseFunc(Mouse);
GLUT.IdleFunc(Idle);
GLUT.ReshapeFunc(Reshape);
GLUT.MotionFunc(Motion);
GLUT.DisplayFunc(Display);
} /// <summary>
/// glut键盘回调函数
/// </summary>
/// <param name="key"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public virtual void Keyboard(byte key, int x, int y)
{
this.key = key;
} /// <summary>
/// glut鼠标按下与释放回调函数
/// </summary>
/// <param name="button"></param>
/// <param name="state"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public virtual void Mouse(int button, int state, int x, int y)
{ this.button = button;
this.state = state;
this.mouseX = x;
this.mouseY = y;
return;
} /// <summary>
/// glut空闲处理回调函数
/// </summary>
public void Idle()
{
currentTime = System.Environment.TickCount;
Update(currentTime - startTime);
startTime = currentTime;
return;
} /// <summary>
/// glut窗口重置回调函数
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
public void Reshape(int width, int height)
{
windowWidth = width;
windowHeight = height;
//防止除零问题
windowHeight = windowWidth > ? windowHeight : ;
InitGL(windowWidth, windowHeight); } /// <summary>
/// glut鼠标移动回调函数
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public void Motion(int x, int y)
{
return;
} /// <summary>
/// glut描绘回调函数
/// </summary>
public void Display()
{
//我感觉用这个得重新设置下lookUP才行
iniView(windowWidth, windowHeight);
DrawGLScene(); } /// <summary>
/// 入口点
/// </summary>
public void Run()
{
GLUT.MainLoop();
} /// <summary>
/// 更新用
/// </summary>
public virtual void Update(float milliseconds)
{
if (key == ) // Escape 按下,退出
{
this.Dispose();
}
return;
} /// <summary>
/// 原书的初始化方法,C# by 大师♂罗莊
/// </summary>
/// <param name="windowWidth">窗口宽</param>
/// <param name="windowHeight">窗口高</param>
/// <returns></returns>
Boolean InitGL(int windowWidth, int windowHeight)
{
// 设置视口 viewport
GL.Viewport(, , windowWidth, windowHeight); //启用阴影平滑
GL.ShadeModel(GL.GL_SMOOTH); //启用反走样
GL.Hint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); // 设置投影模式 projection matrix
GL.MatrixMode(GL.GL_PROJECTION);
GL.LoadIdentity();
GL.Disable(GL.GL_DITHER);
return true;
}
/// <summary>
/// 初始化视口投影,本例子没有采用原书例子,自定义的视口
/// </summary>
public virtual void iniView(int windowWidth, int windowHeight)
{
GLU.Perspective(, windowWidth / (double)windowHeight, , );
// 选择模型观察矩阵 modelview matrix
GL.MatrixMode(GL.GL_MODELVIEW);
//重置模型观察矩阵
GL.LoadIdentity();
GLU.LookAt(, , , // 眼睛位置
, , , // 观察点
, , ); // 怎么看
} /// <summary>
/// 原书的绘制方法 C# by 大师♂罗莊
/// <param name="currentTime">当前帧</param>
/// </summary>
public virtual void DrawGLScene()
{
// 重置黑色背景
GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL.Clear(GL.GL_COLOR_BUFFER_BIT);
// 画三角形
GL.Translatef(, , );
GL.Begin(GL.GL_TRIANGLES);
GL.Color3f(, , );
GL.Vertex3f(-, , -);
GL.Color3f(, , );
GL.Vertex3f(, , -);
GL.Color3f(, , );
GL.Vertex3f(, , );
GL.End();
GLUT.SwapBuffers();
} public void Dispose()
{
GLUT.KeyboardFunc(null);
GLUT.MouseFunc(null);
GLUT.IdleFunc(null);
GLUT.ReshapeFunc(null);
GLUT.MotionFunc(null);
GLUT.DestroyWindow(GLUT.GetWindow());
}
}
}

OpenGL DotNet也非十全十美,需要我们修改源代码:

1、首先一个问题就是使用glut32.dll,这个库已经是上个世纪的库了,我们需要修改GLU.Functions.cs 里面把glut32.dll改为freeglut.dll

2、找不到glu32.dll,这个要大家自己去windows目录看文件名大小写,在我的2012上面文件名为GLU32.dll

然后就可以把桃子框架代码移植过来了。

上面的代码就和C很相似了,使用GLUT函数实现窗口管理,代码量从160行升至220行。

下面我们移植下多重纹理吧。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using OpenGLDotNet; namespace OpenGLTK
{
/// <summary>
/// 自制的纹理载入类 C# by 大师♂罗莊
/// </summary>
class TextureLoad : IDisposable
{
public uint[] ID = new uint[];
Bitmap image;
public bool Load(String fileName)
{
///原则上材质只应该在初始化时候载入一次,否则会影响性能
if (image != null)
{
return true;
}
FileInfo file = new FileInfo(fileName);
if (file.Exists == false)
{
MessageBox.Show("无法载入" + fileName);
return false;
}
try
{
if (file.Extension.ToUpper() == ".TGA")
{
///http://blog.csdn.net/zgke/article/details/4667499
///C# 载入TGA 类,自行参考,这里不再列出
ImageTGA tga = new ImageTGA(fileName);
image = tga.Image;
}
else
{
image = new Bitmap(fileName);
} }
catch (System.ArgumentException)
{
MessageBox.Show("无法载入" + fileName);
return false;
} if (image != null)
{
image.RotateFlip(RotateFlipType.RotateNoneFlipY);
System.Drawing.Imaging.BitmapData bitmapdata;
Rectangle rect = new Rectangle(, , image.Width, image.Height); ///Nearest Linear MipMapped三个纹理实现,本文暂时不考虑
//bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//GL.GenTextures(3, this.texture); //// Create Nearest Filtered Texture
//GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[0]);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
//GL.TexImage2D(GL.GL_TEXTURE_2D, 0, (int)GL.GL_RGB, image.Width, image.Height, 0, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
//// Create Linear Filtered Texture
//GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[1]);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
//GL.TexImage2D(GL.GL_TEXTURE_2D, 0, (int)GL.GL_RGB, image.Width, image.Height, 0, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
//// Create MipMapped Texture
//GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[2]);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
//GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
//GL.uBuild2DMipmaps(GL.GL_TEXTURE_2D, (int)GL.GL_RGB, image.Width, image.Height, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
//image.UnlockBits(bitmapdata); /** 生成纹理对象名称 */
GL.GenTextures(, ID); /** 创建纹理对象 */
GL.BindTexture(GL.GL_TEXTURE_2D, ID[]); /** 控制滤波 */
GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);
GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_REPEAT);
GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_REPEAT); bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
/** 创建纹理 */
GLU.Build2DMipmaps(GL.GL_TEXTURE_2D, (int)GL.GL_RGB, image.Width,
image.Height, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE,
bitmapdata.Scan0);
image.UnlockBits(bitmapdata);
}
return true;
} public void FreeImage()
{
/** 释放内存 */
if (image != null)
{
image.Dispose();
}
}
public void Dispose()
{
FreeImage();
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using OpenGLDotNet; namespace OpenGLTK
{
/// <summary>
/// 第四章 OpenGl 多重纹理载入 C# by 大师♂罗莊
/// </summary>
class OpenGLMultiTexture : Examplefirst
{
TextureLoad[] m_texture = new TextureLoad[];
bool multitexturing=false;
/** 检查是否支持扩展 */
string title = "第四章 OpenGl 多重纹理载入"; public OpenGLMultiTexture()
: base()
{
for (int i = ; i < ; i++)
{
m_texture[i] = new TextureLoad();//对象数组必须初始化
}
LoadTexture();
GLUT.SetWindowTitle(title);
/** 初始化 */
if (!initMultiTexture())//和原来不一样,GL.GetString这个函数不能放入动画事件
{
MessageBox.Show("您的硬件和驱动不支持多重纹理");
return;
} } /// <summary>
/// 检查多重纹理支持
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
bool isExtensionSupported(string input)
{
string extension = GL.GetString(GL.GL_EXTENSIONS); return extension.IndexOf(input)>=;
} bool initMultiTexture()
{
/** 检查是否支持扩展 */
if (isExtensionSupported("GL_ARB_multitexture"))
{
return true;
}
else
return false;
} /** 载入纹理数据 */
bool LoadTexture()
{
/// 文件名
String[] fileName = new String[] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" }; /// 载入四幅位图
for (int i = ; i < ; i++)
{
if (m_texture[i].Load(Path.Combine(Application.StartupPath, @"Image\" + fileName[i]).ToString()) == false) /**< 载入位图文件 */
{
MessageBox.Show("无法载入" + fileName[i]);
return false;
} }
return true; } /// <summary>
/// 初始化视口投影,恢复原书的视口
/// </summary>
public override void iniView(int windowWidth, int windowHeight)
{
GLU.Perspective(45.0f, windowWidth / windowHeight, 1.0f, 100.0f);
GL.MatrixMode(GL.GL_MODELVIEW);
GL.LoadIdentity();
GLU.LookAt(, , , // 眼睛位置
, , , // 观察点
, , ); // 怎么看 } /** 用户自定义的卸载函数 */
public new void Dispose()
{
base.Dispose();
for (int i = ; i < ; i++)
{
m_texture[i].FreeImage();
GL.DeleteTextures(, m_texture[i].ID);
}
}
float wrap = ; /**< 用于雾的流动 */ public override void Keyboard(byte key, int x, int y)
{
if (key == ) // Escape 按下,退出
{
this.Dispose();
} /////** 当按下空格时,开启多重纹理 */
if (key == 0x20)
{
multitexturing = true;//开启
}
else
{
multitexturing = false;//按下其他键关闭
}
}
/// <summary>
/// 重载
/// </summary>
/// <param name="currentTime"></param>
public override void Update(float milliseconds)
{
wrap += milliseconds /; //动画 速度请自己调节
Display(); }
/// <summary>
/// 重载,使用Draw方法绘图
/// </summary>
/// <param name="mouseX"></param>
/// <param name="currentTime"></param>
public override void DrawGLScene()
{
Draw();
GLUT.SwapBuffers();
} /** 绘制函数 */
void Draw()
{
/** 用户自定义的绘制过程 */
GL.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
GL.LoadIdentity(); GL.Translatef(0.0f, 0.0f, -10.0f); /** 激活纹理0,并绑定纹理 */
GL.ActiveTextureARB(GL.GL_TEXTURE0_ARB);
GL.Enable(GL.GL_TEXTURE_2D);
GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]); /** 激活纹理1,并绑定纹理 */
GL.ActiveTextureARB(GL.GL_TEXTURE1_ARB); /** 如果多重纹理启用,则启用该纹理 */
if (multitexturing)
GL.Enable(GL.GL_TEXTURE_2D);
else
GL.Disable(GL.GL_TEXTURE_2D); GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]); /** 绘制一个四方形墙面 */
GL.PushMatrix();
GL.Translatef(-2.5f, 0f, 0f);
GL.Scalef(2.0f, 2.0f, 2.0f);
GL.Begin(GL.GL_QUADS); /** 左上点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f, 1.0f);
GL.Vertex3f(-, , ); /** 左下点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f, 0.0f);
GL.Vertex3f(-, -, ); /** 右下点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f, 0.0f);
GL.Vertex3f(, -, ); /** 右上点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f, 1.0f);
GL.Vertex3f(, , ); GL.End(); /**< 绘制结束 */
GL.PopMatrix(); /** 激活纹理0,并绑定纹理 */
GL.ActiveTextureARB(GL.GL_TEXTURE0_ARB);
GL.Enable(GL.GL_TEXTURE_2D);
GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]); /** 激活纹理1,并绑定纹理 */
GL.ActiveTextureARB(GL.GL_TEXTURE1_ARB); /** 如果多重纹理启用,则启用该纹理 */
if (multitexturing)
GL.Enable(GL.GL_TEXTURE_2D);
else
GL.Disable(GL.GL_TEXTURE_2D);
GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]); GL.Translatef(2.5f, , );
GL.Scalef(2.0f, 2.0f, 2.0f);
GL.Begin(GL.GL_QUADS); /** 左上点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
GL.Vertex3f(-, , ); /** 左下点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f);
GL.Vertex3f(-, -, ); /** 右下点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f);
GL.Vertex3f(, -, ); /** 右上点 */
GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f);
GL.Vertex3f(, , );
GL.End();
}
}
}

移植只要改改几个地方就很方便了。

这里我再次提醒大家,因为我们用到非托管库,freeglut.dll。需要把这个DLL拷贝到应用程序目录,由于系统分32位和64位,而默认VS生成项目模板是Any CPU,也就是32、64位自适应的EXE,而OpenGLDotNet和tao 自带freeglut.dll都是32位。

需要自己设置为X86 32位EXE,或者自行下载freeglut 编译一个64位DLL,然后做两个版本EXE。

C#+OpenGL编程之再见小桃子(The Tao Framework)的更多相关文章

  1. OpenGL编程(一)渲染一个指定颜色的背景窗口

    上次已经搭好了OpenGL编程的环境.已经成功运行了第一个程序.可只是照搬书上的代码,并没弄懂其中的原理.这次通过一个小程序来解释使用GLUT库编写OpenGL程序的过程. 程序的入口 与其他程序一样 ...

  2. OpenGL编程指南(第七版)

    OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...

  3. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  4. 在 Mac OS X Yosemite 10.10.5 上配置 OpenGL 编程环境

    这个教程主要参考了youtube上的视频 Getting Started in OpenGL with GLFW/GLEW in Xcode 6 ,这个视频有点问题,不能照搬.本人通过自己摸(瞎)索( ...

  5. 用MFC实现OpenGL编程

    一.OpenGL简介 众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI公司)在他们的图形工作站上开发高质量图像的接口.但最近几年它成为一个非常优秀的开放式 ...

  6. [ZZ]面向对象编程,再见!

    面向对象编程,再见!- 机器学习算法与自然语言处理 https://mp.weixin.qq.com/s/icXBlVOOYLvDnER7cEeCeg https://medium.com/@csca ...

  7. [转]VS 2012环境下使用MFC进行OpenGL编程

    我就不黏贴复制了,直接给出原文链接:VS 2012环境下使用MFC进行OpenGL编程 其它好文链接: 1.OpenGL系列教程之十二:OpenGL Windows图形界面应用程序

  8. VS15 openGL 编程指南 配置库 triangle例子

    最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去 ...

  9. Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤

    http://blog.csdn.net/vagrxie/article/details/4602961 Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤 wri ...

随机推荐

  1. PL/SQL基础2(笔记)

    1 第一个PL/SQL的程序 DECLARE BEGIN DBMS_OUTPUT.PUT_LINE('Hello World!'); END; / --2一个简单的PL/SQL程序 DECLARE v ...

  2. iOS 简单工厂模式

    iOS 简单工厂模式 什么是简单工厂模式? 简单工厂模式中定义一个抽象类,抽象类中声明公共的特征及属性,抽象子类继承自抽象类,去实现具体的操作.工厂类根据外界需求,在工厂类中创建对应的抽象子类实例并传 ...

  3. 当碰到非ARC写的文件时在ARC环境下运行报错时解决办法

  4. fatal error: file '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Dev

    类似这样的错误: fatal error: file '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.pla ...

  5. 关于bitcode~

    最近在做语音识别- 在真机调试的时候一直报 ld: '/Users/Chenglijuan/Documents/语音识别/lib/iflyMSC.framework/iflyMSC(IFlyRecog ...

  6. 每日Scrum--No.7

    Yesterday:学习和设计路线的编程 Today:编写代码 Problem:.在设计查询参观路线的时候,整个逻辑特别的混乱,设想了各种树,图以及网的遍历问题,但经过多次与同学的交流以及网上的查询资 ...

  7. MFC 网络编程 -- 总结

    原文链接:http://www.cnblogs.com/lidabo/archive/2012/07/19/2598734.html 1.基于 TCP 的 socket 编程 /* 服务器端程序流程: ...

  8. PHP添加Redis模块及连接

    上几篇文章介绍了Redis的安装及使用,下面将介绍php如何添加Redis扩展! php手册并没有提供Redis的类和方法,也没有提供相关的扩展模块,但我们可以在Redis的官网下载PHP的扩展,里面 ...

  9. A python tool to static sim.log duration time

    When working ALU IMS Patch team, we need to static the SU duration to add it to the patch report, th ...

  10. noip2008普及组4题题解-rLq

    (啊啊啊终于补到了今天的作业了) 本题地址:http://www.luogu.org/problem/show?pid=1058 题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣 ...