本文基础:

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

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

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

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

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

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using OpenGLDotNet;
  5.  
  6. namespace OpenGLTK
  7. {
  8. ///OpenGLDotNet需要修改
  9. ///glut32.dll ->freeglut.dll
  10. ///GLUT最初是《OpenGL红皮书(第二版)》[注2]中的示例程序。自那以后,GLUT简单、跨平台的特点,使其在各种实际应用中广泛应用。
  11. ///目前最后版本GLUT v3.7的历史可追溯至1998年8月,且该项目似乎已经被废弃。它的许可证禁止任何人发布修改后的库代码。
  12. ///毋庸置疑GLUT已经很老了,真的需要改善。此外,GLUT的许可证与一些软件发行不兼容(如XFree86的)。
  13. ///一个轻量级的,开源的,跨平台的library。支持OpenGL及OpenGL ES,用来管理窗口,读取输入,处理事件等。因为OpenGL没有窗口管理的功能,所以很多热心的人写了工具来支持这些功能,比如早期的glut,现在的freeglut等。
  14. ///修改代码位置 GLU.Functions.cs
  15.  
  16. ///找不到glu32.dll解决方法:
  17. ///glu32.dll 改为->GLU32.dll,具体文件名大小写可以去 系统目录搜索这个文件我的是server2012
  18. ///修改代码位置 GLUT.Functions.cs
  19.  
  20. ///tao->OpenGLDotNet 需要修改的地方
  21. ///函数去掉glu和gl部分,例如
  22. ///GL.glPopMatrix();->GL.PopMatrix();
  23. ///Gl.gl->GL.
  24. ///Gl.GL_->GL.GL_
  25. /// Glu.glu->GLU.
  26. ///当然你可以修改源代码private ->public
  27. ///修改代码位置 GL.CoreDelegates.cs
  28.  
  29. /// <summary>
  30. /// 第二章 Opengl程序框架 C# by 大师♂罗莊
  31. ///
  32. /// </summary>
  33. class Examplefirst : IDisposable
  34. {
  35. String title = "第二章 Opengl程序框架";
  36. ///窗口大小
  37. internal int windowWidth, windowHeight;
  38.  
  39. //当前帧
  40. internal float currentTime, startTime;
  41.  
  42. //鼠标位置
  43. internal int mouseX, mouseY, button, state;
  44. //键盘按下
  45.  
  46. internal byte key;
  47. public Examplefirst()
  48. {
  49. GLConfig.Init(, , title, , , , );
  50. GL.Init(true);
  51. GLUT.KeyboardFunc(Keyboard);
  52. GLUT.MouseFunc(Mouse);
  53. GLUT.IdleFunc(Idle);
  54. GLUT.ReshapeFunc(Reshape);
  55. GLUT.MotionFunc(Motion);
  56. GLUT.DisplayFunc(Display);
  57. }
  58.  
  59. /// <summary>
  60. /// glut键盘回调函数
  61. /// </summary>
  62. /// <param name="key"></param>
  63. /// <param name="x"></param>
  64. /// <param name="y"></param>
  65. public virtual void Keyboard(byte key, int x, int y)
  66. {
  67. this.key = key;
  68. }
  69.  
  70. /// <summary>
  71. /// glut鼠标按下与释放回调函数
  72. /// </summary>
  73. /// <param name="button"></param>
  74. /// <param name="state"></param>
  75. /// <param name="x"></param>
  76. /// <param name="y"></param>
  77. public virtual void Mouse(int button, int state, int x, int y)
  78. {
  79.  
  80. this.button = button;
  81. this.state = state;
  82. this.mouseX = x;
  83. this.mouseY = y;
  84. return;
  85. }
  86.  
  87. /// <summary>
  88. /// glut空闲处理回调函数
  89. /// </summary>
  90. public void Idle()
  91. {
  92. currentTime = System.Environment.TickCount;
  93. Update(currentTime - startTime);
  94. startTime = currentTime;
  95. return;
  96. }
  97.  
  98. /// <summary>
  99. /// glut窗口重置回调函数
  100. /// </summary>
  101. /// <param name="width"></param>
  102. /// <param name="height"></param>
  103. public void Reshape(int width, int height)
  104. {
  105. windowWidth = width;
  106. windowHeight = height;
  107. //防止除零问题
  108. windowHeight = windowWidth > ? windowHeight : ;
  109. InitGL(windowWidth, windowHeight);
  110.  
  111. }
  112.  
  113. /// <summary>
  114. /// glut鼠标移动回调函数
  115. /// </summary>
  116. /// <param name="x"></param>
  117. /// <param name="y"></param>
  118. public void Motion(int x, int y)
  119. {
  120. return;
  121. }
  122.  
  123. /// <summary>
  124. /// glut描绘回调函数
  125. /// </summary>
  126. public void Display()
  127. {
  128. //我感觉用这个得重新设置下lookUP才行
  129. iniView(windowWidth, windowHeight);
  130. DrawGLScene();
  131.  
  132. }
  133.  
  134. /// <summary>
  135. /// 入口点
  136. /// </summary>
  137. public void Run()
  138. {
  139. GLUT.MainLoop();
  140. }
  141.  
  142. /// <summary>
  143. /// 更新用
  144. /// </summary>
  145. public virtual void Update(float milliseconds)
  146. {
  147. if (key == ) // Escape 按下,退出
  148. {
  149. this.Dispose();
  150. }
  151. return;
  152. }
  153.  
  154. /// <summary>
  155. /// 原书的初始化方法,C# by 大师♂罗莊
  156. /// </summary>
  157. /// <param name="windowWidth">窗口宽</param>
  158. /// <param name="windowHeight">窗口高</param>
  159. /// <returns></returns>
  160. Boolean InitGL(int windowWidth, int windowHeight)
  161. {
  162. // 设置视口 viewport
  163. GL.Viewport(, , windowWidth, windowHeight);
  164.  
  165. //启用阴影平滑
  166. GL.ShadeModel(GL.GL_SMOOTH);
  167.  
  168. //启用反走样
  169. GL.Hint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
  170.  
  171. // 设置投影模式 projection matrix
  172. GL.MatrixMode(GL.GL_PROJECTION);
  173. GL.LoadIdentity();
  174. GL.Disable(GL.GL_DITHER);
  175. return true;
  176. }
  177. /// <summary>
  178. /// 初始化视口投影,本例子没有采用原书例子,自定义的视口
  179. /// </summary>
  180. public virtual void iniView(int windowWidth, int windowHeight)
  181. {
  182. GLU.Perspective(, windowWidth / (double)windowHeight, , );
  183. // 选择模型观察矩阵 modelview matrix
  184. GL.MatrixMode(GL.GL_MODELVIEW);
  185. //重置模型观察矩阵
  186. GL.LoadIdentity();
  187. GLU.LookAt(, , , // 眼睛位置
  188. , , , // 观察点
  189. , , ); // 怎么看
  190. }
  191.  
  192. /// <summary>
  193. /// 原书的绘制方法 C# by 大师♂罗莊
  194. /// <param name="currentTime">当前帧</param>
  195. /// </summary>
  196. public virtual void DrawGLScene()
  197. {
  198. // 重置黑色背景
  199. GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  200. GL.Clear(GL.GL_COLOR_BUFFER_BIT);
  201. // 画三角形
  202. GL.Translatef(, , );
  203. GL.Begin(GL.GL_TRIANGLES);
  204. GL.Color3f(, , );
  205. GL.Vertex3f(-, , -);
  206. GL.Color3f(, , );
  207. GL.Vertex3f(, , -);
  208. GL.Color3f(, , );
  209. GL.Vertex3f(, , );
  210. GL.End();
  211. GLUT.SwapBuffers();
  212. }
  213.  
  214. public void Dispose()
  215. {
  216. GLUT.KeyboardFunc(null);
  217. GLUT.MouseFunc(null);
  218. GLUT.IdleFunc(null);
  219. GLUT.ReshapeFunc(null);
  220. GLUT.MotionFunc(null);
  221. GLUT.DestroyWindow(GLUT.GetWindow());
  222. }
  223. }
  224. }

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

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

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

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

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Text;
  6. using System.Windows.Forms;
  7. using OpenGLDotNet;
  8.  
  9. namespace OpenGLTK
  10. {
  11. /// <summary>
  12. /// 自制的纹理载入类 C# by 大师♂罗莊
  13. /// </summary>
  14. class TextureLoad : IDisposable
  15. {
  16. public uint[] ID = new uint[];
  17. Bitmap image;
  18. public bool Load(String fileName)
  19. {
  20. ///原则上材质只应该在初始化时候载入一次,否则会影响性能
  21. if (image != null)
  22. {
  23. return true;
  24. }
  25. FileInfo file = new FileInfo(fileName);
  26. if (file.Exists == false)
  27. {
  28. MessageBox.Show("无法载入" + fileName);
  29. return false;
  30. }
  31. try
  32. {
  33. if (file.Extension.ToUpper() == ".TGA")
  34. {
  35. ///http://blog.csdn.net/zgke/article/details/4667499
  36. ///C# 载入TGA 类,自行参考,这里不再列出
  37. ImageTGA tga = new ImageTGA(fileName);
  38. image = tga.Image;
  39. }
  40. else
  41. {
  42. image = new Bitmap(fileName);
  43. }
  44.  
  45. }
  46. catch (System.ArgumentException)
  47. {
  48. MessageBox.Show("无法载入" + fileName);
  49. return false;
  50. }
  51.  
  52. if (image != null)
  53. {
  54. image.RotateFlip(RotateFlipType.RotateNoneFlipY);
  55. System.Drawing.Imaging.BitmapData bitmapdata;
  56. Rectangle rect = new Rectangle(, , image.Width, image.Height);
  57.  
  58. ///Nearest Linear MipMapped三个纹理实现,本文暂时不考虑
  59. //bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  60. //GL.GenTextures(3, this.texture);
  61.  
  62. //// Create Nearest Filtered Texture
  63. //GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[0]);
  64. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
  65. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
  66. //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);
  67. //// Create Linear Filtered Texture
  68. //GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[1]);
  69. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
  70. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
  71. //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);
  72. //// Create MipMapped Texture
  73. //GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[2]);
  74. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
  75. //GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_NEAREST);
  76. //GL.uBuild2DMipmaps(GL.GL_TEXTURE_2D, (int)GL.GL_RGB, image.Width, image.Height, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
  77. //image.UnlockBits(bitmapdata);
  78.  
  79. /** 生成纹理对象名称 */
  80. GL.GenTextures(, ID);
  81.  
  82. /** 创建纹理对象 */
  83. GL.BindTexture(GL.GL_TEXTURE_2D, ID[]);
  84.  
  85. /** 控制滤波 */
  86. GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);
  87. GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
  88. GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_REPEAT);
  89. GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_REPEAT);
  90.  
  91. bitmapdata = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  92. /** 创建纹理 */
  93. GLU.Build2DMipmaps(GL.GL_TEXTURE_2D, (int)GL.GL_RGB, image.Width,
  94. image.Height, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE,
  95. bitmapdata.Scan0);
  96. image.UnlockBits(bitmapdata);
  97. }
  98. return true;
  99. }
  100.  
  101. public void FreeImage()
  102. {
  103. /** 释放内存 */
  104. if (image != null)
  105. {
  106. image.Dispose();
  107. }
  108. }
  109. public void Dispose()
  110. {
  111. FreeImage();
  112. }
  113. }
  114. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using System.Windows.Forms;
  6. using OpenGLDotNet;
  7.  
  8. namespace OpenGLTK
  9. {
  10. /// <summary>
  11. /// 第四章 OpenGl 多重纹理载入 C# by 大师♂罗莊
  12. /// </summary>
  13. class OpenGLMultiTexture : Examplefirst
  14. {
  15. TextureLoad[] m_texture = new TextureLoad[];
  16. bool multitexturing=false;
  17. /** 检查是否支持扩展 */
  18. string title = "第四章 OpenGl 多重纹理载入";
  19.  
  20. public OpenGLMultiTexture()
  21. : base()
  22. {
  23. for (int i = ; i < ; i++)
  24. {
  25. m_texture[i] = new TextureLoad();//对象数组必须初始化
  26. }
  27. LoadTexture();
  28. GLUT.SetWindowTitle(title);
  29. /** 初始化 */
  30. if (!initMultiTexture())//和原来不一样,GL.GetString这个函数不能放入动画事件
  31. {
  32. MessageBox.Show("您的硬件和驱动不支持多重纹理");
  33. return;
  34. }
  35.  
  36. }
  37.  
  38. /// <summary>
  39. /// 检查多重纹理支持
  40. /// </summary>
  41. /// <param name="input"></param>
  42. /// <returns></returns>
  43. bool isExtensionSupported(string input)
  44. {
  45. string extension = GL.GetString(GL.GL_EXTENSIONS);
  46.  
  47. return extension.IndexOf(input)>=;
  48. }
  49.  
  50. bool initMultiTexture()
  51. {
  52. /** 检查是否支持扩展 */
  53. if (isExtensionSupported("GL_ARB_multitexture"))
  54. {
  55. return true;
  56. }
  57. else
  58. return false;
  59. }
  60.  
  61. /** 载入纹理数据 */
  62. bool LoadTexture()
  63. {
  64. /// 文件名
  65. String[] fileName = new String[] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" };
  66.  
  67. /// 载入四幅位图
  68. for (int i = ; i < ; i++)
  69. {
  70. if (m_texture[i].Load(Path.Combine(Application.StartupPath, @"Image\" + fileName[i]).ToString()) == false) /**< 载入位图文件 */
  71. {
  72. MessageBox.Show("无法载入" + fileName[i]);
  73. return false;
  74. }
  75.  
  76. }
  77. return true;
  78.  
  79. }
  80.  
  81. /// <summary>
  82. /// 初始化视口投影,恢复原书的视口
  83. /// </summary>
  84. public override void iniView(int windowWidth, int windowHeight)
  85. {
  86. GLU.Perspective(45.0f, windowWidth / windowHeight, 1.0f, 100.0f);
  87. GL.MatrixMode(GL.GL_MODELVIEW);
  88. GL.LoadIdentity();
  89. GLU.LookAt(, , , // 眼睛位置
  90. , , , // 观察点
  91. , , ); // 怎么看
  92.  
  93. }
  94.  
  95. /** 用户自定义的卸载函数 */
  96. public new void Dispose()
  97. {
  98. base.Dispose();
  99. for (int i = ; i < ; i++)
  100. {
  101. m_texture[i].FreeImage();
  102. GL.DeleteTextures(, m_texture[i].ID);
  103. }
  104. }
  105. float wrap = ; /**< 用于雾的流动 */
  106.  
  107. public override void Keyboard(byte key, int x, int y)
  108. {
  109. if (key == ) // Escape 按下,退出
  110. {
  111. this.Dispose();
  112. }
  113.  
  114. /////** 当按下空格时,开启多重纹理 */
  115. if (key == 0x20)
  116. {
  117. multitexturing = true;//开启
  118. }
  119. else
  120. {
  121. multitexturing = false;//按下其他键关闭
  122. }
  123. }
  124. /// <summary>
  125. /// 重载
  126. /// </summary>
  127. /// <param name="currentTime"></param>
  128. public override void Update(float milliseconds)
  129. {
  130. wrap += milliseconds /; //动画 速度请自己调节
  131. Display();
  132.  
  133. }
  134. /// <summary>
  135. /// 重载,使用Draw方法绘图
  136. /// </summary>
  137. /// <param name="mouseX"></param>
  138. /// <param name="currentTime"></param>
  139. public override void DrawGLScene()
  140. {
  141. Draw();
  142. GLUT.SwapBuffers();
  143. }
  144.  
  145. /** 绘制函数 */
  146. void Draw()
  147. {
  148. /** 用户自定义的绘制过程 */
  149. GL.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
  150. GL.LoadIdentity();
  151.  
  152. GL.Translatef(0.0f, 0.0f, -10.0f);
  153.  
  154. /** 激活纹理0,并绑定纹理 */
  155. GL.ActiveTextureARB(GL.GL_TEXTURE0_ARB);
  156. GL.Enable(GL.GL_TEXTURE_2D);
  157. GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]);
  158.  
  159. /** 激活纹理1,并绑定纹理 */
  160. GL.ActiveTextureARB(GL.GL_TEXTURE1_ARB);
  161.  
  162. /** 如果多重纹理启用,则启用该纹理 */
  163. if (multitexturing)
  164. GL.Enable(GL.GL_TEXTURE_2D);
  165. else
  166. GL.Disable(GL.GL_TEXTURE_2D);
  167.  
  168. GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]);
  169.  
  170. /** 绘制一个四方形墙面 */
  171. GL.PushMatrix();
  172. GL.Translatef(-2.5f, 0f, 0f);
  173. GL.Scalef(2.0f, 2.0f, 2.0f);
  174. GL.Begin(GL.GL_QUADS);
  175.  
  176. /** 左上点 */
  177. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
  178. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f, 1.0f);
  179. GL.Vertex3f(-, , );
  180.  
  181. /** 左下点 */
  182. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
  183. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f, 0.0f);
  184. GL.Vertex3f(-, -, );
  185.  
  186. /** 右下点 */
  187. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
  188. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f, 0.0f);
  189. GL.Vertex3f(, -, );
  190.  
  191. /** 右上点 */
  192. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
  193. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f, 1.0f);
  194. GL.Vertex3f(, , );
  195.  
  196. GL.End(); /**< 绘制结束 */
  197. GL.PopMatrix();
  198.  
  199. /** 激活纹理0,并绑定纹理 */
  200. GL.ActiveTextureARB(GL.GL_TEXTURE0_ARB);
  201. GL.Enable(GL.GL_TEXTURE_2D);
  202. GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]);
  203.  
  204. /** 激活纹理1,并绑定纹理 */
  205. GL.ActiveTextureARB(GL.GL_TEXTURE1_ARB);
  206.  
  207. /** 如果多重纹理启用,则启用该纹理 */
  208. if (multitexturing)
  209. GL.Enable(GL.GL_TEXTURE_2D);
  210. else
  211. GL.Disable(GL.GL_TEXTURE_2D);
  212. GL.BindTexture(GL.GL_TEXTURE_2D, m_texture[].ID[]);
  213.  
  214. GL.Translatef(2.5f, , );
  215. GL.Scalef(2.0f, 2.0f, 2.0f);
  216. GL.Begin(GL.GL_QUADS);
  217.  
  218. /** 左上点 */
  219. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
  220. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
  221. GL.Vertex3f(-, , );
  222.  
  223. /** 左下点 */
  224. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
  225. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f);
  226. GL.Vertex3f(-, -, );
  227.  
  228. /** 右下点 */
  229. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
  230. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f);
  231. GL.Vertex3f(, -, );
  232.  
  233. /** 右上点 */
  234. GL.MultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
  235. GL.MultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f);
  236. GL.Vertex3f(, , );
  237. GL.End();
  238. }
  239. }
  240. }

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

