C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

Managed Directx --rendering vertices (使用VertexBuffer 进行render)

 

// -----------------------------------------------------------------------------
//  File: Vertices.cs
//
//  Desc: In this tutorial, we are rendering some vertices. This introduces the
//        concept of the vertex buffer, a Direct3D object used to store
//        vertices. Vertices can be defined any way we want by defining a
//        custom structure and a custom FVF (flexible vertex format). In this
//        tutorial, we are using vertices that are transformed (meaning they
//        are already in 2D window coordinates) and lit (meaning we are not
//        using Direct3D lighting, but are supplying our own colors).
//
//  Copyright (c) Microsoft Corporation. All rights reserved.
// -----------------------------------------------------------------------------
using  System;
using  System.Drawing;
using  System.Windows.Forms;
using  Microsoft.DirectX;
using  Microsoft.DirectX.Direct3D;

namespace  VerticesTutorial
{
    
public   class  Vertices : Form
    
{
        
//  Our global variables for this project
        Device device  =   null //  Our rendering device
        VertexBuffer vertexBuffer  =   null ;

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

        
        
public   bool  InitializeGraphics()
        
{
            
try
            
{
                
//  Now let's setup our D3D stuff
                PresentParameters presentParams  =   new  PresentParameters();
                presentParams.Windowed
= true ;
                presentParams.SwapEffect 
=  SwapEffect.Discard;
                device 
=   new  Device( 0 , DeviceType.Hardware,  this , CreateFlags.SoftwareVertexProcessing, presentParams);
                
this .OnCreateDevice(device,  null );
                
return   true ;
            }

            
catch  (DirectXException)
            

                
return   false
            }

        }


        
public   void  OnCreateDevice( object  sender, EventArgs e)
        
{
            Device dev 
=  (Device)sender;
            
//  Now Create the VB
            vertexBuffer  =   new  VertexBuffer( typeof (CustomVertex.TransformedColored),  3 , dev,  0 , CustomVertex.TransformedColored.Format, Pool.Default);
            vertexBuffer.Created 
+=   new  System.EventHandler( this .OnCreateVertexBuffer);
            
this .OnCreateVertexBuffer(vertexBuffer,  null );
        }

        
public   void  OnCreateVertexBuffer( object  sender, EventArgs e)
        
{
            VertexBuffer vb 
=  (VertexBuffer)sender;
            GraphicsStream stm 
=  vb.Lock( 0 0 0 );
            CustomVertex.TransformedColored[] verts 
=   new  CustomVertex.TransformedColored[ 3 ];

            verts[
0 ].X = 150 ;verts[ 0 ].Y = 50 ;verts[ 0 ].Z = 0.5f ; verts[ 0 ].Rhw = 1 ; verts[ 0 ].Color  =  System.Drawing.Color.Red.ToArgb();
            verts[
1 ].X = 250 ;verts[ 1 ].Y = 250 ;verts[ 1 ].Z = 0.5f ; verts[ 1 ].Rhw = 1 ; verts[ 1 ].Color  =  System.Drawing.Color.Yellow.ToArgb();
            verts[
2 ].X = 50 ;verts[ 2 ].Y = 250 ;verts[ 2 ].Z = 0.5f ; verts[ 2 ].Rhw = 1 ; verts[ 2 ].Color  =  System.Drawing.Color.SkyBlue.ToArgb();
            stm.Write(verts);
            vb.Unlock();
        }

        
private   void  Render()
        
{
            
if  (device  ==   null
                
return ;

            
// Clear the backbuffer to a blue color (ARGB = 000000ff)
            device.Clear(ClearFlags.Target, System.Drawing.Color.Blue,  1.0f 0 );
            
// Begin the scene
            device.BeginScene();
            
            device.SetStreamSource( 
0 , vertexBuffer,  0 );
            device.VertexFormat 
=  CustomVertex.TransformedColored.Format;
            device.DrawPrimitives(PrimitiveType.TriangleList, 
0 1 );
            
// End the scene
            device.EndScene();
            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 .Close();  //  Esc was pressed
        }


        
///   <summary>
        
///  The main entry point for the application.
        
///   </summary>

         static   void  Main() 
        
{

            
using  (Vertices frm  =   new  Vertices())
            
{
                
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();
                }

            }

        }


    }

}


1 定义 VertexBuffer vb = null;
2 创建 VertexBuffer 
    public void OnCreateDevice(object sender, EventArgs e)
    {
    Device dev = (Device)sender;
   
    // Now create the vertex buffer
    vertexBuffer = new VertexBuffer(
        typeof(CustomVertex.TransformedColored), 3, dev, 0,
        CustomVertex.TransformedColored.Format, Pool.Default);
    vertexBuffer.Created +=
        new System.EventHandler(this.OnCreateVertexBuffer);
    this.OnCreateVertexBuffer(vb, null);
    }

    public void OnCreateVertexBuffer(object sender, EventArgs e)
    {
    VertexBuffer vb = (VertexBuffer)sender;
    GraphicsStream stm = vb.Lock(0, 0, 0);   //Lock() 保证cpu能够直接访问 VertexBuffer ,必须和unlock()一起使用
    CustomVertex.TransformedColored[] verts =
        new CustomVertex.TransformedColored[3];
    .
    .
    .
    vb.Unlock();
    }
