笔者学到光源这一节,遇到的问题就比较多了,收集了一些如下所述:

  • (1) 导入的3ds模型,如果没有材质光照效果很奇怪.
    如下图
  • (2) 导入的3ds模型,有材质,灯光效果发暗,材质偏色,效果也很奇怪.

    下图中是有灯光的,但效果惨不忍睹.

  • (3) 场景引入灯光后,场景中的物体的颜色就全部消失了,即合引入颜色材质,效果也是怪怪的.

    如下图中的栅格,它原本应该是蓝色的.

  • (4) 场景中有物体引入材质后,整个场景的颜色就变得很奇怪

    下图中球体引入材质后,整个场景的颜色就变得很奇怪了.

  • (5) 导入的3ds模型,贴图颜色失真。

  • 下图中的茶壶,柱体,地板的贴图分别对应上图材质图片,可以看到经过纹理映射后,贴图颜色失真。
    这种问题并不是光源的问题,但是我也在这里一并列出来。

像这些问题,因为不好形容,网上也找不到合适的答案.群里的高手们也不屑回答这些菜鸟问题,因此只好自力更生了.

我先上一段演示场景的代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using SharpGL;
 10
 11 namespace SharpGLWinformsApplication1
 12 {
 13     /// <summary>
 14     /// 原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/
 15     /// </summary>
 16     public partial class SharpGLForm : Form
 17     {
 18         private float rotation = 0.0f,rotation2=0f,rotation3=0f;
 19         SharpGL.SceneGraph.Assets.Texture textureBox = new SharpGL.SceneGraph.Assets.Texture();
 20
 21         float[] fLightPosition = new float[4] { 16f, 9f, -18f, 0f };// 光源位置
 22         float[] fLightAmbient = new float[4] { 1f, 1f, 1f, 0f };// 环境光参数
 23         float[] fLightDiffuse = new float[4] { 1f, 1f, 1f,0f };// 漫射光参数
 24
 25         float[] fLightPosition2 = new float[4] { -7f, 5f, 2f, 0f };// 光源位置
 26         float[] fLightAmbient2 = new float[4] { 0f, 0f, 1f, 0f };// 环境光参数
 27         float[] fLightDiffuse2 = new float[4] { 0f, 0f, 1f, 0f };// 漫射光参数
 28
 29         bool f1 = false;
 30
 31         public SharpGLForm()
 32         {
 33             InitializeComponent();
 34         }
 35
 36         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
 37         {
 38             OpenGL gl = openGLControl.OpenGL;
 39             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 40             gl.LoadIdentity();
 41             gl.Rotate(rotation3, 0, 1, 0);
 42             drawGrid(gl);
 43             drawLightPT(gl);
 44             drawLightPT2(gl);
 45             drawTextrueBox(gl, 1, 0, 2);
 46             drawSphere(gl, 2, 20, 20, false);
 47
 48             moveLightA(gl);
 49             rotation3+=0.1f;
 50         }
 51
 52
 53         private void moveLightA(OpenGL gl)
 54         {
 55             if (!f1)
 56                 --fLightPosition[0];
 57             else
 58                 ++fLightPosition[0];
 59             if (fLightPosition[0] > 15f)
 60             {
 61                 f1 = !f1;
 62             }
 63             else if (fLightPosition[0] < -25f)
 64             {
 65                 f1 = !f1;
 66             }
 67             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, fLightPosition);//光源位置
 68         }
 69
 70
 71
 72         private void drawLightPT(OpenGL gl)
 73         {
 74             gl.PushMatrix();
 75             {
 76                 gl.Disable(OpenGL.GL_TEXTURE_2D);
 77                 gl.Color(0f,1f, 1f);
 78                 gl.Scale(0.2, 0.2, 0.2);
 79                 gl.Translate(fLightPosition[0]-5 , fLightPosition[1]+5, fLightPosition[2]);
 80                 drawBox(gl, 0, 0, 0);
 81             }
 82             gl.PopMatrix();
 83         }
 84
 85         private void drawLightPT2(OpenGL gl)
 86         {
 87
 88             rotation2+=4f;
 89             gl.PushMatrix();
 90             {
 91                 gl.LoadIdentity();
 92                 gl.Disable(OpenGL.GL_TEXTURE_2D);
 93                 gl.Color(0f, 1f, 1f);
 94                 gl.Scale(0.2, 0.2, 0.2);
 95                 gl.Rotate(rotation2, 0, 1, 0);
 96                 gl.Translate(-28 , 8 , 5);
 97
 98                 drawBox(gl, 0, 0, 0);
 99             }
100             gl.PopMatrix();
101         }
102
103         private void drawTextrueBox(OpenGL gl, float xPos, float yPos, float zPos)
104         {
105             rotation += 3.0f;
106             gl.PushMatrix();
107             {
108                 textureBox.Bind(gl);
109                 gl.Enable(OpenGL.GL_TEXTURE_2D);
110                 gl.Rotate(rotation, 0, 1, 0);
111                 gl.Translate(-1, 2, -5);
112                 gl.Scale(3, 3, 3);
113                 drawBox(gl,xPos, yPos, zPos);
114             }
115             gl.PopMatrix();
116         }
117
118         private void drawBox(OpenGL gl, float xPos, float yPos, float zPos)
119         {
120             gl.PushMatrix();
121             gl.Translate(xPos, yPos, zPos);
122
123             gl.Begin(OpenGL.GL_QUADS);
124
125             //前
126             gl.TexCoord(0, 0); gl.Vertex(0, 0, 0);
127             gl.TexCoord(1, 0); gl.Vertex(-1, 0, 0);
128             gl.TexCoord(1, 1); gl.Vertex(-1, -1, 0);
129             gl.TexCoord(0, 1); gl.Vertex(0, -1, 0);
130
131             //底
132             gl.TexCoord(0, 0); gl.Vertex(0, 0, 0);
133             gl.TexCoord(1, 0); gl.Vertex(0, 0, -1);
134             gl.TexCoord(1, 1); gl.Vertex(-1, 0, -1);
135             gl.TexCoord(0, 1); gl.Vertex(-1, 0, 0);
136
137             //左
138             gl.TexCoord(0, 0); gl.Vertex(-1, 0, 0);
139             gl.TexCoord(1, 0); gl.Vertex(-1, 0, -1);
140             gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1);
141             gl.TexCoord(0, 1); gl.Vertex(-1, -1, 0);
142
143             //右
144             gl.TexCoord(0, 0); gl.Vertex(0, 0, 0);
145             gl.TexCoord(1, 0); gl.Vertex(0, 0, -1);
146             gl.TexCoord(1, 1); gl.Vertex(0, -1, -1);
147             gl.TexCoord(0, 1); gl.Vertex(0, -1, 0);
148
149             //后
150             gl.TexCoord(0, 0); gl.Vertex(0, 0, -1);
151             gl.TexCoord(1, 0); gl.Vertex(-1, 0, -1);
152             gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1);
153             gl.TexCoord(0, 1); gl.Vertex(0, -1, -1);
154
155             //顶
156             gl.TexCoord(0, 0); gl.Vertex(0, -1, 0);
157             gl.TexCoord(1, 0); gl.Vertex(0, -1, -1);
158             gl.TexCoord(1, 1); gl.Vertex(-1, -1, -1);
159             gl.TexCoord(0, 1); gl.Vertex(-1, -1, 0);
160
161
162             gl.End();
163             gl.PopMatrix();
164
165         }
166
167         void drawSphere(OpenGL gl, double radius, int segx, int segy, bool isLines)
168         {
169
170             gl.PushMatrix();
171             gl.Disable(OpenGL.GL_TEXTURE_2D);
172             gl.Translate(-7f, -1f, 2f);
173             var sphere = gl.NewQuadric();
174
175             if (isLines)
176                 gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);
177             else
178                 gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);
179             gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
180             gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
181             gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);
182             gl.Sphere(sphere, radius, segx, segy);
183             gl.DeleteQuadric(sphere);
184             gl.PopMatrix();
185
186         }
187
188
189
190
191         void drawGrid(OpenGL gl)
192         {
193             //关闭纹理和光照
194             gl.Disable(OpenGL.GL_TEXTURE_2D);
195             gl.Disable(OpenGL.GL_LIGHTING);
196
197             //绘制过程
198             gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存当前属性
199             gl.PushMatrix();                        //压入堆栈
200             gl.Translate(0f, -2f, 0f);
201             gl.Color(0f, 0f, 1f);
202
203             //在X,Z平面上绘制网格
204             for (float i = -50; i <= 50; i += 1)
205             {
206                 //绘制线
207                 gl.Begin(OpenGL.GL_LINES);
208                 {
209                     if (i == 0)
210                         gl.Color(0f, 1f, 0f);
211                     else
212                         gl.Color(0f, 0f, 1f);
213
214                     //X轴方向
215                     gl.Vertex(-50f, 0f, i);
216                     gl.Vertex(50f, 0f, i);
217                     //Z轴方向
218                     gl.Vertex(i, 0f, -50f);
219                     gl.Vertex(i, 0f, 50f);
220
221                 }
222                 gl.End();
223             }
224             gl.PopMatrix();
225             gl.PopAttrib();
226             gl.Enable(OpenGL.GL_LIGHTING);
227         }
228
229         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
230         {
231             OpenGL gl = openGLControl.OpenGL;
232             textureBox.Create(gl, "image.bmp");
233
234             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, fLightAmbient);//环境光源
235             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, fLightDiffuse);//漫射光源
236             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, fLightPosition);//光源位置
237
238             gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_AMBIENT, fLightAmbient2);//环境光源
239             gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_DIFFUSE, fLightDiffuse2);//漫射光源
240             gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, fLightPosition2);//光源位置
241
242             gl.Enable(OpenGL.GL_LIGHTING);//开启光照
243             gl.Enable(OpenGL.GL_LIGHT0);
244             gl.Enable(OpenGL.GL_LIGHT1);
245
246             gl.Enable(OpenGL.GL_NORMALIZE);
247             gl.ClearColor(0, 0, 0, 0);
248
249         }
250
251         private void openGLControl_Resized(object sender, EventArgs e)
252         {
253             OpenGL gl = openGLControl.OpenGL;
254             gl.MatrixMode(OpenGL.GL_PROJECTION);
255             gl.LoadIdentity();
256             gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);
257             gl.LookAt(-2, 3, -7, -2, 0, 0, 0, 1, 0);
258             gl.MatrixMode(OpenGL.GL_MODELVIEW);
259         }
260
261
262
263     }
264 }

