D3D学习笔记(渲染管道)

原创 2005年05月03日 21:15:00

渲染管道

它是用来创建为3D世界进行几何描述的2D图形并设定一个虚拟摄相机确定这个世界中哪一部分将被透视投影到屏幕上

 

D3D中最基础的东西——顶点渲染,这个东西就和2D游戏中的画点是一个道理,重要性就不多说了,一个字,“太重要了!”。
  渲染的基本步骤是这样的:
  (1)   定义顶点格式和FVF
  (2)   创建顶点缓冲区并填充之
  (3)   用D3D进行渲染

为了创建一个自定义的顶点结构,我们首先要创建一个包含能存放我们选择的顶点数据的结构。例如,下面我们定放了两种顶点数据类型,一种包含了位置和颜色信息,第二种则包含了位置,法线向量,纹理坐标信息

struct ColorVertex

{

     float _x, _y, _z; // position

     DWORD _color;

};

struct NormalTexVertex

{

     float _x, _y, _z; // position

     float _nx, _ny, _nz; // normal vector

     float _u, _v; // texture coordinates

};

一旦我们有了完整的顶点格式,我们就要使用灵活顶点格式(FVF)的组合标志来描述它。例如第一个顶点结构,我们要使用如下的顶点格式:

#define FVF_COLOR (D3DFVF_XYZ | D3DFVF_DIFFUSE)

上面的顶点结构表明它包含位置和颜色属性。

而第二种结构则要使用:

#define FVF_NORMAL_TEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

上面的顶点结构表明它包含了位置,法线向量,纹理坐标的属性。

有一点要注意,你的标志的顺序必须要和你的顶点结构的顺序一一对应。如果想知道所有的D3DFVF标志

 

上次写了个初始化设备的程序,现在就利用初始化的设备来进行画图了。

 

废话 不多说了 还是直接看程序了,这个程序是我刚才完成的。搞了一天才搞定的,先把程序贴出来再说吧。

下次来看在场景中设置摄像机,灯光、纹理、模型等等。记住路漫漫其修远兮,这才是长征的第一步:)。

下面是程序运行后效果

 

 

下面那个程序包含的头文件在上篇文章里有

 

//////////////////////////////////////////////////////////////////////////////////////////////////

//                               //

// (1)   定义点格式和FVF  // 定点渲染的基本三曲

// (2)   创建点缓冲区并填之  //

// (3)   用D3D进行渲染    //

//                               //

/////////////////////////////////////////////////////////////////////////////////////////////////

 

#include "d3dUtility.h"

 

//

// Globals

//

 

IDirect3DDevice9* Device = 0;

 

const int Width  = 640;

const int Height = 480;

 

 

//想要渲染点,首你得有个缓冲区,D3D中这样定义

//点缓冲区

IDirect3DVertexBuffer9* Triangle = 0; // vertex buffer to store

// our triangle data.

 

//

// Classes and Structures

//

//然后还得为顶点缓冲区里的数据定义格式,这样:

//自定义顶点结构

struct Vertex

{

       Vertex(){}

      

       Vertex(float x, float y, float z,DWORD color)

       {

              _x = x;   _y = y;  _z = z; _color=color;

       }

      

       float _x, _y, _z;//顶点位置

       DWORD _color; //顶点颜色

    static const DWORD FVF;//顶点格式

};

 

//FVF在D3D中的解释是Flexible vertex format,意思就是可变的顶点格式,具体内容参看DX9

const DWORD Vertex::FVF = D3DFVF_XYZ|D3DFVF_DIFFUSE;

 

 

 

//

// Framework Functions

//

 

//Setup的主要功能是创建顶点缓冲区并且填充该缓冲区

bool Setup()