GraphicsStream对象直接访问vertexbuffer, 或者说把vertexbuffer的内容放到Graphicsstream中以合适的大小.
verts[0].X=150; verts[0].Y=50; verts[0].Z=0.5f; verts[0].Rhw=1;
verts[0].Color = System.Drawing.Color.Aqua.ToArgb();

verts[1].X=250; verts[1].Y=250; verts[1].Z=0.5f; verts[1].Rhw=1;
verts[1].Color = System.Drawing.Color.Brown.ToArgb();

verts[2].X=50; verts[2].Y=250; verts[2].Z=0.5f; verts[2].Rhw=1;
verts[2].Color = System.Drawing.Color.LightPink.ToArgb();

stm.Write(verts);
4 render device
private void Render()
{
    if (device == null)
    return;
   
    // Clear the back buffer to a blue color (ARGB = 000000ff)
    device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
    // Begin the scene
    device.BeginScene();
   
    // New for Tutorial 2
    device.SetStreamSource(0, vertexBuffer, 0);    //设置stream源用vertexbuffer.
    device.VertexFormat = CustomVertex.TransformedColored.Format;  //设置render格式
    device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); 
   
    // End the scene
    device.EndScene();
    device.Present();
}

Read and Write VertexBuffer and IndexBuffer Data With GraphicsStreams


using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

public struct PositionNormalTexVertex
{
    
public Vector3 Position;
    
public Vector3 Normal;
    
public  float Tu0, Tv0;
    
public static readonly VertexFormats FVF = VertexFormats.Position | VertexFormats.Texture1;
}

public class Example
{
    
public unsafe void  GraphicsStreamReadWrite()
    
{
        
//Create a vertex buffer in the managed pool
        VertexBuffer vb = new VertexBuffer(typeof(PositionNormalTexVertex), 100, device, Usage.None, PositionNormalTexVertex.FVF, Pool.Managed);

        
//First, fill an array of PositionNormalTexVertex elements with data.
        PositionNormalTexVertex[] vertices = new PositionNormalTexVertex[50];
        
for(int i=0; i<50; i++)
        
{
            
//fill the vertices with some data
            vertices[i].Position = new Vector3(3f,4f,5f);
        }


        
//The size of the verticies are 32-bytes each (float3 (12) + float3 (12) + float(4) + float(4))
        
//To lock 50 verticies, the size of the lock would be 1600 (32 * 50)
        GraphicsStream vbData =  vb.Lock(0,1600, LockFlags.None);

        
//copy the vertex data into the vertex buffer
        vbData.Write(vertices);

        
//Unlock the VB
        vb.Unlock();


        
//This time, lock the entire VertexBuffer
        vbData =  vb.Lock(03200, LockFlags.None);

        
//Cast the InternalDataPointer (a void pointer) to an array of verticies
        PositionNormalTexVertex* vbArray = (PositionNormalTexVertex*) vbData.InternalDataPointer;

        
for(int i=0; i<100; i++)
        
{
            
//perform some operations on the data
            vbArray[i].Tu0 = i;
            vbArray[i].Tv0 
= vbArray[i].Tu0 * 2;

            Console.WriteLine(vbArray[i].Tv0.ToString());
        }


        
//Unlock the buffer
        vb.Unlock();
        vb.Dispose();
    }

}

Read and Write VertexBuffer Data With Arrays

using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

public struct PositionNormalTexVertex
{
    
public Vector3 Position;
    
public Vector3 Normal;
    
public float Tu0, Tv0;
    
public static readonly VertexFormats FVF = VertexFormats.Position | VertexFormats.Texture1;
}


public class Example
{
    
public void ArrayBasedReadWrite()
    
{
        
//Create a vertex buffer in the managed pool
        VertexBuffer vb = new VertexBuffer(typeof(PositionNormalTexVertex), 100, device, Usage.None, PositionNormalTex1Vertex.FVF, Pool.Managed);

        
//Fill an array of the appropriate type with the VB data using Lock()
        PositionNormalTexVertex[] vbData = (PositionNormalTexVertex[]) vb.Lock(0typeof(PositionNormalTexVertex), LockFlags.None, 50);
        
for(int i=0; i<50; i++)
        
{
            
//set your vertices to something
            vbData[i].Position = new Vector3(2f,2f,2f);  
            vbData[i].Normal 
= new Vector3(1f,0f,0f);
            vbData[i].Tu0 
= i;
            vbData[i].Tv0 
= i;
        }

        
//Unlock the vb before you can use it elsewhere
        vb.Unlock();

        
//This lock overload simply locks the entire VB -- setting ReadOnly can improve perf when reading a vertexbuffer
        vbData = (PositionNormalTexVertex[]) vb.Lock(0, LockFlags.ReadOnly);
        
for(int i=0; i<100; i++)
        
{
            
//read some vertex data
            Console.WriteLine("Vertex " + i + "Tu: " +  vbData[i].Tu0 + " , Tv: " + vbData[i].Tv0);
        }


        
//Unlock the buffer
        vb.Unlock();


        vb.Dispose();
    }

}

posted on 2006-05-12 13:55 梦在天涯 阅读(829) 评论(0)  编辑 收藏 引用 所属分类: DirectX


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1641425
  • 排名 - 5

最新评论

阅读排行榜