效果如下图:

场景中有两个光源,一个在X方向左右运行,一个绕点点在转圈.

Box上了材质贴图,球体没有材质.

从效果上看,已经解决了开头所述的问题(3),(4),我们提下关键点在哪里:

1. 第194,195行必须有,否则画栅格时会受到场景中的灯光,或者材质设定的影响,栅格原来颜色就没有了.

  这个其实就是因为OpenGL是个状态机,其它部分代码改变了某些状态,画栅格时就会继承改变.

2. 同样原道理,第171行必须关闭纹理,否会受到Box材质设置状态的影响,球就不会是白色的了.

3. 第246行必须有,它用来自动归一化法线方向,因为光照效果由顶点和法线方向决定.

  这就是问题(1),(2)之所以有问题的原因.

  而导入的3ds模型,其画三角形的函数中也需要注意Normal()函数的向量值有没有方向问题.
  下图是修正了法线后的光照效果,可以看到是正常的.

   

4.  对于问题5,因为在检查了灯光与贴图后都是正常的, 所以问题只会在出现在贴图的时候。

经检测,是在导入3ds模形的代码中,关于读取贴图的一个函数Build2DMipmaps()中,把RGB换BGR即可。

GL.Build2DMipmaps(OpenGL.GL_TEXTURE_2D, 3, image.Width, image.Height, OpenGL.GL_BGR, OpenGL.GL_UNSIGNED_BYTE, bitmapdata.Scan0);

