图片1000 pixel gun 3d怎么设置

Pixel产品大全_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
喜欢此文档的还喜欢
Pixel产品大全
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢图形(针对 Visual Basic 6.0 用户)
图形(针对 Visual Basic 6.0 用户)
Visual Studio 2005
在 Visual Basic 6.0 中,可以使用多种图形方法和属性在 Form 或 PictureBox 控件上绘制图形。Visual Basic 6.0 中的图形是以 Windows 图形设备接口 (GDI) API 为基础的。
在 Visual Basic 2005 中,图形由封装 GDI+ API 的
命名空间提供。GDI+ 对 Visual Basic 6.0 的图形功能进行了扩展,但是方法不可兼容。
在 Visual Basic 6.0 中,图形方法仅应用于 Form 对象和 PictureBox 控件。 在 Visual Basic 2005 中,图形方法可应用于窗体和支持
事件的任何控件,包括 、 和
控件。此外,图形方法也可用于任何支持
属性的控件,包括 、 和
在 Visual Basic 6.0 中,图形方法可从任何事件过程调用;AutoRedraw 属性用于当从 Paint 事件以外的事件调用图形方法时保持图形。 在 Visual Basic 2005 中,图形方法应仅从 Paint 事件过程调用,或对于一些所有者描述的控件,从各种 Draw 事件过程(、 等)调用。AutoRedraw 属性不再被支持,并且不是必需的,因为 Paint 和 Draw 事件可以自动保持图形。
在 Visual Basic 6.0 中,ClipControls 属性用于控制窗体或控件的绘制。设置为 True 时,仅重新绘制新公开的区域,这从理论上来说可提高性能。
Visual Basic 2005 中没有 ClipControls 属性的等效项;GDI+ 的性能增强和最新的视频适配器使该属性不再是必需的。
在 Visual Basic 6.0 中,DrawMode 属性控制在一个图案上绘制另一个图案时图形对象的颜色。此属性仅影响单色或低分辨率显示器(256 色或更低)。
DrawMode 属性在 Visual Basic 2005 中没有等效项;当前的显示器不再需要此属性。
在 Visual Basic 6.0 中,DrawStyle 属性控制使用 Line 方法绘制的线的外观。如果 DrawWidth 属性设置为大于 1 的值,则 DrawStyle 属性不起作用,线将始终为实线。 在 Visual Basic 2005 中,通过设置 DrawLine 方法使用的 System.Drawing.Pen 类的
属性来控制线的外观;线宽与此属性无关。
在 Visual Basic 6.0 中,DrawWidth 属性决定线的粗细(以像素为单位);DrawWidth 属性通常在执行图形方法前设置。 在 Visual Basic 2005 中,System.Drawing.Pen 控件的 Pen.Width 属性决定线的粗细;可以在创建 Pen 时作为参数设置 Width 属性,或在创建 Pen 后设置 Pen.Width。如果未指定 Pen.Width 属性,则默认值为 1 个像素。
在 Visual Basic 6.0 中,窗体或 PictureBox 控件的 Image 属性返回位图的句柄;该句柄可赋给 Picture 属性,或者作为一个值传递给 Windows API 调用。 在 Visual Basic 2005 中,位图不再具有句柄;实际位图本身作为
类型的对象传递。Bitmap 控件可赋给 PictureBox 控件的
属性,但不能传递给 Windows API 调用。
在 Visual Basic 6.0 中,通过指定左上角和右下角坐标以及可选参数 B,可使用Line 方法来绘制矩形。FillColor 属性用于以某种纯色填充矩形,而 FillStyle 属性以交叉线图案填充矩形。 在 Visual Basic 2005 中, 方法用于绘制矩形边框, 方法用于填充矩形。FillRectangle 以
对象作为参数。 替换 FillColor 属性, 类的成员替换 FillStyle 属性。
在 Visual Basic 6.0 中,窗体或 PictureBox 控件的 Point 方法用于返回位于指定点的像素的颜色值。尽管 Point 方法可用于不包含图片的窗体或控件,但它最常用于从赋给 Picture 属性的某个位图中检索颜色。 在 Visual Basic 2005 中,Point 方法不再存在。可以使用 M:System.Drawing.Bitmap.GetPixel(System.Int32,System.Int32) 方法从位图检索颜色值。对于不包含图片的窗体或控件,可以查询
在 Visual Basic 6.0 中,Print 方法用于在窗体或 PictureBox 控件上显示文本。用于显示文本的字体由窗体或控件的 Font 属性决定,颜色由 ForeColor 属性决定。Print 方法不提供对文本位置的控制,只能水平显示文本。 在 Visual Basic 2005 中,使用 DrawString 方法显示文本。字体由
对象决定,颜色由
决定;两者都作为参数传递给 DrawString 方法。DrawString 方法还具有可决定文本起始位置的 X 和 Y 参数。还有一个利用
对象的可选 Format 参数,可用来垂直显示文本。
在 Visual Basic 6.0 中,PSet 方法用于更改窗体或 PictureBox 控件上的像素颜色。如果 DrawWidth 属性设置为大于 1 的值,PSet 方法将绘制实心圆。如果使用了被省略的 ForeColor ,可通过另一个可选参数指定颜色。 在 Visual Basic 2005 中,没有 PSet 方法的等效项。若要更改窗体或 PictureBox 控件上单个像素的颜色,可使用 DrawEllipse 方法绘制一个高度和宽度都为 1 个像素的圆。若要复制 PSet 在 DrawWidth 大于 1 时的功能,请使用 FillEllipse 方法。
下面的代码示例演示 Visual Basic 6.0 和 Visual Basic 2005 在编码方法上的不同之处。
下面的代码演示如何在运行时在窗体上绘制线条。Visual Basic 6.0 示例使用 Line 方法;它以起始点和结束点的 X 和 Y 坐标以及颜色(可选)作为参数。Visual Basic 2005 示例使用 DrawLine 方法,该方法以
对象以及起始点和结束点的 X 和 Y 坐标作为参数。
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
' Draw a solid black line 200 twips from the top of the form.
Line (0, 200) - (ScaleWidth, 200), vbBlack
' Visual Basic 2005
Private Sub Form1_Paint(ByVal sender As Object, ByVal e _
As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Draw a solid black line 25 pixels from the top of the form.
e.Graphics.DrawLine(Pens.Black, 0, 25, Me.Width, 25)
下面的代码演示如何在运行时在窗体上绘制虚线。在 Visual Basic 6.0 示例中,DrawStyle 属性决定线条的外观。Visual Basic 2005 示例使用
对象设置 DashStyle 属性以决定外观。
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
' Draw a dotted line 200 twips from the top of the form.
Me.DrawStyle = vbDot
Line (0, 200) - (ScaleWidth, 200), vbBlack
' Visual Basic 2005
Private Sub Form1_Paint1(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Draw a dotted black line 25 pixels from the top of the form.
Dim LPen As New System.Drawing.Pen(System.Drawing.Color.Black)
LPen.DashStyle = Drawing2D.DashStyle.Dot
e.Graphics.DrawLine(LPen, 0, 25, Me.Width, 25)
下面的代码演示如何在运行时在窗体上绘制不同粗细的线条。Visual Basic 6.0 示例使用 DrawWidth 属性。Visual Basic 2005 示例使用 Pens 对象的 Width 属性。
' Visual Basic 6.0
Private Sub Form_Paint()
' Draw a line with a thickness of 1 pixel.
DrawWidth = 1
Line (0, 200)-(ScaleWidth, 200), vbBlack
' Draw a line with a thickness of 5 pixels.
DrawWidth = 5
Line (0, 400)-(ScaleWidth, 400), vbBlack
' Draw a line with a thickness of 10 pixels.
DrawWidth = 10
Line (0, 600)-(ScaleWidth, 600), vbBlack
' Visual Basic 2005
Private Sub Form1_Paint2(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Draw a line with a thickness of 1 pixel.
Dim TPen As New System.Drawing.Pen(System.Drawing.Color.Black, 1)
e.Graphics.DrawLine(TPen, 0, 25, Me.Width, 25)
' Draw a line with a thickness of 5 pixels.
TPen.Width = 5
e.Graphics.DrawLine(TPen, 0, 50, Me.Width, 50)
' Draw a line with a thickness of 10 pixels.
TPen.Width = 10
e.Graphics.DrawLine(TPen, 0, 75, Me.Width, 75)
下面的代码演示如何在运行时在窗体上绘制圆。在 Visual Basic 6.0 示例中使用 Circle 方法;它以中心点的 X 和 Y 坐标、半径以及颜色(可选)作为参数。Visual Basic 2005 示例使用 DrawEllipse 方法,该方法以 Pen 对象、边界矩形左上角的 X 和 Y 坐标以及宽度和高度作为参数。
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
' Draw a 1000 twip diameter red circle
Circle (500, 500), 500, vbRed
' Visual Basic 2005
Private Sub Form1_Paint3(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Draw a 70 pixel diameter red circle.
e.Graphics.DrawEllipse(Pens.Red, 0, 0, 70, 70)
下面的代码演示如何在运行时在窗体上绘制两个矩形,一个以纯色填充,另一个以交叉线图案填充。在 Visual Basic 6.0 示例中,FillColor 和 FillStyle 属性与 Line 方法一起使用。使用 B 参数调用 Line 方法绘制矩形。
Visual Basic 2005 示例使用 Graphics.Rectangle 方法绘制轮廓,以及以 Brush 对象作为参数的 Graphics.FillRectangle 方法。本示例使用 SolidBrush 和 HatchBrush 两个控件。 注意
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
' Draw a solid red rectangle.
FillColor = vbRed
FillStyle = vbSolid
Line (10, 10)- (), vbRed, B
' Draw a rectangle filled with a crosshatch pattern.
FillColor = vbBlack
FillStyle = vbCross
Line (10, 500)- (), vbBlack, B
' Visual Basic 2005
Private Sub Form1_Paint4(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Draw a solid red rectangle.
Dim SBrush As New System.Drawing.SolidBrush _
(System.Drawing.Color.Red)
e.Graphics.DrawRectangle(Pens.Red, 2, 2, 70, 40)
e.Graphics.FillRectangle(SBrush, 2, 2, 70, 40)
' Draw a rectangle filled with a crosshatch pattern.
Dim HBrush As New System.Drawing.Drawing2D.HatchBrush( _
System.Drawing.Drawing2D.HatchStyle.Cross, _
System.Drawing.Color.Black, System.Drawing.Color.Transparent)
e.Graphics.DrawRectangle(Pens.Black, 2, 40, 70, 40)
e.Graphics.FillRectangle(HBrush, 2, 40, 70, 40)
下面的代码演示运行时在窗体上显示图像的图形方法。Visual Basic 6.0 示例使用 PaintPicture 方法。Visual Basic 2005 示例使用 DrawImage 方法。
' Visual Basic 6.0
Private Sub Form_Paint()
' Create a stdPicture object.
Dim Pict1 As New stdPicture
Pict1 = LoadPicture("C:\Windows\Greenstone.bmp")
PaintPicture Pict1, 0, 0
' Visual Basic 2005
Private Sub Form1_Paint5(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Create a Bitmap object.
Dim Pict1 As New Bitmap("C:\Windows\Greenstone.bmp")
e.Graphics.DrawImage(Pict1, 0, 0)
下面的代码演示运行时在窗体上显示文本字符串的图形方法。Visual Basic 6.0 示例使用 Print 方法。Visual Basic 2005 示例使用 DrawString 方法。
' Visual Basic 6.0
Private Sub Form_Paint()
Me.Font.Size = 24
Me.Font.Bold = True
Me.ForeColor = vbRed
Print "Hello World!"
' Visual Basic 2005
Private Sub Form1_Paint6(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim TextFont As New System.Drawing.Font("Arial", 24, FontStyle.Bold)
Dim TextBrush As New System.Drawing.SolidBrush(System.Drawing.Color.Red)
e.Graphics.DrawString("Hello World!", TextFont, TextBrush, 10, 10)
TextFont.Dispose()
TextBrush.Dispose()
下面的代码演示运行时决定窗体上的字符串大小,然后在周围绘制矩形的图形方法。Visual Basic 6.0 示例使用 TextHeight 和
TextWidth 方法。Visual Basic 2005 示例使用
方法,该方法返回一个
' Visual Basic 6.0
Private Sub Form_Paint()
Me.Font.Size = 24
Me.Font.Bold = True
Me.ForeColor = vbRed
Print "Hello World!"
Line (0, 0)-(TextWidth("Hello World!"), _
TextHeight("Hello World!")), vbBlack, B
' Visual Basic 2005
Private Sub Form1_Paint7(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim TextFont As New System.Drawing.Font("Arial", 24, FontStyle.Bold)
Dim TextBrush As New System.Drawing.SolidBrush(System.Drawing.Color.Red)
e.Graphics.DrawString("Hello World!", TextFont, TextBrush, 10, 10)
Dim TextSize As New System.Drawing.SizeF
TextSize = e.Graphics.MeasureString("Hello World!", TextFont)
e.Graphics.DrawRectangle(Pens.Black, 10, 10, TextSize.Width, TextSize.Height)
TextFont.Dispose()
TextBrush.Dispose()
下面的示例演示运行时更改窗体上单个像素颜色的图形方法。Visual Basic 6.0 示例使用 PSet 方法。Visual Basic 2005 示例使用 DrawEllipse 方法,其 Height 和 Width 参数均设置为 1。
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
Me.DrawWidth = 1
PSet (), vbRed
' Visual Basic 2005
Private Sub Form1_Paint8(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
e.Graphics.DrawEllipse(Pens.Red, 70, 70, 1, 1)
下面的代码演示在运行时确定窗体上图像中指定位置像素的颜色,然后以该颜色绘制矩形的图形方法。Visual Basic 6.0 示例使用 Point 方法检索颜色值。Visual Basic 2005 示例使用
在 Visual Basic 6.0 中,默认度量单位是缇数;在 Visual Basic 2005 中,默认度量单位是像素。
' Visual Basic 6.0
Private Sub Form_Paint()
Dim PixelColor As Long
Picture1.Picture = LoadPicture("C:\Windows\Greenstone.bmp")
PixelColor = Picture1.Point(10, 10)
FillColor = PixelColor
Line (0, 0)-(100, 500), PixelColor, B
' Visual Basic 2005
Private Sub Form1_Paint9(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim Pict1 As New Bitmap("C:\Windows\Greenstone.bmp")
Picture1.Image = Pict1
Dim PixelColor As Color = Pict1.GetPixel(4, 4)
Dim PixelBrush As New SolidBrush(PixelColor)
e.Graphics.FillRectangle(PixelBrush, 0, 0, 100, 100)
下表列出了 Visual Basic 6.0 图形属性和方法及它们在 Visual Basic 2005 中的等效项。
Visual Basic 6.0
Visual Basic 2005 等效项
AutoRedraw 属性
新的实现。若要永久保存图形,请在 Paint 事件中放入图形方法。
Circle 方法
DrawEllipse 方法
ClipControls 属性
新的实现。ClipControls 属性不再是必需的。
Clear 方法
CurrentX 属性
各种图形方法的 x 参数。例如,(pen, x, y, width, height)
CurrentY 属性
各种图形方法的 y 参数。例如,DrawRectangle (pen, x, y, width, height)
新的实现。DrawMode 属性不再是必需的。
DrawStyle 属性
DashStyle 属性
DrawWidth 属性
FillColor 属性
SolidBrush 对象
FillStyle 属性
HatchBrush 对象
HasDC 属性
新的实现。GDI+ 不再需要设备上下文。
新的实现。GDI+ 不再需要设备上下文。
Image 属性
新的实现。
DrawLine 方法
PaintPicture 方法
DrawImage 方法
Point 方法
无直接等效项。对于位图,请使用 Bitmap.GetPixel。对于窗体或控件,请使用
Print 方法
DrawString 方法
DrawEllipse、FillEllipse 方法
TextHeight、TextWidth 属性
MeasureString 方法
应用程序从 Visual Basic 6.0 升级到 Visual Basic 2005 时,图形方法并不升级,并会在代码中插入警告。由于 GDI 和 GDI+ 之间的巨大差异,现有的所有图形代码都需要重写。
您对此内容的反馈非常重要。请告诉我们您的想法。
更多反馈?
1500 个剩余字符
我们非常感谢您的反馈。
开发人员中心4007人阅读
& 一个pixel shader是在每一像素光栅化处理期间物理卡的GPU上执行的一种程序。(不像vertex shader,Direct3D不会用软件方法仿效pixel shader的功能。)。它本质上代替了固定管道功能中的多重纹理阶段并给了我们直接操作单独像素和访问每一个像素纹理坐标的能力。这种直接访问像素和纹理坐标允许我们完成多种特殊效果,比如多重纹理、逐像素光照、视野深度、云层仿真、火焰仿真和复杂阴影技术。
你可以通过检查D3DCAPS9结构体的PixelShaderVersion成员和D3DVS_VERSION宏来检测你的物理卡支持的pixel
shader版本。下面的代码片断举例说明了这个:
// If the device's supported version is less than version 2.0
if( caps.PixelShaderVersion & D3DPS_VERSION(2, 0) )
&&&& // Then pixel shader version 2.0 is not supported on this device.
Objectives
·获得关于多重纹理概念的基本理解
·学习如何写、创建并应用pixel shaders
·学习如何应用pixel shader执行多重纹理
一、多重纹理概述(
Multitexturing Overview)
多重纹理可能是用pixel shader可以执行的最简单的技术。此外,由于pixel shader替换了多重纹理阶段,接下来我们需要对多重纹理阶段是什么和如何做具有一些基本的理解。这一节简单概述一下多重纹理。
当我们最初在以前的章节揭示纹理时,我们有两个原因在固定功能管道中省略讨论多重纹理:第一,multitexturing
是有点棘手的,并且我们当时考虑它为一种高级话题。另外,固定功能多重纹理阶段被新的更强大的pixel shader代替了。因此有意不花时间在过时的固定功能多重纹理阶段。
多重纹理背后的思想是有些方面代替混合(blending)。在前面讲混合的章节中我们学到用先前已写入后台缓冲的像素混合正被光栅化的纹理以完成一个特殊效果。我们扩展这个同样的思想到多重纹理。即,我们一次开启几个纹理并定义这些纹理如何混合到一起以完成一种特殊效果。多重纹理的一个普通应用是做光照(lighting)。代替应用Direct3D的在顶点处理阶段的光照模式,我们应用被称为光图(light
map)的特殊的纹理图,它编码了一个表面如何被照明。例如,假设我们想用一个点光照亮一个很大的箱子。我们可以定义一个D3DLIGHT9结构的点光源,或者我们可以把一个表现箱子的纹理图与一个表现点光的光图混合在一起,如图所示。
Figure 18.1: Rendering a crate lit by a spotlight using multitexturing. Here we combine the two textures by multiplying the corresponding texels together.
如“混合”那一章所介绍的,结果图形依赖于纹理如何混合。在固定功能多重纹理阶段,混合方程式控制了整个纹理混合阶段。通过pixel shader我们可以把混合函数编程在代码中成为一种简单表达式。这允许我们用任何我们想要的方法混合纹理。在我们讨论这一节的例程中我们详细说明混合纹理。
混合纹理(这一例子中是两个)以照明箱子有两个比Direct3D光照的益处:
·光照是在点光光图中预先计算好的。因而,光照不需要在运行时被计算,这节省了处理时间。当然,光照只能预先计算静态物体和静态光。
·因为光图是预先计算的,我们就能比Direct3D模式应用更精确更变化多样的光照模式。(在很多现实场景中更好的光照结果)
多重纹理阶段的一个代表性应用是实现一个对静态物体的完全光照引擎(full lighting engine for static objects)。例如,我们可能有一个存贮物体颜色的纹理图,如一个箱子纹纹理图。然后我们可能有一个漫反射光图以保存漫反射表面阴影,并有一个细节图保存表面上小的、高发生率的细节。当这些所有纹理组合在一起时,它仅仅应用查找预先计算好的纹理表现场景的光、颜色和细节。
The spotlight light map is a trivial example of a very basic light map. Typically, special programs are used to generate light maps given a scene and
light sources. Generating light maps goes beyond the scope of this book. For the interested reader, Alan Watt and Fabio Policarpo describe light mapping in
3D Games: Real-time Rendering and Software Technology.
点光光图是一个对非常基本的光图中价值不高的例子。代表性的,特殊的程序被用于当给定一个场景和一个光源时产生光图。产生光图超出了教程的范围。对于感兴趣的学生。Alan Watt
和Fabio Policarpo 描述了3D游戏中的光图:Real-time Rendering and Software Technology.
开启多重纹理(Enabling Multiple Textures)
回忆一下纹理通过IDirect3DDevice9::SetTexture方法设置并且取样器阶段通过IDirect3DDevice9::SetSamplerState方法设置,原形如下:
HRESULT IDirect3DDevice9::SetTexture(
&&&& DWORD Stage, // specifies the texture stage index
&&&& IDirect3DBaseTexture9 *pTexture
HRESULT IDirect3DDevice9::SetSamplerState(
&&&& DWORD Sampler, // specifies the sampler stage index
&&&& D3DSAMPLERSTATETYPE Type,
&&&& DWORD Value
一个特殊的采样器阶段索引i是关联到第i纹理阶段。即,第i采样阶段指定采样阶段为第i次设置纹理。
&&&&&&& texture/sampler 阶段索引识别我们想设置texture/sampler的texture/sampler阶段。因而,我们能开启多重纹理并且用不同的阶段索引设置它们的相应采样阶段。在以前的讲解中,我们通常指定0,表示第一阶段,因为我们在一个时间只使用一层纹理。所以举个例子,如果我们需要开启三层纹理,我们用阶段0、1、2象这样:
// Set first texture and corresponding sampler states.
Device-&SetTexture(&&&& 0, Tex1);
Device-&SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// Set second texture and corresponding sampler states.
Device-&SetTexture(&&&& 1, Tex2);
Device-&SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// Set third texture and corresponding sampler states.
Device-&SetTexture(&&&& 2, Tex3);
Device-&SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
这一代码开启了Tex1,
Tex2, and Tex3并设置每一纹理的采样模式。
多重纹理坐标(Multiple Texture Coordinates)
回忆以前章节有关每个3D三角形,我们想定义一个被画于3D三角形上的相应的纹理上的三角形。我们通过加入纹理坐标到每一顶点做到这点。因而,每三个三角形顶点定义一个相应的纹理上的三角形。
因为我们现在应用多重纹理,对于每三个顶点定义一个三角形我们需要定义一个相应的每个形启的纹理上的三角形。我们通过加入额外的对于每个顶点的纹理坐标的设置来做到这点—一种设置是为了,相应于,每个开启的纹理。例如,如果我们混合三重纹理到一起,而每个顶点必须有三个纹理坐标设置索引三个开启的坐标。因而,一个具有三重纹理的多重纹理的顶点结构体看起来象这样:
struct MultiTexVertex
&&&& MultiTexVertex(float x, float y, float z,
&&&&&&&&&&&&&&&&&&& float u0, float v0,
&&&&&&&&&&&&&&&&&&& float u1, float v1,
&&&&&&&&&&&&& &&&&&&float u2, float v2)
&&&&&&&&& _x =& x;&& _y = _z =
&&&&&&&&& _u0 = u0;& _v0 = v0;
&&&&&&&&& _u1 = u1;& _v1 = v1;
&&&&&&&&& _u2 = u2;& _v2 = v2;
&&&& float _x, _y, _z;
&&&& float _u0, _v0; // Texture coordinates for texture at stage 0.
&&&& float _u1, _v1; // Texture coordinates for texture at stage 1.
&&&& float _u2, _v2; // Texture coordinates for texture at stage 2.
&&&& static const DWORD FVF;
const DWORD MultiTexVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX3;
观察灵活顶点格式标志D3DFVF_TEX3被指定为表示顶点结构包含三重纹理坐标设置。固定功能管道支持8个纹理坐标设置。为了应用多于8的,你必须用一个顶点声明(vertex declaration)和可编程顶点管道。
在较机关报的pixel shader版本中,我们能用一个纹理坐标设置索引到多重纹理,因而移除多重纹理坐标的需要。当然这要假定同样纹理坐标被用于每一纹理阶段。如果每一阶段的纹理坐标不同,那么我们将仍然需要多重纹理坐标。
Pixel Shader Inputs and Outputs
两样东西被输入一个pixel shader:颜色和纹理坐标。两者都在每个象素。
回忆一下顶点颜色是被原始外观插值的。(Recall that vertex colors are interpolated across the face of a primitive.)
A per pixel texture coordinate is simply the (u, v) coordinates that specify the texel in the texture that is to be mapped to the pixel in question. Direct3D
computes both colors and texture coordinates per pixel, from vertex colors and vertex texture coordinates, before entering the pixel shader. The number of colors and texture coordinates
input into the pixel shader depends on how many colors and texture coordinates were output by the vertex shader. For example, if a vertex shader outputs two colors and three texture
coordinates, then Direct3D will calculate two colors and three texture coordinates per pixel and input them into the pixel shader. We map the input colors and texture coordinates to variables in our pixel shader program using the semantic syntax. Using the
previous example, we would write:
每一像素纹理坐标是简单的(u, v)坐标,那个被指定为纹理中的图素(texel),被映射到像素的东东。在进入pixel shader前,通过顶点颜色和顶点纹理坐标,Direct3D计算每一像素的颜色和纹理坐标两者。
struct PS_INPUT
&&&& vector c0 : COLOR0;
&&&& vector c1 : COLOR1;
&&&& float2 t0 : TEXCOORD0;
&&&& float2 t1 : TEXCOORD1;
&&&& float2 t2 : TEXCOORD2;
对于输出,一个pixel shader输出一个单一的对于像素的计算后的颜色值:
struct PS_OUTPUT
&&&& vector finalPixelColor : COLOR0;
三、使用pixel shader的步骤(
Steps to Using a Pixel Shader)
下面的列表是创建和使用一个pixel shader的必要步骤的概要。
1.写出并编译pixel shader。
2.基于编译后的shader代码创建一个IDirect3DPixelShader9界面以表示pixel shader。
3.通过IDirect3DDevice9::SetPixelShader方法开启pixel shader。
当然,我们必须用完后销毁这个pixel shader。下几个小节相信讲述这些步骤。
Writing and Compiling a Pixel Shader
我们编译一个pixel shader与编译一个vertex shader采用同样方法。首先,我们必须写一个pixel shader程序。在本书中,我们用HLSL写我们的shader。一旦shader代码被写好,我们用D3DXCompileShaderFromFile函数进行编译,如以前章节介绍的一样。回忆一下这个函数返回一个指向ID3DXBuffer的指针以包括编译后的shader代码。
因为我们使用pixel shader,我们将要记住更改编译目标到pixel shader target (e.g.,
ps_2_0)替代一个 vertex shader target (e.g.,
vs_2_0)。编译目标能过D3DXCompileShaderFromFile函数的一个参数指定。以前章节有详细描述。
3.2创建一个pixel Shader(Creating
a Pixel Shader)
一旦我们拥有了编译后的shader代码,我们就能获得一个指向IDirect3DPixelShader9表面的指针,它描述一个pixel shader,用下面的方法:
HRESULT IDirect3DDevice9::CreatePixelShader(
&&&&& CONST DWORD *pFunction,
&&&&& IDirect3DPixelShader9** ppShader
·pFunction—指向编译后的shader代码的指针
·ppShader—返回一个指针指向一个IDirect3DPixelShader9表面
For example, suppose the variable
shader is an ID3DXBuffer that contains the compiled shader code. Then to obtain an
IDirect3DPixelShader9 interface, we would write:
举例来说,假设变量shader是一个包括编译后的shader代码的ID3DXBuffer。然后为了获得一个IDirect3DPixelShader9表面,我们将这样写:
IDirect3DPixelShader9* MultiTexPS = 0;
hr = Device-&CreatePixelShader(
&&&&&&&&&& (DWORD*)shader-&GetBufferPointer(),
&&&&&&&&&& &MultiTexPS);
重申一下,D3DXCompileShaderFromFile是一个返回编译后的shader代码的函数。
设置一个 Pixel Shader
当我们已经获得一个指向一个描述我们的pixel shader的IDirect3DPixelShader9表面的指针后,我们开以用下面的方法开启(enable)它:
HRESULT IDirect3DDevice9::SetPixelShader(
&&&&& IDirect3DPixelShader9* pShader
这个方法得到一个单一的参数,这里我们传递一个指向我们想开启的pixel shader的指针。为了开启一个我们在3.2节创建的shader,我们这样写:
Device-&SetPixelShader(MultiTexPS);
3.4销毁一个
Pixel Shader
如同所有Direct3D界面,为了清除它们我们必须在用完后调用它们的Release方法。继续用我们在3.2节创建的pixel shader,我们有:
d3d::Release(MultiTexPS);
四、HLSL采样器对象(
HLSL Sampler Objects)
纹理在一个pixel shader中使用特定的tex*HLSL中的有关的内部函数 被采样。
采样参考一个图素(对于一个像素的基于纹理坐标的一个像素)和采样器状态(纹理过滤器状态texture filter states)。
查看前面章节中对于这些函数的详细描述。通常的,这些函数要求我们指定两件事:
·&(u, v)纹理坐标用于索引纹理
·我们想要索引的详细的纹理
&(u, v)纹理坐标是,当然,由pixel shader的输入给定。我们想要索引的详细的纹理是在pixel shader中用一个特定的HLSL对象叫做一个采样器(sampler)指定的。我们可以想象一个采样器对象为一个识别一个纹理和采样阶段的对象。例如,假设我们正用到三个纹理阶段,这意味着我们需要能够涉及在pixel
shader中的这些阶段的每一个。在pixel shader中,我们可以这样写:
sampler FirstT
sampler SecondT
sampler ThirdT
Direct3D将用一个唯一的纹理阶段关联这些采样器的每个对象。然后在应用程序中我们找到一个采样器对象相关的阶段并设置适当的纹理和这个阶段的采样器状态。下面的代码举例说明了应用程序如何设置FirstTex的纹理和采样器状态:
// Create texture:
IDirect3DTexture9* T
D3DXCreateTextureFromFile(Device, &tex.bmp&, &Tex);
// Get handle to constant:
FirstTexHandle = MultiTexCT-&GetConstantByName(0, &FirstTex&);
// Get a description of the constant:
D3DXCONSTANT_DESC FirstTexD
MultiTexCT-&GetConstantDesc(FirstTexHandle, &FirstTexDesc, &count);
// Set texture/sampler states for the sampler FirstTex. We identify
// the stage FirstTex is associated with from the
// D3DXCONSTANT_DESC::RegisterIndex member:
Device-&SetTexture(FirstTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&& Tex);
Device-&SetSamplerState(FirstTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(FirstTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device-&SetSamplerState(FirstTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
替代方案,代替使用sampler类型,我们能够使用更精确更健壮的类型为sampler1D,
sampler2D, sampler3D,和
samplerCube的类型这些类型是更安全并确保它们只用于相应的tex*的函数。例如,一个sampler2D对象只能被tex2D*函数应用。同样的,一个sampler3D对象只能被tex3D*函数应用
五、例程: Multitexturing in a Pixel Shader
本节的例程示范了使用pixel shader的多重纹理。本例将基于图中的&result&纹理化一个距形,用一个箱子纹理、一个点光纹理、一个包含字符串&Pixel Shader Sample.&的纹理混合到一起。
Figure 18.2: Combining the textures. Let b, s, and t be the colors of corresponding texels from the crate texture, spotlight texture, and text texture, respectively. We define how these colors
are combined as c = b ? s + t, where
? denotes component-wise multiplication.
本例能不用pixel shader完成。然而,它能简单并直接的实现这一应用,它允许我们示范如何写、创建并使用pixel shader而不用心烦意乱于一些特殊效果的运算法则。
尽管在本例中我们仅仅一次用到三个纹理,也值得检查用于每一pixel shader版本的采样器对象的版本号。换句话说,我们能一次用到多少个纹理取决于我们用的pixel shader版本。
·Pixel shader versions ps_1_1 to ps_1_3 support up to four texture samples.
·Pixel shader version ps_1_4 supports up to six texture samples.
·Pixel shader versions ps_2_0 to ps_3_0 support up to 16 texture samples.
有两重纹理的多重纺理pixel shader执行如下:
// File: ps_multitex.txt
// Desc: Pixel shader that does multitexturing.
// Globals
sampler BaseT
sampler SpotLightT
sampler StringT
// Structures
struct PS_INPUT
&&&& float2 base&&&&& : TEXCOORD0;
&&&& float2 spotlight : TEXCOORD1;
&&&& float2 text&&&&& : TEXCOORD2;
struct PS_OUTPUT
&&&& vector diffuse : COLOR0;
PS_OUTPUT Main(PS_INPUT input)
&&&& // zero out members of output
&&&& PS_OUTPUT output = (PS_OUTPUT)0;
&&&& // sample appropriate textures
&&&& vector b = tex2D(BaseTex,&&&&& input.base);
&&&& vector s = tex2D(SpotLightTex, input.spotlight);
&&&& vector t = tex2D(StringTex,&&& input.text);
&&&& // combine texel colors
&&&& vector c =b *s +t;
&&&& // increase the intensity of the pixel slightly
&&&& c += 0.1f;
&&&& // save the resulting pixel color
&&&& output.diffuse =
首先pixel shader声明三个采样器对象,每一个对应我们正在混合的一个纹理。接下来input
和output结构被定义。注意我们没把任何颜色值输入这个pixel shader,这是因为我们正在应用专用于颜色和光照的纹理,就是说,持有我们的表面颜色的基本纹理和点光纹理是我们的光图(light map)。这个pixel shader只输出一个颜色值,指定对于特定的像素我们已计算好的颜色。
主函数用tex2D函数采样了三个纹理。也就是说,它从每个画到这个我们现在正在计算的像素上的纹理上,基于指定的坐标和采样器对象,吸取图素。然后我们用公式c = b * s + t联合图素颜色。接着我们用加上0.1f到每个成员来加亮一点全面的像素颜色。最后,我们保存结果像素颜色并返回它。
现在我们已经看到了实际的pixel shader代码,我们切换一下看一下应用程序代码。应用程序有如下有关的全局变量:
IDirect3DPixelShader9* MultiTexPS = 0;
ID3DXConstantTable* MultiTexCT&&& = 0;
IDirect3DVertexBuffer9* QuadVB = 0;
IDirect3DTexture9* BaseTex&&&&& = 0;
IDirect3DTexture9* SpotLightTex = 0;
IDirect3DTexture9* StringTex&&& = 0;
D3DXHANDLE BaseTexHandle&&&&& = 0;
D3DXHANDLE SpotLightTexHandle = 0;
D3DXHANDLE StringTexHandle&&& = 0;
D3DXCONSTANT_DESC BaseTexD
D3DXCONSTANT_DESC SpotLightTexD
D3DXCONSTANT_DESC StringTexD
多重纹理例程的顶点结构这样定义:
struct MultiTexVertex
&&&& MultiTexVertex(float x, float y, float z,
&&&&&&&&&&&&&&&&&&& float u0, float v0,
&&&&&&&&&&&&&&&&&&& float u1, float v1,
&&&&&&&&&&&&&&&&&&& float u2, float v2)
&&&&&&&&& _x =& x;&& _y =& y; _z =
&&&&&&&&& _u0 = u0;& _v0 = v0;
&&&&&&&&& _u1 = u1;& _v1 = v1;
&&&&&&&&& _u2 = u2,& _v2 = v2;
&&&& float _x,& _y,& _z;
&&&& float _u0,& _v0;
&&&& float _u1,& _v1;
&&&& float _u2,& _v2;
&&&& static const DWORD FVF;
const DWORD MultiTexVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX3;
观察一下它包含三个纹理坐标设置。
Setup函数执行了下面的任务:
·填充表示距形的顶点缓冲
·编译pixel shader
·创建pixel shader
·加载纹理
·设置放射距阵并关闭灯光
·取得采样器对象的句柄
·取得采样器对象的描述
bool Setup()
HRESULT hr = 0;
// Create quad geometry.
Device-&CreateVertexBuffer(
&&&& 6 * sizeof(MultiTexVertex),
&&&& D3DUSAGE_WRITEONLY,
&&&& MultiTexVertex::FVF,
&&&& D3DPOOL_MANAGED,
&&&& &QuadVB,
MultiTexVertex*v =0;
QuadVB-&Lock(0, 0, (void**)&v, 0);
v[0] = MultiTexVertex(-10.0f, -10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
v[1] = MultiTexVertex(-10.0f, 10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[2] = MultiTexVertex( 10.0f, 10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
v[3] = MultiTexVertex(-10.0f, -10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
v[4] = MultiTexVertex( 10.0f, 10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
v[5] = MultiTexVertex( 10.0f, -10.0f, 5.0f,
&&&&&&&&&&&&&&&&&&&&&& 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
QuadVB-&Unlock();
// Compile shader
ID3DXBuffer* shader&&&&& = 0;
ID3DXBuffer* errorBuffer = 0;
hr = D3DXCompileShaderFromFile(
&&&& &ps_multitex.txt&,
&&&& &Main&, // entry point function name
&&&& &ps_1_1&,
&&&& D3DXSHADER_DEBUG,
&&&& &shader,
&&&& &errorBuffer,
&&&& &MultiTexCT);
// output any error messages
if( errorBuffer )
&& ::MessageBox(0, (char*)errorBuffer-&GetBufferPointer(), 0, 0);
&& d3d::Release(errorBuffer);
if(FAILED(hr))
&& ::MessageBox(0, &D3DXCompileShaderFromFile() - FAILED&, 0, 0);
// Create Pixel Shader
hr = Device-&CreatePixelShader(
&&&& (DWORD*)shader-&GetBufferPointer(),
&&&& &MultiTexPS);
if(FAILED(hr))
&&&& ::MessageBox(0, &CreateVertexShader - FAILED&, 0, 0);
d3d::Release(shader);
// Load textures.
D3DXCreateTextureFromFile(Device, &crate.bmp&, &BaseTex);
D3DXCreateTextureFromFile(Device, &spotlight.bmp&, &SpotLightTex);
D3DXCreateTextureFromFile(Device, &text.bmp&, &StringTex);
// Set projection matrix
D3DXMATRIX P;
D3DXMatrixPerspectiveFovLH(
&&&&&&&&&& &P, D3DX_PI * 0.25f,
&&&&&&&&& &(float)Width / (float)Height, 1.0f, 1000.0f);
Device-&SetTransform(D3DTS_PROJECTION, &P);
// Disable lighting.
Device-&SetRenderState(D3DRS_LIGHTING, false);
// Get handles
BaseTexHandle&&&&& = MultiTexCT-&GetConstantByName(0, &BaseTex&);
SpotLightTexHandle = MultiTexCT-&GetConstantByName(0, &SpotLightTex&);
StringTexHandle&&& = MultiTexCT-&GetConstantByName(0, &StringTex&);
// Set constant descriptions:
MultiTexCT-&GetConstantDesc(
&&&&&&&&&&&&&&& BaseTexHandle,
&&&& &&&&&&&&&&&&BaseTexDesc,
&&&&&&&&&&&&&&& &count);
MultiTexCT-&GetConstantDesc(
&&&&&&&&&&&&&&& SpotLightTexHandle,
&&&&&&&&&&&&&&& &SpotLightTexDesc,
&&&&&&&&&&&&&&& &count);
MultiTexCT-&GetConstantDesc(
&&&&&&&&&&&&&&& StringTexHandle,
&&&&&&&&&&&&&&& &StringTexDesc,
&&&&&&&&&&&&&&& &count);
MultiTexCT-&SetDefaults(Device);
Display函数设置pixel shader,开启两个纹理,并在渲染距形前设置它们的相应采样器状态。
bool Display(float timeDelta)
if( Device )
&&&& // ...camera update code snipped
&&&& // Render
&&&& Device-&Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
&&&&&&&&&&&&&&&&&& 0xffffffff, 1.0f, 0);
&&&& Device-&BeginScene();
&&&& // set the pixel shader
&&&& Device-&SetPixelShader(MultiTexPS);
&&&& Device-&SetFVF(MultiTexVertex::FVF);
&&&& Device-&SetStreamSource(0, QuadVB, 0, sizeof(MultiTexVertex));
&&&& // base tex
&&&& Device-&SetTexture(BaseTexDesc.RegisterIndex, BaseTex);
&&&& Device-&SetSamplerState(BaseTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(BaseTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(BaseTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
&&&& // spotlight tex
&&&& Device-&SetTexture(SpotLightTexDesc.RegisterIndex, SpotLightTex);
&&&& Device-&SetSamplerState(SpotLightTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(SpotLightTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(SpotLightTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
&&&& // string tex
&&&& Device-&SetTexture(&&&& StringTexDesc.RegisterIndex, StringTex);
&&&& Device-&SetSamplerState(StringTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(StringTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
&&&& Device-&SetSamplerState(StringTexDesc.RegisterIndex,
&&&&&&&&&&&&&&&&&&&&&&&&&&&& D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
&&&& // draw the quad
&&&& Device-&DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
&&&& Device-&EndScene();
&&& &Device-&Present(0, 0, 0, 0);
当然我们必须记得在Cleanup函数中释放三个我们分配表面:
void Cleanup()
&&&& d3d::Release(QuadVB);
&&&& d3d::Release(BaseTex);
&&&& d3d::Release(SpotLightTex);
&&&& d3d::Release(StringTex);
&&&& d3d::Release(MultiTexPS);
&&&& d3d::Release(MultiTexCT);
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3070452次
积分:41812
积分:41812
排名:第35名
原创:71篇
转载:3170篇
评论:735条
声明:早期转载的文章未标明转载敬请原谅,以后将陆续改过来,向原创者致敬!
有问题可留言
痞子龙3D编程
QQ技术交流群:
(8)(5)(6)(7)(2)(3)(7)(24)(5)(5)(16)(17)(16)(66)(7)(55)(2)(37)(16)(1)(10)(6)(37)(5)(31)(18)(31)(128)(333)(203)(256)(59)(78)(57)(16)(39)(10)(27)(16)(8)(26)(32)(53)(56)(45)(142)(228)(6)(10)(6)(9)(6)(9)(22)(25)(18)(83)(208)(442)(111)(32)(1)}

我要回帖

更多关于 pixel dungeon 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信