这里我再次提醒大家,因为我们用到非托管库,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. hadoop2.6完全分布式安装HBase1.1

    本文出自:http://wuyudong.com/archives/119 对于全分布式的HBase安装,需要通过hbase-site.xml文档来配置本机的HBase特性,由于各个HBase之间通过 ...

  2. IOS客户端Coding项目记录(五)

    1:统一修改导航栏的样式,在 AppDelegate.m中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWit ...

  3. 多线程在iOS开发中的应用

    多线程基本概念 01 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 02 线程 2-1 基本概念 1个进程要想执行任务,必须得有线程 ...

  4. Homebrew OS X 不可或缺的套件管理器

    Homebrew OS X 不可或缺的套件管理器,可以说Homebrew就是mac下的apt-get.yum. 1.安装homebrew brew的安装很简单,使用一条ruby命令即可,Mac系统上已 ...

  5. Java线程池的实现

    线程池的作用: 一个线程的周期分为:创建.运行.销毁三个阶段. 处理一个任务时,首先创建一个任务线程,然后执行任务,完了还要销毁线程.而线程只有处于运行状态的时候,才是真的在处理我们交给它的任务,这个 ...

  6. gerrit添加新用户

    默认gerrit的web服务端口为8080,通过apache的反向代理就可以使用标准的80(HTTP)来访问gerrit的web界面,在apache的配置文件httpd.conf添加如下反向代理和HT ...

  7. Sql server存储过程中常见游标循环用法

    用游标,和WHILE可以遍历您的查询中的每一条记录并将要求的字段传给变量进行相应的处理 DECLARE ), ), @A3 INT DECLARE YOUCURNAME CURSOR FOR SELE ...

  8. tair源码分析——leveldb新增的CompactRangeSelfLevel过程

    tair是一个分布式KV存储引擎,当新增机器或者有机器down掉的时候,tair的dataserver会根据ConfigServer生成的新的对照表进行数据的迁移和清理.在数据清理的过程中就用到了在t ...

  9. 一个自定义 HBase Filter -“通过RowKeys来高性能获取数据”

    摘要: 大家在使用HBase和Solr搭建系统中经常遇到的一个问题就是:“我通过SOLR得到了RowKeys后,该怎样去HBase上取数据”.使用现有的Filter性能差劲,网上也没有现成的自定义Fi ...

  10. hbase常用命令总结

    创建表:表名:csliyb:testuser列族:name 例子:create 'csliyb:testuser','name','age' 添加记录: put 'csliyb:testuser',' ...