可以看到,效果正常了。

5. 最后一个困绕笔者的问题是物体旋转中心点的问题.这个话题跟灯光无关,在这个场景中恰好碰到了这个问题,发现原来是知识上的一个盲点.

  演示场景中,你会看到Box并不是绕世界坐标系的原点(绿色线的交汇点)在转,而是沿指定位置为轴心在转.

  是绕世界坐标原点转,还是绕你指定的坐标为轴转动,关键在于你是先Translate(),还是先Rotate().  读者可以参考下演示代码,然后自己尝试一下就知道了.

本节源代码下载

原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

转载于:https://www.cnblogs.com/hackpig/p/5824745.html

SharpGL学习笔记(十二) 光源例子:解决光源场景中的常见问题相关推荐

  1. ROS学习笔记十二:使用gazebo在ROS中仿真

    想要在ROS系统中对我们的机器人进行仿真,需要使用gazebo. gazebo是一种适用于复杂室内多机器人和室外环境的仿真环境.它能够在三维环境中对多个机器人.传感器及物体进行仿真,产生实际传感器反馈 ...

  2. 吴恩达《机器学习》学习笔记十二——机器学习系统

    吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...

  3. Python语言入门这一篇就够了-学习笔记(十二万字)

    Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...

  4. OpenCV学习笔记(十二)——图像分割与提取

    在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...

  5. ROS学习笔记十二:使用roswtf

    ROS学习笔记十二:使用roswtf 在使用ROS过程中,roswtf工具可以为我们提供ROS系统是否正常工作的检查作用. 注意:在进行下列操作之前,请确保roscore没有运行. 检查ROS是否安装 ...

  6. Polyworks脚本开发学习笔记(十二)-输出和读取文本文件

    Polyworks脚本开发学习笔记(十二)-输出和读取文本文件 Polyworks作为一个测量工具,将测量的数据方便的导出到文本文件则是一项必须的功能.在DATA_FILE这个命令下提供了很多子命令用 ...

  7. 【现代机器人学】学习笔记十二:轮式移动机器人

    目录 轮式机器人类型 全向轮式机器人 建模 单个全向轮是怎么运动的 多个全向轮是如何带动底盘运动的 运动规划和反馈控制 非完整约束轮式移动机器人 建模 独轮车 差速驱动机器人 车型机器人 非完整移动机 ...

  8. 【theano-windows】学习笔记十二——卷积神经网络

    前言 按照进度, 学习theano中的卷积操作 国际惯例, 来一波参考网址 Convolutional Neural Networks (LeNet) 卷积神经网络如何应用在彩色图像上? 卷积小知识 ...

  9. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 变量的地址就是指针,存放指针的变量就是指针变量(因而又叫作地址变量 address variable); 这个地址编号本身就是一个无符号的整数,在32位系统下为4字节(8位 ...

  10. Vue.js 学习笔记 十二 Vue发起Ajax请求

    首先需要导入vue-resource.js,可以自己下载引入,也可以通过Nuget下载,它依赖于Vue.js. 全局使用方式: Vue.http.get(url,[options]).then(suc ...

最新文章

  1. HTTP Host 头攻击,这是什么鬼?
  2. postman 并发测试
  3. PAT甲级1151 LCA in a Binary Tree (30 分):[C++题解]LCA、最低公共祖先、哈希表映射
  4. 二十五、求单点的最短路径
  5. VTK:PolyData之DownsamplePointCloud
  6. mysql子查询存到另一张表_MySQL多表查询与子查询
  7. PMP读书笔记(第10章)
  8. [USACO14JAN]Recording the Moolympics
  9. fatfs 文件属性_FATFS文件系统剖析(全).
  10. opencv基本绘图函数--点,线,矩形,圆等
  11. android怎么oauth2公版认证,Android中腾讯微博OAuth认证(一)---获取RequestToken
  12. 测试几个免费在线音乐识别器
  13. 单因子方差分析Python实现(小鸡增肥)
  14. 分层确定性钱包(HD Wallets)
  15. git-linux终端命令详解
  16. 编辑混合变形变形器(Blend Shape)
  17. 芝加哥大学计算机科学,芝加哥大学计算机科学
  18. 帝国CMS7.5微信扫码登录插件 帝国cms插件分享
  19. 重磅长篇精读:国内前端行业十日谈
  20. OPENWRT入门之三------刷入openwrt固件和首次使用

热门文章

  1. 事实证明:市场没有换来任何技术
  2. 能否设计变容量发动机
  3. 吾讲救活公司的办法,当事人还在玩手机,应该怎么办
  4. 全网首发:安装Python(或其他软件)出现0x80072f7d错误的解决办法
  5. 求最大公约数欧几里得算法
  6. java多脚本顺序运行_关于eclipse里运行selenium脚本的顺序问题
  7. QT 静态链接库和动态链接库
  8. 大学物理光学思维导图_思维导图真的需要学吗?(附资料)
  9. ttk.treeview鼠标悬浮文字_电竞新选择,罗技G键盘、鼠标、耳机三件套给力体验...
  10. 代理(Proxy)和背靠背用户代理(B2BUA)