Rendering saved geometric Images

Source: Internet
Author: User

Model Objects eventually contain a series of vertexbuffer and indexbuffer objects, which we will use to draw objects on the screen. And the simplicity from the last chapterCubeBody examples are different. However, it is very likely that the model will contain multiple triangles, all of which must be drawn together to form a complete object. For this reason, the model object contains a set of hierarchies. Positive must be used to obtain vertex data.

A model object contains a meshes attribute, which provides a set of modelmesh objects. Each modelmesh represents a group of triangles that are presented at the object position.

The reason for multiple model mesh objects is that model objects can store the geometry that contains some complex classes. Imagine, for example, if you want to render a helicopter model. There are three main parts of the helicopter model: body, body rotation, and tail. The propeller can be moved and associated with the helicopter so that they can be rotated. They can understand a part of the helicopter, but we cannot simply use the helicopter transformation matrix.

XNa allows each split block of the model. It is called bones in xNa terminology and can be converted separately. This is why the model can be stored and rendered in multiple blocks. We will not explore more details about bones and how to use them in this book, but on the internet you should be able to find a lot of information through search engines, if you want to know more about the content, you will be given more information.

Contains the modelmesh object and another set, modelmeshpart object, which contains the attribute meshparts. Model mesh refers to the collection of multiple model grids to form a part of the entire geometry. This method is used to divide the model mesh into multiple parts because each part has parameters different from other parts, such as textures. If multiple textures are used in the model, different textures can be activated and rendered separately.

In the modelmeshpart class we finally found, both indexbuffer and vertexbuffer are hidden. In addition to the other attributes, vertexoffset is required when the setvertexbuffer function is used and the vertex buffer is used to set the mesh part. The drawindexedprimitives function is used to render the mesh part, all numvertices, startindex, and primitivecount are required.

There are two different functions that we can use to draw a model. First, we need to use each grid part in order to tell each grid to use their own effect objects to draw them themselves.

The models provided by these effects objects do not require us to create them, but of course they do not know anything about the environment we build. To make the mesh part correctly rendered on the screen, we need to give it the world, perspective, and projection matrix it can use.

BelowCodeThe objectmodel variable contains the rendered model, and the effect variable is class-level basiceffect. In order to require all matrix pre-configuration, use the mesheffect object to traverse the effect objects provided by each model.

  // build an array of the absolute bone transformation matrices matrix []  bonetransforms =  New  matrix [objectmodel. bones. count]; objectmodel. copyabsolutebonetransformsto (bonetransforms );  // loop for each of the meshes within the model   foreach  (modelmesh  in  objectmodel. meshes) { // initialize each of the effects within the mesh   foreach  (basiceffect mesheffect  in  mesh. effects) {mesheffect. world = bonetransforms [mesh. parentbone. index] * effect. world; mesheffect. view = effect. view; mesheffect. projection = effect. projection;}  // draw the mesh (including all of its meshparts)  mesh. draw () ;}

Note: In addition to drawing a model, this code also processes the location of bone in the model. The copyabsolutebonetransformsto function uses the final coordinates of each bone to fill the array, considering the bone level. Then these transformations determine the final coordinates for each bone based on the active world matrix. Because our model does not contain bone, the conversion will not work, but the code will be compatible with more complex models.

The code will do anything necessary to make the object appear on the screen, but it has a disadvantage: because the effect object used for rendering the model is not effective, we created and configured it in our main game categories. None of them showed our effect attribute values in the model's effect object. As in the previous code, the effect conversion matrix does not need to be copied from our effect to the effect object of the model.

When these matrices are set to make the model appear at the current position on the screen, a large number of other attributes will not be copied here, So rendering objects will be ignored. These attributes include highlight attributes, diffuse and radiant colors, Alpha values, or more.

Therefore, the alternative solution is to use our own effect object to render the model. This already contains all the attributes we need to observe from the model, so we don't have to worry about any processing of them in the rendering code. We can simply recursive the mesh and render each of them directly.

There is a key part of the information. The model effect object contains our own effect object: Use texture for each mesh part. Previously, the Code draws fully-textured objects, even if there is no reference to textures in the code. We can read the texture from the model effect and use the texture in our own effect to ensure that the current texture can be applied to every part of the model.

The code can do this, and then use the information provided by the modelmeshpart object to build vertex and index buffering, and draw them. The code for rendering in this way is as follows.

Matrix initialworld; matrix [] bonetransforms; // Store the initial world Matrix initialworld = effect. World;// Build an array of the absolute bone Transformation Matrices bonetransforms = New Matrix [objectmodel. Bones. Count]; objectmodel. copyabsolutebonetransformsto (bonetransforms ); // Loop for each Mesh  Foreach (Modelmesh Mesh In Objectmodel. Meshes ){ // Update the world matrix to account for the position of this bone Effect. World = bonetransforms [mesh. parentbone. Index] * effect. World; // Loop for each mesh part      Foreach (Modelmeshpart meshpart In Mesh. meshparts ){// Set the texture for this meshpart Seteffecttexture (effect, (basiceffect) meshpart. effect). Texture ); // Set the vertex and index Buffers Effect. graphicsdevice. setvertexbuffer (meshpart. vertexbuffer, meshpart. vertexoffset); effect. graphicsdevice. Indices = meshpart. indexbuffer; // Draw the mesh part          Foreach (Effectpass Pass pass In Effect. currenttechnique. Passes ){ // Apply the pass Pass. Apply (); // Draw this meshpart Effect. graphicsdevice. drawindexedprimitives (primitivetype. trianglelist, 0, 0, meshpart. numvertices, meshpart. startindex, meshpart. primitivecount );}}} // Restore the initial world Matrix Effect. World = initialworld;

There are some points of interest in this Code. Some operations are the same. You can see in the previous code that we restored the absolute bone array conversion and then the mesh set of our recursive model. In each grid, we do not update the effect attribute because we use our own effect this time. It has been configured to use all the required matrices and other attributes, such as lighting and materials. One thing we have to do is observe the position of bone. Before the loop, copy from the original world matrix and multiply it by the bone position of each grid.

The effect is that we are now ready to render the mesh, So we develop and process each part of it. The first thing we need to do for each part is to ask its own effect object and read the needed texture. Through this process, we call our own results object to a process called seteffecttexture. This is a simple function. It places the texture 2D provided into the provided effect, and the provided texture does not exist yet.

With the texture settings, the Code sets the vertexbuffer and indexbuffer of the grid part to the graphics device. This makes preparations for index rendering.

The final mesh part is ready for rendering. As we have already prepared, we will then render the index Triangle List to each part for every javastpass loop. Note that all the details about the rendering required by drawindexedprimitive will be provided by the mesh section, so this is very straightforward.

In the end, after all the loops are completed, the initialized world matrix will be re-stored back to our effect, rewriting any bone conversions left there. This will stop unexpected slow conversions during rendering.

Although the Code is not very complex, it is a bit large and idealistic if we avoid repeating every object in our game. Fortunately, the game framework will help us get out of this problem again and let's see how we can integrate and render the feature model we have added.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.