游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2223|回复: 1

DirectX9 3D 快速上手 6

[复制链接]

44

主题

248

帖子

274

积分

中级会员

Rank: 3Rank: 3

积分
274
发表于 2005-4-25 01:14:00 | 显示全部楼层 |阅读模式
                                              DirectX9 3D 快速上手 6
                                                                                                 By sssa2000
                                                                                                  4/25/2005
讲了很多,最基础的部分就剩下纹理没有讲到了。Texture是Directx里面非常重要的一部分。为了简便起见,我们还是以SDK的Tutorial5为例子。
纹理就像一张墙纸,用来贴在物体的表面,当然,如果足够大,贴一次就能覆盖整个物体的表面,也可以用适当的方法让纹理排列成你要的效果。
来看看纹理的比较重要的函数:Device.SetTexture
public void SetTexture(
    int stage, //纹理混合阶段序号,从0开始
    BaseTexture texture //要设置的纹理对象
);

public void SetTextureStageState(
    int stage, //纹理混合阶段序号
    TextureStageStates state, // TextureStageStates enumeration的成员
    int value //对应阶段状态的值
);
SetTextureStageState函数对处理不同的纹理坐标,颜色操作,Alpha操作,和凹凸映射/环境映射比较适用,但是这些操作只对DX9的固定功能的多纹理单元有效,不能将他们与像素shader连用。
public void SetSamplerState(
    int stage, //纹理混合阶段序号
    SamplerStageStates state, // SamplerStageStates enumeration的成员
  int value  //对应采样器状态的值
);
知道了这些下面读懂这些代码就很容易了,我们需要建立Vertex,这里我们需要有一点点地改变,在以前我们接触到的Vertex里面都不涉及到纹理,所以我们选择了CustomVertex里面不包括纹理的类型,现在我们要用CustomVertex.PositionNormalTextured,从名字就可以看出来,这个类型包括了法线还包括了位置的X,Y,Z,以及纹理坐标的Tu和Tv。
当然如果使用CustomVertex.PositionTextured 也是可以的,它不包括法线信息。
接下来我们需要为每个Vertex指定信息,我们先打断一下讲讲纹理坐标,为了通过指定纹理坐标来访问纹理中的每个图素,DX采用了一个一般化的编址方案,纹理地址由[0.0,1.0]区间内的坐标组成,这样我们就不用关心纹理的实际尺寸,例如可以使用(0.0f,0.0f) ,(1.0f,0.0f),(1.0f,1.0f),(0.0f,1.0f)把一个纹理贴到一个矩形上,同样如果(0.0f,0.0f) ,(0。5f,0.0f),(0.5,1.0f),(0.0f,1.0f)就是纹理的左半边。
我们可以通过TextureLoader.FromFile方法来读入图片作为纹理。
这里代码很简单里面有详细的注释,我就不多讲了,
//-----------------------------------------------------------------------------
// File: texture.cs
//
// Desc: Better than just lights and materials, 3D objects look much more
//       convincing when texture-mapped. Textures can be thought of as a sort
//       of wallpaper, that is shrinkwrapped to fit a texture. Textures are
//       typically loaded from image files, and D3DX provides a utility to
//       function to do this for us. Like a vertex buffer, textures have
//       Lock() and Unlock() functions to access (read or write) the image
//       data. Textures have a width, height, miplevel, and pixel format. The
//       miplevel is for "mipmapped" textures, an advanced performance-
//       enhancing feature which uses lower resolutions of the texture for
//       objects in the distance where detail is less noticeable. The pixel
//       format determines how the colors are stored in a texel. The most
//       common formats are the 16-bit R5G6B5 format (5 bits of red, 6-bits of
//       green and 5 bits of blue) and the 32-bit A8R8G8B8 format (8 bits each
//       of alpha, red, green, and blue).
//
//       Textures are associated with geometry through texture coordinates.
//       Each vertex has one or more sets of texture coordinates, which are
//       named tu and tv and range from 0.0 to 1.0. Texture coordinates can be
//       supplied by the geometry, or can be automatically generated using
//       Direct3D texture coordinate generation (which is an advanced feature).
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D=Microsoft.DirectX.Direct3D;

namespace TextureTutorial
{
        public class Textures : Form
        {
                // Our global variables for this project
                Device device = null; // Our rendering device
                VertexBuffer vertexBuffer = null;
                Texture texture = null;
                PresentParameters presentParams = new PresentParameters();
                bool pause = false;


                public Textures()
                {
                        // Set the initial size of our form
                        this.ClientSize = new System.Drawing.Size(400,300);
                        // And its caption
                        this.Text = "Direct3D Tutorial 5 - Textures";
                }

