Шаг 1. Начнём с изменения тех методов которые уже использовались в нашем проекте - облегчим методыLoadContent() и Draw() путём переноса из них части кода в отдельные методы. Начнём с метода LoadContent(): уберём из него весь код создания вершин и загрузки шейдера, а на его место вставим код вызова методов СreateVertexList(),СreateIndexList() и СreateEffect() в которых и будут создаваться вершины, индексы и шейдер. Данные методы мы реализуем чуть позже.
1 2 3 4 5 6 7 8 9 10 11 12 13
protectedoverridevoid LoadContent() { СreateVertexList();// создать вершины СreateIndexList();// создать индексы // создать объект Effect используя контент менеджер effect = Content.Load("Effect"); // создать описание формата вершин vertexDeclaration =new VertexDeclaration( graphics.GraphicsDevice, VertexPositionColor.VertexElements); }
Шаг 2. Из метода Draw() уберём весь код рисования 3D-объекта и вставим на его место вызов метода DrawCube()который после реализации будет рисовать куб.
1 2 3 4 5 6 7 8 9 10 11
protectedoverridevoid Draw(GameTime gameTime) { // отчистка экрана в синий цвет graphics.GraphicsDevice.Clear(Color.Blue); // нарисовать куб DrawCube(); // вывод сцены на экран base.Draw(gameTime); }
Шаг 3. Добавим в класс Program новое поле indexList которое будет массивом индексов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Program : Game { // графический компонент GraphicsDeviceManager graphics; // массив вершин VertexPositionColor[] vertexList; // массив индексов int[] indexList; // описание формата вершин VertexDeclaration vertexDeclaration; // эффект (шейдер) Effect effect; // счетчик времени float time;
Шаг 4. Начнём создавать и реализовывать новые методы в классе Programm. Первым будет метод СreateVertexList() в котором мы должны написать код создания массива вершин. Этот код очень похож на тот что был у наc раньше в методе LoadContent(), но отличается от него тем, что вместо 3-х вершин описывающих углы треугольника мы создаём 8 вершин описывающик углы куба.
/// /// создание и заполнение массива вершин /// privatevoid СreateVertexList() { // создать массив-контейнер для хранения трёх вершин vertexList =new VertexPositionColor[8]; // верхний набот вершин vertexList[0]=new VertexPositionColor(new Vector3(-1.0f, -1.0f, 1.0f), Color.Yellow); vertexList[1]=new VertexPositionColor(new Vector3(1.0f, -1.0f, 1.0f), Color.Red); vertexList[2]=new VertexPositionColor(new Vector3(-1.0f, -1.0f, -1.0f), Color.Red); vertexList[3]=new VertexPositionColor(new Vector3(1.0f, -1.0f, -1.0f), Color.Yellow); // нижний набор вершин vertexList[4]=new VertexPositionColor(new Vector3(-1.0f, 1.0f, 1.0f), Color.Red); vertexList[5]=new VertexPositionColor(new Vector3(1.0f, 1.0f, 1.0f), Color.Yellow); vertexList[6]=new VertexPositionColor(new Vector3(-1.0f, 1.0f, -1.0f), Color.Yellow); vertexList[7]=new VertexPositionColor(new Vector3(1.0f, 1.0f, -1.0f), Color.Red); }
Шаг 5. Создадим метод СreateIndexList(). Данный метод должен позаботиться о создании массива индексов. Каждые 3 индекса в массиве индексов ссылаются на 3 вершины в массиве вершин тем самым описывают 3 угла треугольника. Пара треугольников, или 6 индексов составляют грань куба.
/// /// рендеринг куба /// void DrawCube() { // использовать для отрисовки эффект BasicEffect effect.Begin(); // начать отрисовку первого прохода effect.CurrentTechnique.Passes[0].Begin(); // указать описание формата вершин graphics.GraphicsDevice.VertexDeclaration= vertexDeclaration; // отключить отсечение невидимых поверхностей graphics.GraphicsDevice.RenderState.CullMode= CullMode.None; // нарисовать треугольник используя массив вершин graphics.GraphicsDevice.DrawUserPrimitives (PrimitiveType.TriangleList, vertexList, 0, 1); // завершить первый проход effect.CurrentTechnique.Passes[0].End(); // завершить использование эффекта BasicEffect effect.End(); }
Шаг 7. Заменим вызов метода graphics.GraphicsDevice.DrawUserPrimitives() на вызов методаgraphics.GraphicsDevice.DrawUserIndexedPrimitives(). Второй метод отличается от первого тем, что он рисует индексированные примитивы, т.е. кроме массива вершин использует массив индексов.
/// /// рендеринг куба /// void DrawCube() { // использовать для отрисовки эффект BasicEffect effect.Begin(); // начать отрисовку первого прохода effect.CurrentTechnique.Passes[0].Begin(); // указать описание формата вершин graphics.GraphicsDevice.VertexDeclaration= vertexDeclaration; // отключить отсечение невидимых поверхностей graphics.GraphicsDevice.RenderState.CullMode= CullMode.None; // нарисовать куб используя массив вершин и индексов graphics.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, // тип примитивов vertexList, // массив вершин 0, // позиция первой используемой вершины 8, // кол-во используемых вершин indexList, // массив индексов 0, // позиция первого используемого индекса 12);// кол-во выводимых примитивов // завершить первый проход effect.CurrentTechnique.Passes[0].End(); // завершить использование эффекта BasicEffect effect.End(); }
Итак мы нарисовали куб состоящий из 12 треугольников, но вместо 36 вершин (по 3 на треугольник) мы создали только 8 (описывающих углы куба) и с помощью индексов мы из 8 вершин собрали 12 треугольников. Теперь при запуске приложения вы увидите окно в котором будет "летать" цветной куб.
842 Прочтений • [Урок 6. Как создавать и использовать индексы для рисования сложных 3D объектов] [08.08.2012] [Комментариев: 0]