SharpGL學習筆記(十一) 光源創建的綜合例子:光源參數可調節的測試場景

来源:http://www.cnblogs.com/hackpig/archive/2016/08/26/5811922.html
-Advertisement-
Play Games

燈光的測試例子:光源參數可以調節的測試場景 先看一下測試場景和效果。 場景中可以切換視圖, 以方便觀察三維體和燈光的位置。環境光,漫射光,鏡面反射光都可以在四種顏色間切換。 燈光位置和攝像機位置(LookAt)可以輸入數值或者點動調節,也可以按鍵盤的QEWASD六個鍵進行調節。 你還會註意到:球體對 ...


 

燈光的測試例子:光源參數可以調節的測試場景

 

先看一下測試場景和效果。

場景中可以切換視圖, 以方便觀察三維體和燈光的位置。環境光,漫射光,鏡面反射光都可以在四種顏色間切換。

燈光位置和攝像機位置(LookAt)可以輸入數值或者點動調節,也可以按鍵盤的QEWASD六個鍵進行調節。

你還會註意到:球體對光的效果要敏感柔和些,而那個六面體BOX看來效果不好。這是因為燈光對頂點發生作用。在程式裡面,球休的頂點數量有20*10,而BOX只有4*6個,而且還重合了一些頂點。

這一點,在3dsmax的全局光照裡面表現很明顯,做為牆壁的box頂點數量越大,計算出來光照效果越好

還有,界面上燈光位置是 -1,5,1,1  前三個是x,y,z, 後面的一個1不是坐標,它取值0或者1,表示燈光是定向光源(directonal),還是定位光源(positional)。

 

