Experience with Direct3D

zhaozj2021-02-16  60

Experience with Direct3D

This article discusses the issue of using Direct3D9 on LOD terrain rendering, where the LOD is used in the LOD is used to maximize the simplest four-tree method. There are many articles in the four fork tree LOD, but there is almost no exception based on OpenGL discussion, although the concept is the main, concrete practical, because D3D is different from OpenGL, more operations, compare. About LOD's complete concepts and practical methods, and the difference between the practice of conventional OpenGL (such as cone cutting), this article is not mentioned.

This article only talked about my own experience, perhaps not a good party, but also prayed to the jade, advanced Mingda unsuccessful enlightened is fortunate!

With OpenGL, use Direct3D to use Direct3D, which is more troublesome in that the former can arbitrarily draw a vertex at any time, while D3D can only be drawn from fixed Vertex buffers, although there is a supported index buffer, but he The use of the function is similar to the Vertex buffer must also fill one-time filled (and must also specify a good vertex or the total number of INDEXs before), which is relatively unfavorable for the actual LOD. .

Based on this, a better strategy is to adopt a fixed VB, store the 2D vertex array, and the drawing work is completed by the fill IB. In order to be randomly added to OpenGL, I made a class of Class for IB. It is very simple, including a vector object with a STD, so as long as it will add the necessary vertices to the vector, and fill one-time after completion IB objects. It is as follows:

Class indexbuffervector // is used to add the total number of not pre-determined to indexBuffer to add a class.

{

protected:

LPDIRECT3DDEVICE9 LPD3DDEV; // D3D device indicator

Std :: Vector IndexVector; // Used to store the Vector of Index

PUBLIC:

LPDIRECT3DINDEXBUFFER9 LPIB; // IndexBuffer object

Void init (lpdirect3ddevice9 _lpd3ddev); // Initialization

Void AddIndex; // Add new INDEX in order

Bool FillBufferwithvector (); // Rebuild and populate IndexBuffer with vertices in VECTOR

INT getIndexNum (); // Get the total number of INDEX in the current vector

Void Clearvector (); // Clear the index in the Vector

Void release (); // release

}

Very simple but very practical, just use addIndex () to add the required vertex index to the Vector item, just call FillBufferwithvector () before drawing.

After this problem is solved, there is a unhappy problem. When using OpenGL, each time use Triangle_FAN to draw each rectangular block each time, this method is straightforward and efficient.

The rectangular block as shown above is done in accordance with 0, 1, 2, 3, and 4 order. However, for the entire gear consisting of a plurality of rectangular blocks, it is impossible to only quote the process of Triangle_fan. There are several rectangles to draw several Triangle_FANs. For D3D IB, it is one-time painted, which seems to only Use triangle_list to draw each triangle to specifically. Although I can re-painted a Triangle_FAN re-painted IB, so that every frame is to be aggravated and redraw more IB, although I didn't tried it, but I think the effect may be relatively low.

So I use Triangle_List, so although it needs to have more repetition of vertex, filling IB and drawing by simply completion. In this way, it is necessary to add 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 0, 3, 4, 0, 4, 1, but there is a problem in this way, such as the above. After the detection, the above triangle 0, 1, 2, need to make up a vertex 5, Triangle_FAN, only inserting a 5 in 1, 2 is 0, 1, 5, 2, but triangle_list is troublesome, need 0 1, 5, 0, 5, 2, ie, 5, 0, 5 INDEX, 0 is the current rectangular center point. For example, when you are in handing every rectangular block, the following Void Lodsystem :: Renderquad (int Xpos, int ypos, int size)

{

Switch (quadinfo.at (xpos, ypos) .state)

{

Case Divide: // If this piece can continue to subdivide

/ / Regenerate each sub-block

Renderquad (XPOS-SIZE / 2, YPOS-SIZE / 2, SIZE / 2);

Renderquad (XPOS SIZE / 2, YPOS-SIZE / 2, SIZE / 2);

Renderquad (XPOS-SIZE / 2, YPOS SIZE / 2, SIZE / 2);

Renderquad (XPOS SIZE / 2, YPOS SIZE / 2, SIZE / 2);

Break;

Case Draw: // Symnation This block can no longer be divided, you can draw it.

Ibv.addIndex (INDEXOF (XPOS, YPOS)); //

Ibv.addIndex (INDEXOF (XPOS-SIZE, YPOS-SIZE)); //

Remedytop (XPOS, YPOS, SIZE, INDEXOF (XPOS, YPOS));

Ibv.addIndex (INDEXOF (XPOS SIZE, YPOS-SIZE)); //

Ibv.addIndex (INDEXOF (XPOS, YPOS)); //

Ibv.addIndex (INDEXOF (XPOS SIZE, YPOS-SIZE)); //

RemedyRight (XPOS, YPOS, SIZE, INDEXOF (XPOS, YPOS);

Ibv.addIndex (INDEXOF (XPOS SIZE, YPOS SIZE)); // Right

Ibv.addIndex (INDEXOF (XPOS, YPOS)); //

Ibv.addIndex (INDEXOF (XPOS SIZE, YPOS SIZE)); // Right

Remedybottom (XPOS, YPOS, SIZE, INDEXOF (XPOS, YPOS);

Ibv.addIndex (INDEXOF (XPOS-SIZE, YPOS SIZE)); //

Ibv.addIndex (INDEXOF (XPOS, YPOS)); //

Ibv.addIndex (INDEXOF (XPOS-SIZE, YPOS SIZE)); //

Remedyleft (XPOS, YPOS, SIZE, INDEXOF (XPOS, YPOS);

Ibv.addIndex (INDEXOF (XPOS-SIZE, YPOS-SIZE)); //

Break;

DEFAULT:

Break;

}

}

Where RemedyTop (), etc. is used to detect and supplement whether the corresponding vertices INDEX (own recursive) according to the resolution of the adjacent cigle block. As shown below, in case the episode of the adjacent rectangular block is more than 2 or more, it is not only 5, and it is not only 5, and it is necessary to make up in 5 before 5. , 1, 6, 0, 6, 5, 0, 5, 2, can be inserted into the center point of the original rectangle when each make up one point (if you use triangle_fan, you don't need to manage these), this is why I want Void Remedytop (int XPOS, int ypos, int size, dword centerindex); // repair top

The final addition of an CENTERINDEX parameter is used to pass the center of the original rectangle, so that in these recursive processes, the rectangular center vertex can be transmitted in accordance with generation. such as

Void Lodsystem :: Remedytop (int XPOS, Int Ypos, int size, dword centerindex)

{

IF (YPOS-SIZE <= 0) //

Return;

IF (SIZE <1)

Return; // The resolution is no longer divided

IF (quadinfo.at (xpos, ypos-2 * size) .State == Divide) / / one piece can be divided

{

Remedytop (XPOS-SIZE / 2, YPOS-SIZE / 2, SIZE / 2, CENTERINDEX); // If there may be crack on //

// Draw this

Ibv.addIndex (INDEXOF (XPOS, YPOS-SIZE);

Ibv.addIndex (CenterIndex);

Ibv.addIndex (INDEXOF (XPOS, YPOS-SIZE);

Remedytop (XPOS SIZE / 2, YPOS-SIZE / 2, SIZE / 2, CENTERINDEX); // If there may be cracks on //

}

}

July 2004

转载请注明原文地址:https://www.9cbs.com/read-17375.html

New Post(0)