分享
 
 
 

Direct3D世界的Hello:高洛德渲染的三角形

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

Direct3D的所有操作都是在Direct3D设备上进行的。创建设备要使用Device类的构造函数。

public Device ( System.Int32 adapter , Microsoft.DirectX.Direct3D.DeviceType deviceType ,

System.Windows.Forms.Control renderWindow , Microsoft.DirectX.Direct3D.CreateFlags

behaviorFlags, Microsoft.DirectX.Direct3D.PresentParameters presentationParameters )

Direct3D设备有3种类型,Hardware, Software和Reference类型。其中Reference类型只有在DirectX SDK中的runtime才有。我们通常使用的DirectX Runtime没有这种类型的设备。

创建设备的时候我们还要指定在那个显卡上进行操作,一般情况下,我们指定0,表示使用缺省的显卡。

我们还要把该设备与一个窗口关联起来。

CreateFlags中我们经常使用的参数,就是指定要使用硬件/软件定点处理。

当我们缩放窗口的时候,拉大窗口肯定会导致窗口被重绘,但是缩小窗口并不能导致窗口被绘制。这也是合情合理的,因为缩小窗口只是导致窗口可见面积的减小,

没有必要重新绘制。当然这是一般情况,在我们的例子,我们要求三角形总是在窗口中央,所以这样的表现不被接受。我们需要自己来强制重绘,所以,我们在Form1_Paint()事件中加入了this.Invalidate()函数。

但是这样又引入了另外的问题,运行修改后的程序后,我们发现我们绘制的内容不见了。这是因为在Windows Form中不是所有的绘制都发生在Paint中,因为Windows XP支持透明窗口,这个透明处理是由操作系统自动完成的,这就说明在Paint事件之外会发生一些绘制操作,Windows会用缺省的信息来重绘窗口,这导致我们绘制的内容被覆盖掉。这就是为什么我们要在我们的Form类的构造函数种使用SetStyle函数了。

(??为什么加入了Invalidate()后会出现这种现象?

我的看法,不对的地方还请高手指教了。嘿嘿。

我们是先Render,然后才调用Invalidate()的。Invalidate()触发Windows的Piant外绘制,我们的绘制被覆盖。移动的时候,反复这样清除,导致闪烁,所以

就有了我们看到的现象。

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

这一语句告诉Windows 我们的窗口不是透明的,并要求所有的绘制都要发生在Paint事件中。否则,我们会发现我们绘制的内容根本看不到,当移动窗口的时候,会隐隐看到我们绘制的三角形在闪烁。大家可以试试看,在我的机器上,不是很明显。

在绘制三角形的时候,我们使用了TransfomredColored的顶点格式。这种格式就如他的名字一样,是已经转换过的,对于这种格式的顶点,Direct3D不再做Lighting, View Transform,Projection Transform.我们在数据中指定的坐标值就是这些顶点要显示的地方。

而且我们可以看到,绘制出来的三角形内部已经被填充了,可是我们并没有做任何类似的操作。这其实是一种渲染模式(Shading Mode, 不知道这么翻译对不对)。

高洛德(Gouraud)渲染,还有Flat Shading Mode和Phong Shading Mode.

(Gouraud渲染很有用的,尤其是在用多个三角形描述一个曲面/对象的时候,面对几千个上万个三角形,你不可能自己去计算每个三角形的光照吧。Gouraud可以根据每个三角形面和光源的角度自动计算这些三角形顶点的具体颜色和亮度,然后用差值平滑处理三角形内部的点,这样就可以形成真实的物体了。具体来说是这样,

每个三角形是是一个平面,有自己的法向矢量,光线也有自己的矢量,根据这个三角形面和光线的角度可以计算出这个三角形的顶点的具体光照情况,然后根据材料特性就可以计算出这些顶点的具体颜色、亮度等。然后对于三角形内部的其他点,可以用差值平滑处理,计算出这些点的颜色和亮度信息。具体怎么算,我也不知道,呵呵,

我不是搞算法的,不关心这个。

如果你把顶点数据的格式改成 PositonColored,你会发现,又看不到我们绘制的东西了,呵呵,我们下面会知道为什么。

好了,下面是这节的例子。

#region Using directives

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

#endregion

namespace Ch01

{

partial class Form1 : Form

{

private Device device = null;

public Form1()

{

InitializeComponent();

this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true );

}

public void InitializeGraphics()

{

PresentParameters para = new PresentParameters();

para.Windowed = true;

para.SwapEffect = SwapEffect.Discard;

device = new Device( 0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, para );

}

private void Form1_Paint(object sender, PaintEventArgs e)

{

device.Clear( ClearFlags.Target, Color.Blue, 1.0f, 0 );

CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];

verts[0].Position = new Vector4( this.Width / 2.0f, 50.0f, 0.5f, 1.0f );

verts[0].Color = Color.Aqua.ToArgb();

verts[1].Position = new Vector4( this.Width - this.Width / 5.0f, this.Height - ( this.Height / 5.0f ), 0.5f, 1.0f );

verts[1].Color = Color.Black.ToArgb();

verts[2].Position = new Vector4( this.Width / 5.0f, this.Height - ( this.Height / 5.0f ), 0.5f, 1.0f );

verts[2].Color = Color.Purple.ToArgb();

device.BeginScene();

device.VertexFormat = CustomVertex .TransformedColored .Format;

device.DrawUserPrimitives( PrimitiveType.TriangleList, 1, verts );

device.EndScene();

device.Present();

this.Invalidate();

}

static void Main()

{

using ( Form1 frm = new Form1() )

{

// Show our form and initialize our graphics engine

frm.Show();

frm.InitializeGraphics();

Application.Run( frm );

}

}

}

}

BeginScene()和EndScene()是配对的。必需调用Present()函数后,我们绘制的东西才能显示出来。

DrawUserPrimitives()是具体的绘制函数,还有个类似的函数DrawPrimitives(),这个函数用起来就比较麻烦了,得创建顶点缓冲,然后通过Device的SetStreamSource()函数设置到设备上去,并且要把顶点数据,写到这个顶点缓冲中去,然后才能够调用DrawPrimitives()绘制。

在使用DrawUserPrimitives()的时候,我们使用了PrimitiveType.TrangleList,这里涉及了一个基本概念,3D Primitive.在Direct3D中支持多种类型。

其中比较重要的是,Triangle List, Triangle Strip, Triangle Fan.具体概念,可以参考其他的资料。并且这些Primitive在不同的Shading Mode中的含义也是不同的,起码在Gouraud shading mode中是这样,TriangleList的每个三角形被单独平滑处理,TriangleStrip中的三角形被作为一个整体来平滑,TriangleFan呢?

也应该和TriangleStrip一样吧,没有试过,有心人给确认一下吧。

而且组织顶点数据的时候还涉及了Backface Culling的概念,也就是说顶点的顺序也是有讲究的,不能乱来。否则,打死你也看不到你画的东西,除非你在device.RenderState.CullMode中关掉了Backface Culling.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有