国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

DirectX9 3D快速上手 3

2024-07-21 02:16:09
字體:
供稿:網(wǎng)友
菜鳥學堂:

directx9 3d快速上手 3



by sssa2000

4/15/2005

我們這里暫時先跳過,乏味的索引緩沖和深度緩沖的內(nèi)容,先看看怎么在3d空間中實現(xiàn)一個東西,給自己來點成就感。

正好sdk的向?qū)б彩沁@么安排的,呵呵,那我們就繼續(xù)從向?qū)С霭l(fā)吧,以tutorial 3為例子。



這個例子主要講解運用變換矩陣來實現(xiàn)物體的變換,學過圖形學或者線性代數(shù)的肯定就很容易理解,沒學過的,找點這方面的資料看看就可以了。



先看看這個例子實現(xiàn)了什么,編譯運行,噢,相比前面兩個例子,有耳目一新的感覺,一個三角形繞著y軸旋轉(zhuǎn)。



相比tutorial 2,多了2個函數(shù):onresetdevice和setupmatrices。其中有注釋,中文由我翻譯,e文太差,翻譯得不好不要b4我啊



         public void onresetdevice(object sender, eventargs e)



         {



              device dev = (device)sender;



              // turn off culling, so we see the front and back of the triangle



//關(guān)閉剔除,所以我們可以看見前面的和背面的三角形



              dev.renderstate.cullmode = cull.none;



              // turn off d3d lighting, since we are providing our own vertex colors



//關(guān)閉燈光,因為我們已經(jīng)提供了自己的顏色



              dev.renderstate.lighting = false;



         }




 


         private void setupmatrices()



         {



              // for our world matrix, we will just rotate the object about the y-axis.



              // set up the rotation matrix to generate 1 full rotation (2*pi radians)



              // every 1000 ms. to avoid the loss of precision inherent in very high



              // floating point numbers, the system time is modulated by the rotation



              // period before conversion to a radian angle.



 // 在世界坐標中,我們要繞y旋轉(zhuǎn),建立旋轉(zhuǎn)矩陣產(chǎn)生每秒360度的旋轉(zhuǎn),為了避免浮點數(shù)中的位數(shù)造成的時間上的損失,我們在轉(zhuǎn)變?yōu)榛《惹埃瑥娭普{(diào)整系統(tǒng)時間



              int  itime  = environment.tickcount % 1000;



              float fangle = itime * (2.0f * (float)math.pi) / 1000.0f;



              device.transform.world = matrix.rotationy( fangle );




 


              // set up our view matrix. a view matrix can be defined given an eye point,



              // a point to lookat, and a direction for which way is up. here, we set the



              // eye five units back along the z-axis and up three units, look at the



              // origin, and define "up" to be in the y-direction.



//建立觀察矩陣,它可以被定義為視點,就像一個攝像機一樣。這里我們設(shè)置在z軸-5,y軸3的位置



              device.transform.view = matrix.lookatlh( new vector3( 0.0f, 3.0f,-5.0f ), new vector3( 0.0f, 0.0f, 0.0f ), new vector3( 0.0f, 1.0f, 0.0f ) );




 


              // for the projection matrix, we set up a perspective transform (which



              // transforms geometry from 3d view space to 2d viewport space, with



              // a perspective divide making objects smaller in the distance). to build



              // a perpsective transform, we need the field of view (1/4 pi is common),



              // the aspect ratio, and the near and far clipping planes (which define at



              // what distances geometry should be no longer be rendered).



//射影矩陣,我們建立一個透視變換(透視變換把3d空間變換到2d視口,造成透視的效果),為了建立透視變換,我們需要視覺空間,(通常是1/4 pi)縱橫比 和 遠距離剔除(遠處物體不渲染)



              device.transform.projection = matrix.perspectivefovlh( (float)math.pi / 4, 1.0f, 1.0f, 100.0f );



         }




 


所有的新東西都在這里了,一共不到10條語句,簡單吧?有幾點要解釋一下。



dev.renderstate.cullmode = cull.none;



這一句,或許很多人會疑惑,首先了解一下dx的背面剔除功能,和現(xiàn)實中一樣,我們同一時間只能夠看到一個物體的一面,看不到它的背面,這就是背面剔除。cull是一個枚舉,一共3個值:



counterclockwise



3



cull back faces with counterclockwise vertices.



clockwise



2



cull back faces with clockwise vertices.



none



1



do not cull back faces.



如果我們指定了背面剔除的方式,那么我們就看不到物體的背面,這樣當三角形轉(zhuǎn)過來的時候我們就看不到轉(zhuǎn)過來的東西,所以設(shè)置為none,如果不理解,可以在程序中修改一下這一句話,就能很直觀的理解了。



這個例子就這么多內(nèi)容,當然你也可以把rotatey改為,rotatex, rotatez等等,可以更加好的理解一下這個例子。


 



 


接下來我們來了解一下mesh。