                public bool InitializeGraphics()
                {
                        try
                        {
                                presentParams.Windowed=true; // We don't want to run fullscreen
                                presentParams.SwapEffect = SwapEffect.Discard; // Discard the frames
                                presentParams.EnableAutoDepthStencil = true; // Turn on a Depth stencil
                                presentParams.AutoDepthStencilFormat = DepthFormat.D16; // And the stencil format
                                device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //Create a device
                                device.DeviceReset += new System.EventHandler(this.OnResetDevice);
                                this.OnCreateDevice(device, null);
                                this.OnResetDevice(device, null);
                                pause = false;

                                return true;
                        }
                        catch (DirectXException)
                        {
                                // Catch any errors and return a failure
                                return false;
                        }
                }
                public void OnCreateDevice(object sender, EventArgs e)
                {
                        Device dev = (Device)sender;
                        // Now Create the VB
                        vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), 100, dev, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Default);
                        vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer);
                        this.OnCreateVertexBuffer(vertexBuffer, null);
                }
                public void OnResetDevice(object sender, EventArgs e)
                {
                        Device dev = (Device)sender;
                        // Turn off culling, so we see the front and back of the triangle
                        dev.RenderState.CullMode = Cull.None;
                        // Turn off D3D lighting
                        dev.RenderState.Lighting = false;
                        // Turn on the ZBuffer
                        dev.RenderState.ZBufferEnable = true;
                        // Now create our texture
                        texture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\banana.bmp");
                }
                public void OnCreateVertexBuffer(object sender, EventArgs e)
                {
                        VertexBuffer vb = (VertexBuffer)sender;
                        // Create a vertex buffer (100 customervertex)
                        CustomVertex.PositionNormalTextured[] verts = (CustomVertex.PositionNormalTextured[])vb.Lock(0,0); // Lock the buffer (which will return our structs)
                        for (int i = 0; i < 50; i++)
                        {
                                // Fill up our structs
                                float theta = (float)(2 * Math.PI * i) / 49;
                                verts[2 * i].Position = new Vector3((float)Math.Sin(theta), -1, (float)Math.Cos(theta));
                                verts[2 * i].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta));
                                verts[2 * i].Tu = ((float)i)/(50-1);
                                verts[2 * i].Tv = 1.0f;
                                verts[2 * i + 1].Position = new Vector3((float)Math.Sin(theta), 1, (float)Math.Cos(theta));
                                verts[2 * i + 1].Normal = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta));
                                verts[2 * i + 1].Tu = ((float)i)/(50-1);
                                verts[2 * i + 1].Tv = 0.0f;
                        }
                        // Unlock (and copy) the data
                        vb.Unlock();
                }
                private void SetupMatrices()
                {
                        // For our world matrix, we will just rotate the object about the y-axis.
                        device.Transform.World = Matrix.RotationAxis(new Vector3((float)Math.Cos(Environment.TickCount / 250.0f),1,(float)Math.Sin(Environment.TickCount / 250.0f)), Environment.TickCount / 1000.0f );

                        // 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.
                        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).
                        device.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4.0f, 1.0f, 1.0f, 100.0f );
                }

                private void Render()
                {
                        if (pause)
                                return;

                        //Clear the backbuffer to a blue color
                        device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0f, 0);
                        //Begin the scene
                        device.BeginScene();
                        // Setup the world, view, and projection matrices
                        SetupMatrices();
                        // Setup our texture. Using textures introduces the texture stage states,
                        // which govern how textures get blended together (in the case of multiple
                        // textures) and lighting information. In this case, we are modulating
                        // (blending) our texture with the diffuse color of the vertices.
                        device.SetTexture(0,texture);
                        device.TextureState[0].ColorOperation = TextureOperation.Modulate;
                        device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
                        device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
                        device.TextureState[0].AlphaOperation = TextureOperation.Disable;
       
                        device.SetStreamSource(0, vertexBuffer, 0);
                        device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
                        device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4*25)-2);
                        //End the scene
                        device.EndScene();
                        // Update the screen
                        device.Present();
                }

                protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
                {
                        this.Render(); // Render on painting
                }
                protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
                {
                        if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
                                this.Dispose(); // Esc was pressed
                }
        protected override void OnResize(System.EventArgs e)
        {
            pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);
        }

        
        
        /// <summary>
                /// The main entry point for the application.
                /// </summary>
                static void Main()
                {

            using (Textures frm = new Textures())
            {
                if (!frm.InitializeGraphics()) // Initialize Direct3D
                {
                    MessageBox.Show("Could not initialize Direct3D.  This tutorial will exit.");
                    return;
                }
                frm.Show();

                // While the form is still valid, render and process messages
                while(frm.Created)
                {
                    frm.Render();
                    Application.DoEvents();
                }
            }
                }

        }
}
这里还有一个简单的方法处理纹理,其实也差不多,看上去简单一些而已:
tex = new Texture(device, new Bitmap(this.GetType(), "puck.bmp"), Usage.Dynamic, Pool.Default);
然后在画图的时候用一句
device.SetTexture(0, tex);
就可以把纹理设置到物体上了,不过如果要进行稍微复杂的纹理操作,这个方法就不管用了。
关于纹理的东西还有很多很多,比如纹理的寻址模式,纹理包装,纹理过滤抗锯齿以及alpha混合 和多重纹理等等,这里介绍的只是九牛一毛,不过这些在后面都会慢慢介绍到。
                                                                               By sssa2000

sf_200542511415.rar

318.3 KB, 下载次数:

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2005-4-25 06:17:00 | 显示全部楼层

Re:DirectX9 3D 快速上手 6

??啦
?在?在?W?中.....
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-25 12:07

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表