{

       //

       // Create the vertex buffer.

       //创建顶点缓冲区(顶点缓存)

      

       Device->CreateVertexBuffer(

              3 * sizeof(Vertex), //Length —— 分配给缓存的字节大小。假如想得到一个能存储8个顶点的顶点缓存,

              //那么我们就要在顶点结构中设置这个参数为 8 * sizeof ( Vertex )

              D3DUSAGE_WRITEONLY, // 第二个参数暂时不管,填0

              Vertex::FVF,        // FVF —— 存储在缓存中的顶点格式

              D3DPOOL_DEFAULT,    //   Pool —— 缓存放置在哪一个内存池中           

              &Triangle,          // ——返回创建好的顶点缓存的指针。

              0);                 //没有使用;设置为0     

      

      

      

       ////////////////////////////////////////////////////////////////////////////////////////////

       // Fill the buffers with the triangle data.

       //                  访问缓冲内存

       //为了访问一个顶点/索引缓存,我们需要得到一个指针。

       //我们通过一个指针获得缓存数据必须使用Lock方法。当我们访问完缓存后必须对它解锁。

       //一旦有一个指向内存的指针,我们就能对它进行读写。

       //                               LOCK方式

       // HRESULT IDirect3DVertexBuffer9::Lock(UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,

       //     DWORD Flags);ppbData —— 一个指向锁定内存开始位置的指针

       /////////////////////////////////////////////////////////////////////////////////////////////////////

       // OffsetToLock —— 偏移量,以字节为单位,从缓存开始位置到锁定开始位置的距离。

       //SizeToLock —— 锁定的字节数。

       //ppbData —— 一个指向锁定内存开始位置的指针。

       //Flags —— 标记描述怎样锁定内存。它可能是0或者是下面参数中的1个或多个的组合:

       //D3DLOCK_DISCARD——这个参数仅仅会在动态缓存时被使用。它指示硬件丢弃缓存并返回一个指向新分配的缓存的指针。

       //                    这是很有用的因为当我们存取一个新分配的缓存时它允许硬件继续从丢弃的缓存渲染。这防止了硬件延迟。

       //D3DLOCK_NOOVERWRITE——这个参数仅仅会在动态缓存时被使用。它声明你将向缓存中添加数据。即,你不能向已经渲染的内存中写数据。

       //                      这是有好处的因为他允许你在添加新数据到缓存的同时让硬件继续渲染。

       //D3DLOCK_READONLY——这个参数声明你锁定的缓存只能从中读取数据而不能写数据。这允许一些内在的优化。

       //用参数D3DLOCK_DISCARDD3DLOCK_NOOVERWRITE的地址实际上就是缓存的一部分被使用(正在渲染)时它被锁定。

       //                                          假如情况允许这些标记被使用,当在锁定时他们防止渲染停止。

       /////////////////////////////////////////////////////////////////////////////////////////////////

      

       Vertex* vertices;

      

    Triangle->Lock(0, 0,(void**)&vertices, 0);

       vertices[0] = Vertex(-1.0f, 0.0f, 2.0f,0xffff0000);

       vertices[1] = Vertex( 0.0f, 1.0f, 2.0f,0xff0000ff);

       vertices[2] = Vertex( 1.0f, 0.0f, 2.0f,0xffffffff);

       Triangle->Unlock();

      

       //

       // Set the projection matrix.

       //

      

      

       D3DXMATRIX proj;

                            D3DXMatrixPerspectiveFovLH(

                                   &proj,                        // result

                                   D3DX_PI * 0.5f,               // 90 - degrees

                                   (float)Width / (float)Height, // aspect ratio

                                   1.0f,                         // near plane

                                   1000.0f);                     // far plane

                            Device->SetTransform(D3DTS_PROJECTION, &proj);

                           

                           

                           

                            //

                            // Set wireframe mode render state.

                            //

                            // 关闭culling,让我们能看到3角型的正反面

                            Device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

                           

                            // 关闭灯光,因为我们的顶点有自己的颜色

                            Device->SetRenderState( D3DRS_LIGHTING, FALSE );

                           

                            //Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

                           

                           

                            return TRUE;

}

void Cleanup()

{

       d3d::Release<IDirect3DVertexBuffer9*>(Triangle);

}

 

bool Display(float timeDelta)