對我們初學者來說mesh應(yīng)該是一個讓人激動的東西,讓我們來看看介紹:mesh可以用來儲存任何類型的圖形數(shù)據(jù),但主要用來封裝復雜的模型。mesh類同樣也有一些用來提高渲染物體性能的方法。用mesh你可以從外部文件讀入3d的模型例如.3ds文件,這樣我們就可以在3d max中做好模型,然后讀入程序,想想看,一個游戲的雛形是不是已經(jīng)在你腦海了呢?



mesh對象內(nèi)部也包含了很多幾何體的模型,我們來看看怎么使用它,因為使用它比使用頂點要快捷方便得多,一會你就會深刻體會到。



首先我們要先建立一個mesh對象    private mesh mesh = null;



然后mesh = mesh.box(device,2.0f,2.0f,2.0f); 這樣我們就建立了一個長寬高都為2的立方體,很簡單吧?如果你用頂點來建立的話,最快的方法,即使用索引緩沖器,深度緩沖器也要寫8個頂點得值,還要setstreamsource等等繁瑣的工作,這一切在mesh中都替我們完成了。當然,mesh內(nèi)置的幾何形體還有很多,比如圓柱,茶壺等等,你可以一個一個的試一下。



我們來看看核心的drawbox函數(shù):


 


this is equivalent

        private void drawbox(float yaw, float pitch, float roll, float x, float y, float z)



        {



            angle += 0.01f;



            device.transform.world = matrix.rotationyawpitchroll(yaw, pitch, roll) * matrix.translation(x, y, z);



            material boxmaterial = new material();



            boxmaterial.ambient = color.white; //環(huán)境色



            boxmaterial.diffuse = color.white; //漫反射



            device.material = boxmaterial;



            mesh.drawsubset(0);



        }



先介紹matrix.rotationyawpitchroll方法,看看他的原形:

public static matrix rotationyawpitchroll(
    float yaw, //偏移量,即繞y軸的轉(zhuǎn)動角度
    float pitch,//斜度,即繞x軸的角度
    float roll//滾動,即繞z的角度
);


 


材質(zhì)(materials)描述了這樣的一種屬性。你可以指定物體如何反射環(huán)境光以及散射(diffuse)光線,鏡面高光(specular highlights)(少后會討論它)看起來是什么樣,以及物體是否完全反射(emit)光線。 這里創(chuàng)建了一個新的材質(zhì),它的環(huán)境顏色(ambient color)(注:環(huán)境顏色和環(huán)境光的顏色是不同的^_^)和散射顏色值都被設(shè)置為白色。使用白色表示它會反射所有的光線。接下來,我們把材質(zhì)賦予了device的material屬性,這樣direct3d就知道渲染時使用那種材質(zhì)數(shù)據(jù)。



這里介紹一點關(guān)于光線和色彩的知識:環(huán)境色(ambient color),當其為黑色時,表示(環(huán)境光)不會影響材質(zhì)的顏色,當環(huán)境色變淺時,它就會照亮材質(zhì),并將兩種顏色混和起來,從而影響材質(zhì)的顏色。如何場景中有環(huán)境光,那么這些光的顏色和亮度就會控制環(huán)境色對于最終材質(zhì)顏色的影響程度)。把材質(zhì)改為沒有紅色成分的顏色(比如綠色)會使物體再次變?yōu)楹谏ㄗⅲ阂驗榇藭r物體不會反射紅色,紅色的光線被物體全部吸收了),改為含一些紅色成分的顏色(比如灰色gray)會使物體呈現(xiàn)深灰色。



mesh會被分為一系列的子集(subsets)(依據(jù)屬性緩沖的大小來分配),同時使用一個叫做“drawsubset”的方法來渲染。使用mesh類創(chuàng)建的普通圖元總是只有一個基于0的子集。所以使用了mesh.drawsubset(0)




 


下面附上這個例子的全部代碼:



using system;



using system.drawing;



using system.collections;



using system.componentmodel;



using system.windows.forms;



using system.data;



using microsoft.directx;



using microsoft.directx.direct3d;




 


namespace chapter5code



{



     /// <summary>



     /// summary description for form1.



     /// </summary>



     public class form1 : system.windows.forms.form



     {



        private device device = null;



        private mesh mesh = null;




 


         /// <summary>



         /// required designer variable.



         /// </summary>



         private system.componentmodel.container components = null;



        private float angle = 0.0f;




 


         public form1()



         {



              //



              // required for windows form designer support



              //



              initializecomponent();




 


            this.setstyle(controlstyles.allpaintinginwmpaint | controlstyles.opaque, true);



         }




 


        /// <summary>



        /// we will initialize our graphics device here



        /// </summary>



        public void initializegraphics()



        {



            // set our presentation parameters



            presentparameters presentparams = new presentparameters();




 


            presentparams.windowed = true;



            presentparams.swapeffect = swapeffect.discard;



            presentparams.autodepthstencilformat = depthformat.d16;



            presentparams.enableautodepthstencil = true;




 


            // create our device



            device = new device(0, devicetype.hardware, this, createflags.softwarevertexprocessing, presentparams);



            mesh = mesh.box(device, 2.0f, 2.0f, 2.0f);



        }




 