代碼如下:

  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 
 14     public partial class SharpGLForm : Form
 15     {
 16         private float rotation = 0.0f;
 17         private bool isRotate = false;
 18         private bool isLines = false;
 19         private bool isFrontView = false;
 20         private bool isLeftView = false;
 21         private bool isTopView = false;
 22         private bool isPerspective = true;
 23         private float[] lightPos = new float[] { -1, -3, 1, 1 };
 24         private float[] lightSphereColor = new float[] { 1f, 1f, 1f };
 25         private IList<float[]> lightColor = new List<float[]>();
 26         private double[] lookatValue = { 1, 1, 2, 0, 0, 0, 0, 1, 0 };
 27         private IList<double[]> viewDefaultPos = new List<double[]>();
 28         public SharpGLForm()
 29         {
 30             InitializeComponent();
 31         }
 32 
 33         private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
 34         {
 35             OpenGL gl = openGLControl.OpenGL;
 36             gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
 37             gl.LoadIdentity();
 38             gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
 39 
 40             drawGrid(gl);
 41             DrawCube(ref gl, 1.5f,-1f, -2f, isLines);
 42             drawOneSphere(ref gl,-3,-2,-4,isLines);
 43             if (isRotate)
 44                 rotation += 3.0f;
 45         }
 46 
 47         private void setLightColor(OpenGL gl)
 48         {
 49             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, lightColor[0]);
 50             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, lightColor[1]);
 51             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, lightColor[2]);
 52         }
 53 
 54         private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
 55         {
 56             OpenGL gl = openGLControl.OpenGL;
 57 
 58             //四個視圖的預設位置
 59             viewDefaultPos.Add(new double[] { 1, 1, 2, 0, 0, 0, 0, 1, 0 });     //透視
 60             viewDefaultPos.Add(new double[] { 0, 0, 2, 0, 0, 0, 0, 1, 0 });     //前視 
 61             viewDefaultPos.Add(new double[] { 5, 0, 0, 0, 0, 0, 0, 1, 0 });     //左視
 62             viewDefaultPos.Add(new double[] { 0, 13, 0, -1, 0, 0, 0, 1, 0 });   //頂視
 63             lookatValue =(double[])viewDefaultPos[0].Clone();
 64 
 65             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //環境光(ambient light)
 66             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //漫射光(diffuse light)
 67             lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //鏡面反射光(specular light)
 68 
 69             setLightColor(gl);
 70             gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
 71             
 72             gl.Enable(OpenGL.GL_LIGHTING);
 73             gl.Enable(OpenGL.GL_LIGHT0);
 74 
 75             gl.ClearColor(0, 0, 0, 0);
 76         }
 77 
 78         private void drawOneSphere(ref OpenGL gl, float xPos, float yPos, float zPos, bool isLine)
 79         {
 80             gl.PushMatrix();
 81             {
 82                 gl.Translate(xPos, yPos, zPos);
 83                 gl.Color(lightSphereColor);
 84                 drawSphere(gl,1,20,10,isLine);
 85             }
 86             gl.PopMatrix();
 87         }
 88 
 89         private void openGLControl_Resized(object sender, EventArgs e)
 90         {
 91 
 92             OpenGL gl = openGLControl.OpenGL;
 93             gl.MatrixMode(OpenGL.GL_PROJECTION);
 94             gl.LoadIdentity();
 95             gl.Perspective(40.0f, (double)Width / (double)Height, 0.01, 100.0);
 96 
 97 
 98             gl.LookAt(lookatValue[0], lookatValue[1], lookatValue[2],
 99                 lookatValue[3], lookatValue[4], lookatValue[5],
100                 lookatValue[6], lookatValue[7], lookatValue[8]);
101             
102             gl.MatrixMode(OpenGL.GL_MODELVIEW);
103             updateLabInfo();
104         }
105 
106         internal void DrawCube(ref OpenGL Gl, float xPos, float yPos, float zPos, bool isLine)
107         {
108             Gl.PushMatrix();
109             Gl.Translate(xPos, yPos, zPos);
110             if (isLine)
111                 Gl.Begin(OpenGL.GL_LINE_STRIP);
112             else
113                 Gl.Begin(OpenGL.GL_POLYGON);
114 
115             /** 頂面 */
116             Gl.Vertex(0.0f, 0.0f, 0.0f);
117             Gl.Vertex(0.0f, 0.0f, -1.0f);
118             Gl.Vertex(-1.0f, 0.0f, -1.0f);
119             Gl.Vertex(-1.0f, 0.0f, 0.0f);
120 
121             /** 前面 */
122             Gl.Vertex(0.0f, 0.0f, 0.0f);
123             Gl.Vertex(-1.0f, 0.0f, 0.0f);
124             Gl.Vertex(-1.0f, -1.0f, 0.0f);
125             Gl.Vertex(0.0f, -1.0f, 0.0f);
126 
127             /** 右面 */
128             Gl.Vertex(0.0f, 0.0f, 0.0f);
129             Gl.Vertex(0.0f, -1.0f, 0.0f);
130             Gl.Vertex(0.0f, -1.0f, -1.0f);
131             Gl.Vertex(0.0f, 0.0f, -1.0f);
132 
133             /** 左面*/
134             Gl.Vertex(-1.0f, 0.0f, 0.0f);
135             Gl.Vertex(-1.0f, 0.0f, -1.0f);
136             Gl.Vertex(-1.0f, -1.0f, -1.0f);
137             Gl.Vertex(-1.0f, -1.0f, 0.0f);
138 
139             /** 底面 */
140             Gl.Vertex(0.0f, 0.0f, 0.0f);
141             Gl.Vertex(0.0f, -1.0f, -1.0f);
142             Gl.Vertex(-1.0f, -1.0f, -1.0f);
143             Gl.Vertex(-1.0f, -1.0f, 0.0f);
144 
145 
146             /** 後面 */
147             Gl.Vertex(0.0f, 0.0f, 0.0f);
148             Gl.Vertex(-1.0f, 0.0f, -1.0f);
149             Gl.Vertex(-1.0f, -1.0f, -1.0f);
150             Gl.Vertex(0.0f, -1.0f, -1.0f);
151             Gl.End();
152             Gl.PopMatrix();
153         }
154 
155         void drawGrid(OpenGL gl)
156         {
157             //繪製過程
158             gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存當前屬性
159             gl.PushMatrix();                        //壓入堆棧
160             gl.Translate(0f, -2f, 0f);
161             gl.Color(0f, 0f, 1f);
162 
163             //在X,Z平面上繪製網格
164             for (float i = -50; i <= 50; i += 1)
165             {
166                 //繪製線
167                 gl.Begin(OpenGL.GL_LINES);
168                 {
169                     if (i == 0)
170                         gl.Color(0f, 1f, 0f);
171                     else
172                         gl.Color(0f, 0f, 1f);
173 
174                     //X軸方向
175                     gl.Vertex(-50f, 0f, i);
176                     gl.Vertex(50f, 0f, i);
177                     //Z軸方向 
178                     gl.Vertex(i, 0f, -50f);
179                     gl.Vertex(i, 0f, 50f);
180 
181                 }
182                 gl.End();
183             }
184             gl.PopMatrix();
185             gl.PopAttrib();
186         }
187 
188       
189         void drawSphere(OpenGL gl,double radius,int segx,int segy,bool isLines)
190         {
191             gl.PushMatrix();
192             gl.Translate(2f, 1f, 2f);
193             var sphere = gl.NewQuadric();
194             if (isLines)
195                 gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);
196             else
197                 gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);
198             gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
199             gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
200             gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);
201             gl.Sphere(sphere, radius, segx, segy);
202             gl.DeleteQuadric(sphere);
203             gl.PopMatrix();
204         }
205 
206         private void moveObject(int obj,string keyName)
207         {
208             //obj==0移動視圖
209             switch (keyName)
210             {
211                 case "btnQ":
212                     if (obj == 0) ++lookatValue[1];   //y
213                     else
214                         ++lightPos[1];
215                     break;
216                 case "btnE":
217                     if (obj == 0) --lookatValue[1];
218                     else
219                         --lightPos[1];
220                     break;
221                 case "btnW":
222                     if (obj == 0) --lookatValue[2];   //z
223                     else
224                        --lightPos[2];
225                     break;
226                 case "btnS":
227                     if (obj == 0)  ++lookatValue[2];
228                     else
229                         ++lightPos[2];
230                     break;
231                 case "btnA":
232                     if (obj == 0) --lookatValue[0];  //X
233                     else
234                        --lightPos[0];
235                     break;
236                 case "btnD":
237                     if (obj == 0)  ++lookatValue[0];
238                     else
239                         ++lightPos[0];
240                     break;
241             }
242         }
243 
244         private void rbPerspective_CheckedChanged(object sender, EventArgs e)
245         {
246             switch (((RadioButton)sender).Name)
247             {
248                 case "rbPerspective":
249                     isPerspective = !isPerspective;
250                     isFrontView = false;
251                     isTopView = false;
252                     isLeftView = false;
253                     break;
254                 case "rbLeft":
255                      isLeftView = !isLeftView;
256                     isFrontView = false;
257                     isPerspective = false;
258                     isTopView = false;
259                     break;
260                 case "rbFront":
261                      isFrontView = !isFrontView;
262                     isTopView = false;
263                     isPerspective = false;
264                     isLeftView = false;
265                     break;
266                 case "rbTop":
267                      isTopView = !isTopView;
268                     isPerspective = false;
269                     isLeftView = false;
270                     isFrontView = false;
271                     break;
272                 default:
273                     return;
274             }
275             setViewDefaultValue();
276             openGLControl_Resized(null, null);
277         }
278 
279         private void cbxRotate_CheckedChanged(object sender, EventArgs e)
280         {
281             var cbx=((CheckBox)sender);
282             switch (cbx.Name)
283             {
284                 case "cbxRotate":
285                     isRotate = cbx.Checked;
286                     break;
287                 case "cbxLines":
288                     isLines = cbx.Checked;
289                     break;
290                 case "cbxLightOff":
291                     if (!cbx.Checked)
292                         this.openGLControl.OpenGL.Enable(OpenGL.GL_LIGHT0);
293                     else
294                         this.openGLControl.OpenGL.Disable(OpenGL.GL_LIGHT0);
295                     break;
296             }
297         }
298 
299         private void SharpGLForm_Load(object sender, EventArgs e)
300         {
301             this.cbxLightType.SelectedIndex = 0;
302             updateLabInfo();
303         }
304 
305         private void updateLabInfo()
306         {
307             tbLightPos.Text = string.Format("{0},{1},{2},{3}", lightPos[0], lightPos[1], lightPos[2], lightPos[3]);
308             tbLookAt.Text = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}", lookatValue[0], lookatValue[1], lookatValue[2],
309                 lookatValue[3], lookatValue[4], lookatValue[5], lookatValue[6], lookatValue[7], lookatValue[8]);
310         }
311 
312         private void rbWhite_CheckedChanged(object sender, EventArgs e)
313         {
314             var rad = ((RadioButton)sender);
315             var lightType = this.cbxLightType.SelectedIndex;
316             if (rad.Checked)
317             {
318                 switch (rad.Name)
319                 {
320                     case "rbWhite":
321                         lightColor[lightType][0] = 1f;
322                         lightColor[lightType][1] = 1f;
323                         lightColor[lightType][2] = 1f;
324                         lightColor[lightType][3] = 1f;
325                         break;
326                     case "rbRed":
327                         lightColor[lightType][0] = 1f;
328                         lightColor[lightType][1] = 0f;
329                         lightColor[lightType][2] = 0f;
330                         lightColor[lightType][3] = 1f;
331                         break;
332                     case "rbGreen":
333                         lightColor[lightType][0] = 0f;
334                         lightColor[lightType][1] = 1f;
335                         lightColor[lightType][2] = 0f;
336                         lightColor[lightType][3] = 1f;
337                         break;
338                     case "rbBlue":
339                         lightColor[lightType][0] = 0f;
340                         lightColor[lightType][1] = 0f;
341                         lightColor[lightType][2] = 1f;
342                         lightColor[lightType][3] = 1f;
343                         break;
344                 }
345                 setLightColor(openGLControl.OpenGL);
346             }
347         }
348 
349         private void cbxLightType_SelectedIndexChanged(object sender, EventArgs e)
350         {
351             var lightType = this.cbxLightType.SelectedIndex;
352             if (lightType >= 0)
353                 judgeColor(lightColor[lightType]);
354         }
355 
356         private void judgeColor(float[] color)
357         {
358             if (color[0] == 1f && color[1] == 1f && color[2] == 1f && color[3] == 1f)
359                 rbWhite.Checked = true;
360             else if (color[0] == 1f && color[1] == 0f && color[2] == 0f && color[3] == 1f)
361                 rbRed.Checked = true;
362             else if (color[0] == 0f && color[1] == 1f && color[2] == 0f && color[3] == 1f)
363                 rbGreen.Checked = true;
364             else if (color[0] == 0f && color[1] == 0f && color[2] == 1f && color[3] == 1f)
365                 rbBlue.Checked = true;   
366         }
367 
368         private void btnQ_Click(object sender, EventArgs e)
369         {
370             moveObject(radioButton1.Checked ? 0 : 1,((Button)sender).Name);
371             openGLControl_Resized(null, null);
372             openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
373         }
374 
375         private void setViewDefaultValue()
376         {
377             if (isPerspective)
378             {
379                 lookatValue = (double[])viewDefaultPos[0].Clone();
380             }
381             else if (isFrontView)
382             {
383                 lookatValue = (double[])viewDefaultPos[1].Clone();
384             }
385             else if (isLeftView)
386             {
387                 lookatValue = (double[])viewDefaultPos[2].Clone();
388             }
389             else if (isTopView)
390             {
391                 lookatValue = (double[])viewDefaultPos[3].Clone();
392             }
393         }
	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.前言 在學習Socket之前,先來學習點網路相關的知識吧,自己學習過程中的一些總結,Socket是一門很高深的學問,本文只是Socket一些最基礎的東西,大神請自覺繞路。 傳輸協議 TCP:Transmission Control Protocol 傳輸控制協議TCP是一種面向連接(連接導向)的 ...
  • 1.什麼是SQL語句 sql語言:結構化的查詢語言。(Structured Query Language),是關係資料庫管理系統的標準語言。 它是一種解釋語言:寫一句執行一句,不需要整體編譯執行。語法特點:1.沒有“ ”,字元串使用‘ ’包含2.沒有邏輯相等,賦值和邏輯相等都是=3.類型不再是最嚴格 ...
  • 這裡主要看一下Hello World代碼 ...
  • 阿裡巴巴-矢量圖標庫 此網站 1、能搜到官方和個人提供的優秀圖標 再也不用擔心不會用photoshop~再也不用擔心沒圖標,做不出界面了~ 2、能生成複雜的字體 IP地址:http://iconfont.cn/ 網站界面: 轉自:http://Www.CnBlogs.Com/WebEnh/ 感謝We ...
  • 依賴屬性,簡單的說,在WPF控制項應用過程中,界面上直接可以引用的屬性 如:<Button Content="aaa"></Button> Content稱為Button的依賴屬性 當我們自定義控制項時,如何添加依賴屬性呢 1、添加屬性 2、註冊屬性 然後在應用自定義控制項時,就能直接設置屬性了,例如: ...
  • 學習了Spring.NET+NHibernate的框架,覺得Spring.NET框架不夠輕量,配置來配置去的比較頭疼,所以把Spring.NET換成了Autofac框架,同時加入WCF框架整了一個組合。 本來想把NHibernate換成EF的,因為現在普通用的.net 4.0,但是.net 4.0里 ...
  • 在一個系統裡面,往往有很多菜單項目,每個菜單項對應一個頁面,一般用戶只需要用到一些常用的功能,如果每次都需要去各個層次的菜單裡面去找對應的功能,那確實有點繁瑣。特別是在菜單繁多,而客戶又對系統整體不熟悉的情況下,如果有一個類似瀏覽器的收藏夾模塊,把一些常用的菜單連接保存起來,每次從這個收藏夾主頁去找... ...
  • 自定義標題欄 一、設計界面樣式 <UserControl x:Class="WpfApplication6.TitleListControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="htt ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...