{

       if( Device )

       {

              // 清除背景为0xffff0000

              Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);

              // 开始绘制场景

              Device->BeginScene();

             

              // --渲染图形--

              // 指定渲染源

              Device->SetStreamSource(0, Triangle, 0, sizeof(Vertex));

              // 指定自定义的FVF

              Device->SetFVF(Vertex::FVF);

             

              // Draw one triangle. 渲染

              Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

              // 结束场景绘制

              Device->EndScene();

              // 显示到屏幕上

              Device->Present(0, 0, 0, 0);

       }

       return true;

}

 

 

//

// WndProc

//消息处理

LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

       switch( msg )

       {

       case WM_DESTROY:

              ::PostQuitMessage(0);

              break;

             

       case WM_KEYDOWN:

              if( wParam == VK_ESCAPE )

                     ::DestroyWindow(hwnd);

              break;

       }

       return ::DefWindowProc(hwnd, msg, wParam, lParam);

}

 

//

// WinMain

//

int WINAPI WinMain(HINSTANCE hinstance,

                               HINSTANCE prevInstance,

                               PSTR cmdLine,

                               int showCmd)

{

       if(!d3d::InitD3D(hinstance,

              Width, Height, true, D3DDEVTYPE_HAL, &Device))

       {

              ::MessageBox(0, "InitD3D() - FAILED", 0, 0);

              return 0;

       }

      

       if(!Setup())

       {

              ::MessageBox(0, "Setup() - FAILED", 0, 0);

              return 0;

       }

      

       d3d::EnterMsgLoop( Display );

      

       Cleanup();

      

       Device->Release();

      

       return 0;

}

 

 

[面经]阿里游戏一面的算法题

前言:两天前参加阿里游戏的面试,一面时出了一道面试题。那时我看楞了,好像没做过这种题型,看起来很容易又很难。很容易是,使用O(N^2)就可以解决,难得是,优化时间复杂度。 题目:字符串删...

快速排序

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分...
  • Turne
  • Turne
  • 2017年09月01日 13:18
  • 84

Unity3D Shader官方教程翻译Unity3D 的渲染管道

Unity's Rendering Pipeline Shaders define both how an object looks by itself (its material proper...

D3d9c的固定渲染管道(fixed function pipeline)与可编程管道(programmable function pipeline)的异同点

现在的游戏图形部分越来多依靠GPU来渲染绘制。说起GPU先说着色器,着色器是可编程的(programmable),分为顶点着色器和像素着色器。着色器是一段运行在GPU上的程序,可以取代渲染的固定功能流...
  • mathlmx
  • mathlmx
  • 2011年12月04日 09:00
  • 443

蛋哥的学习笔记之-基于Unity的Shader编程:0-2 基本3D图形渲染管线概述

一、要干些啥: 今天主要概括和整理下基本的3D图形渲染管线,说白了就是让大家了解一下,我们是如何通过给定的一堆数据:视点(相机)、3D模型、光源、光照模型、纹理和渲染方式等,进行一系...

Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(一)

渲染管线是指:在给定一个3D场景的几何描述及一架已确定位置和方向的虚拟摄像机(virtual camera)时,根据虚拟摄像机的视角生成2D图像的一系列步骤(如图5.1所示)。本章的内容大部分是理论性...

Introduction to 3D Game Programming with DirectX 11学习笔记 5 渲染管线(三)

规范化深度值你可能认为在投影之后可以丢弃原始的3D z坐标,因为所有的投影点已经摆放在2D投影窗口上,形成了我们最终看到的2D图像,不会再使用3D z坐标了。其实不然,我们仍然需要为深度缓存算法提供3...

code_opengl学习笔记3-1-在3D中绘制点

  • 2013年09月30日 18:09
  • 7.54MB
  • 下载

unity3d NGUI官网示例详解及学习笔记

  • 2013年11月21日 22:13
  • 13.33MB
  • 下载

android学习笔记之3D--(03)-Renderer类 渲染类

原文地址:http://blog.csdn.net/geolo/article/details/5958440 public static interface GLSurfaceView.Re...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:D3D学习笔记(渲染管道)
举报原因:
原因补充:

(最多只允许输入30个字)