        private void setupcamera()



        {



            device.transform.projection = matrix.perspectivefovlh((float)math.pi / 4, this.width / this.height, 1.0f, 100.0f);



            device.transform.view = matrix.lookatlh(new vector3(0,0, 18.0f), new vector3(), new vector3(0,1,0));



            device.renderstate.ambient = color.darkblue;




 


            device.lights[0].type = lighttype.directional;



            device.lights[0].diffuse = color.darkblue;



            device.lights[0].direction = new vector3(0, -1, -1);



            device.lights[0].update ();



            device.lights[0].enabled = true;




 


        }




 


        protected override void onpaint(system.windows.forms.painteventargs e)



        {



            device.clear(clearflags.target | clearflags.zbuffer, color.cornflowerblue, 1.0f, 0);




 


            setupcamera();




 


            device.beginscene();




 


            // draw our boxes



            drawbox(angle / (float)math.pi, angle / (float)math.pi * 2.0f, angle / (float)math.pi / 4.0f, 0.0f, 0.0f, 0.0f);



            //drawbox(angle / (float)math.pi, angle / (float)math.pi / 2.0f, angle / (float)math.pi * 4.0f, 5.0f, 0.0f, 0.0f);



           // drawbox(angle / (float)math.pi, angle / (float)math.pi * 4.0f, angle / (float)math.pi / 2.0f, -5.0f, 0.0f, 0.0f);




 


          //  drawbox(angle / (float)math.pi, angle / (float)math.pi * 2.0f, angle / (float)math.pi / 4.0f, 0.0f, -5.0f, 0.0f);



          //  drawbox(angle / (float)math.pi, angle / (float)math.pi / 2.0f, angle / (float)math.pi * 4.0f, 5.0f, -5.0f, 0.0f);



          //  drawbox(angle / (float)math.pi, angle / (float)math.pi * 4.0f, angle / (float)math.pi / 2.0f, -5.0f, -5.0f, 0.0f);




 


         //   drawbox(angle / (float)math.pi, angle / (float)math.pi * 2.0f, angle / (float)math.pi / 4.0f, 0.0f, 5.0f, 0.0f);



           drawbox(angle / (float)math.pi, angle / (float)math.pi / 2.0f, angle / (float)math.pi * 4.0f, 5.0f, 5.0f, 0.0f);



            drawbox(angle / (float)math.pi, angle / (float)math.pi * 4.0f, angle / (float)math.pi / 2.0f, -5.0f, 5.0f, 0.0f);




 


            device.endscene();




 


            device.present();




 


            this.invalidate();



        }




 


        private void drawbox(float yaw, float pitch, float roll, float x, float y, float z)



        {



            angle += 0.01f;




 


            device.transform.world = matrix.rotationyawpitchroll(yaw, pitch, roll) * matrix.translation(x, y, z);



            material boxmaterial = new material();



            boxmaterial.ambient = color.white;



            boxmaterial.diffuse = color.white;



            device.material = boxmaterial;



            mesh.drawsubset(0);



        }




 


        /// <summary>



         /// clean up any resources being used.



         /// </summary>



         protected override void dispose( bool disposing )



         {



              if( disposing )



              {



                   if (components != null)



                   {



                       components.dispose();



                   }



              }



              base.dispose( disposing );



         }




 


         #region windows form designer generated code



         /// <summary>



         /// required method for designer support - do not modify



         /// the contents of this method with the code editor.



         /// </summary>



         private void initializecomponent()



         {



              this.components = new system.componentmodel.container();



              this.size = new size(800,600);



              this.text = "form1";



         }



         #endregion




 


         /// <summary>



         /// the main entry point for the application.



         /// </summary>



        static void
main
()



        {



            using (form1 frm = new form1())



            {



                // show our form and initialize our graphics engine



                frm.show();



                frm.initializegraphics();



                application.run(frm);



            }



        }



     }



}



不知道大家注意到?jīng)]有,我注釋掉了很多drawbox函數(shù)的調(diào)用,你也可以把它改過來,運行看看,你會發(fā)現(xiàn)一個問題,就是如果你畫9個box和你畫一個box,旋轉(zhuǎn)的速度是不一樣的,因為這里并沒有像上個例子那樣對時間有強制的調(diào)整。這個例子里面還有一些是關(guān)于燈光的,我們馬上就會講到,其實從字面也可以看出來是什么意思。接下來我們就要去讀入我們自己的模型了,激動啊。



2005-4-15


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 威宁| 恩平市| 霸州市| 宜川县| 花莲县| 诏安县| 香河县| 伊宁县| 宣汉县| 贺兰县| 新营市| 塔河县| 综艺| 永昌县| 都昌县| 梧州市| 侯马市| 弋阳县| 承德县| 永安市| 宁明县| 宁夏| 广饶县| 二连浩特市| 武陟县| 新民市| 昌乐县| 偃师市| 藁城市| 英山县| 伊宁县| 扎兰屯市| 合山市| 海宁市| 绥化市| 江源县| 乡城县| 五原县| 腾冲县| 丹寨县| 合川市|