Форум программистов, компьютерный форум, киберфорум
XNA/MonoGame
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.98/56: Рейтинг темы: голосов - 56, средняя оценка - 4.98
34 / 11 / 0
Регистрация: 22.09.2010
Сообщений: 357
1

Проблемы, связанные с ContentManager и загрузкой/выгрузкой контента

31.12.2010, 13:40. Показов 10304. Ответов 106
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Краткая сводка:

1) Рабочий пример загрузки текстуры
2) RootDirectory нельзя изменить после присвоения. Однако это не мешает инициализировать её абсолютным путём, например: "C:\\"
3) Пример загрузки в случае RootDirectory = "Content" (расширения при загрузке не указываются):
C#
1
texture = Content.Load<Texture2D>(@"folder1\\folder2\\texture");
4) Пример загрузки текстуры, не используя ContentManager:
C#
1
texture = Texture2D.FromStream(GraphicsDevice, File.OpenRead("путь" + ".png"));
5)При выгрузке ассетов(не всех сразу вызовом Unload()), занимаемая ими память не освобождается даже при обнулении ссылки на ассеты и вызова сборщика мусора. Память высвобождается путём обнуления ссылок, которые указывают на этот экземпляр контент менеджера. Есть несколько способов избежать этого:
__А) создавать ContentManager на каждый ассет.
__Б) создать свой класс. наследуя от ContentManager

6) Способ загрузки эффектов, текстур, моделей и т.д. в реальном времени (динамическая компиляция).

7) Чтобы игра не зависала при длительных загрузках, загружать нужно в отдельном потоке, используя классы Thread/Task и т.д.

___________________________________________________________

Помогите, не пойму в чем проблема, в участке кода
spriteTexture = content.Load<Texture2D>(@"all\textures\qwerty1");
выскакивает исключение Error loading "all\textures\qwerty1". File not found.
Хотя в проект добавлен каталог all и в нем textures и внутри файл qwerty1.jpg, и через проект изображение открывается. Я даже задавал полный путь - то же самое пишет.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.12.2010, 13:40
Ответы с готовыми решениями:

Проблемы с выгрузкой файлов
Здравствуйте при выгрузке файлов, при совпадении имен как я понимаю почему то одному файлу...

Проблемы с выгрузкой информации в Excel
Есть вьюха первое поле - номер во вьюхе остальные поля с данными текстовыми и одно поле...

Настройки Биос, связанные с загрузкой?
Доброго времени суток! Постигла меня следующая проблема: в windows отказали клавиатура и мышь...

Отслеживание изменений URL на сайте с динамической загрузкой контента
Подскажите пожалуйста, как отслеживать изменения URL при динамической загрузке контента,...

106
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
01.02.2012, 22:03 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от za5 Посмотреть сообщение

Не по теме:

когда компилируешь какой-то определённый fbx, просто создавай отдельную папку, а потом все текстуры туда и распакуются в .xnb какие надо.)
это наверняка самый простой способ. ещё можно таскать с моделью текстовый файл со списком текстур

Как раз по теме. Я делаю редактор. Идея такая. Временно загрузил модель (текстуру и прочее), подошла, сохраняешь в ту папку, с которой будешь брать уже скомпилированную модель (.xnb).
Программа должна сама знать.Теоретически, это необходимо только для файлов с моделями (меши).
Здесь два варианта, либо сделать свой импортер, который будет читать .fbx и сохранять список файлов текстур для этой модели. Либо научиться читать сам файл .xnb, и при копировании считывать с него файлы текстур.
Но как прочитать эти файлы?
0
za5
01.02.2012, 22:52
  #22

Не по теме:

Цитата Сообщение от Nukutu Посмотреть сообщение
либо сделать свой импортер, который будет читать .fbx и сохранять список файлов текстур
первый вариант можно и без импортера.
второй вариант лишняя трата времени скорее всего.

0
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
02.02.2012, 14:17 23
Цитата Сообщение от za5 Посмотреть сообщение

Не по теме:


первый вариант можно и без импортера.
второй вариант лишняя трата времени скорее всего.

Не понял, какой вариант можно без импортера?
Все таки хотелось бы автоматизировать процесс, какие файлы надо копировать. А то недоработок в XNA еще много, не может найти файл текстуры, а пишет совсем другую ошибку.
0
444 / 348 / 32
Регистрация: 16.10.2010
Сообщений: 842
Записей в блоге: 7
02.02.2012, 16:00 24
Цитата Сообщение от Nukutu Посмотреть сообщение
Не понял, какой вариант можно без импортера?
Все таки хотелось бы автоматизировать процесс, какие файлы надо копировать. А то недоработок в XNA еще много, не может найти файл текстуры, а пишет совсем другую ошибку.
здесь не нужно изменять импортер для того чтобы получить список текстур. просто в новую папку компилировать и считывать список текстур, потом просто считывать список текстур при наличии txt.

а... всё. понял. ты же имеешь ввиду ещё и свои текстуры. тогда да. просто три строчки в твоём импортере и готово.
0
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
02.02.2012, 17:46 25
Понятно, что, как всегда, приходится изворачиваться и находить пути решения. Но, чем дальше в глубь XNA, тем "лес" становится темнее, дремучее и не понятнее.
Например, в том же примере, создает файл model.xnb и к нему текстуру cat_0.xnb из файла текстуры cat.tga
Сразу возникает вопрос, где найти название этого файла в проге (cat_0.xnb) и как формируется имя файла (ведь оно не совпадает с cat.tga)? Все перерыл, а намека нет. Если я буду использовать ту же текстуру для другой модели, то что произойдет, он создаст новое имя файла, в котором будет та же текстура и придется два раза одно и то же грузить?
Цитата Сообщение от za5 Посмотреть сообщение
просто три строчки в твоём импортере и готово.
Подскажи пожалуйста какие, а то совсем уже не понимаю логики разработчиков XNA.
0
za5
03.02.2012, 00:50
  #26

Не по теме:

Цитата Сообщение от Nukutu Посмотреть сообщение
cat_0.xnb
добавь вот эту строчку после // Build this new model data.

C#
1
MessageBox.Show(String.Join("\n", Directory.GetFiles(contentBuilder.OutputDirectory).Select(str => Path.GetFileName(str)).Where(str => str != "Model.xnb")));
100% работает. проверено.

Цитата Сообщение от Nukutu Посмотреть сообщение
Если я буду использовать ту же текстуру для другой модели, то что произойдет, он создаст новое имя файла, в котором будет та же текстура и придется два раза одно и то же грузить?
... есть подозрение, что эта цифра добавляется на случай предотвращения совпадений имён при наличии одноимённых текстур с разными расширениями, может предположить, что нет одноимённых текстур т.е. всегда будет добавляться только _0. хотя нет... тут же ещё сложный вопрос как заставить отменить повторную загрузку( ведь исходника "ModelProcessor" нет.

Добавлено через 9 минут
Цитата Сообщение от Nukutu Посмотреть сообщение
Все перерыл, а намека нет.
ещё намёк может быть найден путём просмотра FBXImporter.dll

0
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
03.02.2012, 04:26 27
В общем, сырая эта XNA. Только для примитивных игр.
Например, ContentManager может очистить только весь загруженный контент (модели, текстуры и прочее). Получается, что я не могу удалять выбранные мною контенты, если они мне не нужны в реадкторе игры.
Наверное надо попробовать еще SlimDX.
0
444 / 348 / 32
Регистрация: 16.10.2010
Сообщений: 842
Записей в блоге: 7
03.02.2012, 21:40 28
Цитата Сообщение от Nukutu Посмотреть сообщение
В общем, сырая эта XNA.
вчера смотрел декомпилятором этот fbximporter.dll contentprocessor.dll кучу процессоров для составных частей модели пересмотрел кучу классов contentwriter'ов увидел как всё это сложно а также увидел место где в итоге всё сохраняется. т.е. самому здесь что-либо поменять пока вряд ли можно. для распаковки этого fbx, там юзается встроенная в дллку fbxsdk та самая, которую можно скачать. так что есть посмотреть на fbxsdk?
и ещё одна непонятка: почему не хочешь грузить одну и ту же текстуру, что в двух fbx'ах два раза например. и как часто в разных fbx'ах оказываются тестуры с одинаковыми именами?... здесь видимо просто надо как-то получить список текстур с помощью fbxsdk (если не подходит тот способ который я описал в одной строчке и который сохраняет нам список скомпилированных текстур , дающий нам право при перемещении какой-то модели не переносить её текстуру, которая также используется соседней моделью - т.е. будем знать, что её надо скопировать либо удалить вообще, в случае если в директории не осталось моделей юзающих эту текстуру)
Цитата Сообщение от Nukutu Посмотреть сообщение
Только для примитивных игр.
имхо не стоит судить о хне только потому, что чем-то неустроила работа с контентом.)
может потом что-нибудь добавят в этом плане. кто знает.
Получается, что я не могу удалять выбранные мною контенты, если они мне не нужны в реадкторе игры.
покажи пару строчек где ты пытался удалять выбранные тобою контенты. и какие контенты выбираются и в каких преобразования они исп.?
1
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
03.02.2012, 22:11 29
Цитата Сообщение от za5 Посмотреть сообщение
покажи пару строчек где ты пытался удалять выбранные тобою контенты. и какие контенты выбираются и в каких преобразования они исп.?
Контент менеджер имеет только contentManager.Unload();, которой удаляется весь загруженный контент. Просто другого метода в нем не предусмотрено для удаления контента.
Так что и нечего писать.

Добавлено через 3 минуты
По поводу текстур. Тут трудно предположить что и когда будет использоваться, а если еще разные люди делают. Программа должна работать не зависимо кто как создает модели и на чем. Можно одну и ту же текстуру грузить 100 раз, вот только для производительности как это будет выглядеть?

Добавлено через 10 минут
Как я вижу работу редактора игры. Кто-то сделал модель, дал мне ее, я подключил ее в редактор, посмотрел, сохранил в списке. Потом новая модель. Потом сотая модель. Если два разных человека для двух моделей использовали одну и ту же текстуру, то грузиться она будет в память дважды. Но тут еще коллизия наступит. Модели с текстурами будут сохраняться в одной папке. Первая модель компилируется и создает текстуру, добавляя "_0", вторая добавит, наверное уже "_1" к названию текстуры. В итоге я сам запутаюсь, они разные или одинаковые.
0
444 / 348 / 32
Регистрация: 16.10.2010
Сообщений: 842
Записей в блоге: 7
04.02.2012, 21:47 30
http://create.msdn.com/en-US/sample/xnb_format
http://create.msdn.com/en-US/s... extensions

Добавлено через 3 минуты
Цитата Сообщение от Nukutu Посмотреть сообщение
Контент менеджер имеет только contentManager.Unload();, которой удаляется весь загруженный контент. Просто другого метода в нем не предусмотрено для удаления контента.
другого метода и не нужно.
если ты говоришь об
вот этом куске
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        /// <summary>
        /// Loads a new 3D model file into the ModelViewerControl.
        /// </summary>
        void LoadModel(string fileName)
        {
            Cursor = Cursors.WaitCursor;
 
            // Unload any existing model.
            modelViewerControl.Model = null;
            contentManager.Unload();
 
            // Tell the ContentBuilder what to build.
            contentBuilder.Clear();
            contentBuilder.Add(fileName, "Model", null, "ModelProcessor");
 
            // Build this new model data.
            string buildError = contentBuilder.Build();
 
            if (string.IsNullOrEmpty(buildError))
            {
                // If the build succeeded, use the ContentManager to
                // load the temporary .xnb file that we just created.
                modelViewerControl.Model = contentManager.Load<Model>("Model");
            }
            else
            {
                // If the build failed, display an error message.
                MessageBox.Show(buildError, "Error");
            }
 
            Cursor = Cursors.Arrow;
        }
и тебя смущает то, что очищается всё, а не выборочно, так почему бы не ввести просто List<Model>????.
1
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
04.02.2012, 22:17 31
Смущает следующее:Model = contentManager.Load<Model>("Model"); - добавляется конкретная модель.
Далее contentManager может добавить еще несколько моделей, например (не буду обрамлять в тег кода), Model1 = contentManager.Load<Model>("Model1");, Model2 = contentManager.Load<Model>("Model2");
Да я могу обнулить любую модель, Model1 = null;
Но как при этом себя поведет contentManager при следующей загрузке Model1 = contentManager.Load<Model>("Model1");?
В коде показано, что modelViewerControl.Model = null; и contentManager.Unload();
Выходит contentManager где-то держит список загруженного контента. Но метода Remove() для конкретного метода нет. Ведь не случайно разработчик не ограничился только первой строчкой modelViewerControl.Model = null;
Скорее всего при закладывании логики в XNA не подумали, что придется грузить контент динамически, а не только через компилирование.
Потому, что если только через компилирование, то понятно, что весь контент загружается на стадии компиляции и предусматривать выгрузку одного какого-то контента нет смысла.
0
444 / 348 / 32
Регистрация: 16.10.2010
Сообщений: 842
Записей в блоге: 7
05.02.2012, 23:25 32
в принципе да. у меня тоже ошибку выдал когда попытался кое-что сделать. может тогда через List<ContentManager> т.е. каждая модель будет ассоциирована со своим как ContentManager? и ещё:
порылся в методах и увидел некоторую protected readasset, честно говоря, исходя из её описания можно написать свой контэнт мэнэджэр наследуя и переопределяя

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        //
        // Сводка:
        //     Низкоуровневый рабочий метод, который считывает данные актива.
        //
        // Параметры:
        //   assetName:
        //     Имя актива, который будет загружен с диска.
        //
        //   recordDisposableObject:
        //     Делегируйте функцию для обработки ликвидации активов. Если значение recordDisposableObject
        //     равно null, используется отслеживание и управление продолжительностью существования
        //     по умолчанию, поэтому выгрузка или ликвидация диспетчера содержимого удаляет
        //     все, что было загружено через этот диспетчер. Если recordDisposableObject
        //     указывает допустимый делегат, последний используется вместо отслеживания
        //     продолжительности существования по умолчанию и вызывается каждый раз, когда
        //     загрузчик встречает тип, реализующий IDisposable. Необходимо использовать
        //     собственный код для выгрузки активов, которые были загружены подобным образом,
        //     так как метод ContentManager's Unload не будет знать об их наличии.
        [SuppressMessage("Microsoft.Design", "CA1004")]
        protected T ReadAsset<T>(string assetName, Action<IDisposable> recordDisposableObject);
потом залез гугол и это увидел: http://blogs.msdn.com/b/shawnh... asset.aspx !

Добавлено через 23 часа 25 минут
отсюда очевидный вывод: если мы не можем
чего-либо сделать, то это не значит, что это нельзя сделать )
1
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
06.02.2012, 11:35 33
Цитата Сообщение от za5 Посмотреть сообщение
отсюда очевидный вывод: если мы не можем
чего-либо сделать, то это не значит, что это нельзя сделать )
Тогда еще подскажите как правильно удалять с
C#
1
List<IDisposable> disposableAssets = new List<IDisposable>();
вот в этом методе
C#
1
2
3
4
public void Remove<T>(string assetName)
        {
            loadedAssets.Remove(assetName);
        }
по аналогии с
C#
1
2
3
4
5
6
7
8
public override void Unload() 
        { 
            foreach (IDisposable disposable in disposableAssets)  
                disposable.Dispose(); 
 
            loadedAssets.Clear(); 
            disposableAssets.Clear(); 
        }
0
444 / 348 / 32
Регистрация: 16.10.2010
Сообщений: 842
Записей в блоге: 7
07.02.2012, 21:43 34
Цитата Сообщение от Nukutu Посмотреть сообщение
Тогда еще подскажите как правильно удалять с
C#
1
List<IDisposable> disposableAssets = new List<IDisposable>();
вот в этом методе
вот это:
List<IDisposable> disposableAssets = new List<IDisposable>();
заменить на
Dictionary<IDisposable, string> disposableAssets = new Dictionary<IDisposable, string>();
а дальше ясно. вызываем Dispose() потом удалять из loadedassets, потом из dispassets по имени. или так не работает?
0
181 / 107 / 13
Регистрация: 22.03.2010
Сообщений: 456
08.02.2012, 03:19 35
Цитата Сообщение от za5 Посмотреть сообщение
так не работает
Проблема в том, что как добавить?
Вот здесь:
C#
1
protected T ReadAsset<T>(string assetName, Action<IDisposable> recordDisposableObject);
Передается только один параметр.

И еще, я проверял, на одну запись модели записывается несколько IDisposable объектов.
Что там происходит в ReadAsset, не понятно.
0
14 / 14 / 8
Регистрация: 31.05.2012
Сообщений: 210
Записей в блоге: 2
13.06.2012, 23:41 36
Вроде все правильно...

вот ошибка... как исправить?


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
 
namespace TEST_3D_Project
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        Model _home;
        Matrix _world;
        Matrix _view;
        Matrix _proj;
        Matrix _gameWorldRotation;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            _home = Content.Load<Model>("abc");
        }
        protected override void Initialize()
        {
            base.Initialize();
        }
        protected override void LoadContent()
        {
        }
        protected override void UnloadContent()
        {
 
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            base.Update(gameTime);
        }
        private void DrawModel(Model model, Matrix world, Matrix view, Matrix proj)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.View = view;
                    effect.World = world * transforms[mesh.ParentBone.Index];
                    effect.Projection = proj;
                }
                mesh.Draw();
            }
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            _view = Matrix.CreateLookAt(new Vector3(0, 700, 500), Vector3.Zero, Vector3.Up);
            _proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1.0f, 1000);
            _gameWorldRotation = Matrix.CreateRotationZ(MathHelper.ToRadians((float)gameTime.ElapsedGameTime.TotalMilliseconds / 100));
            _world = _world * _gameWorldRotation; 
            DrawModel(_home, _world, _view, _proj);
            base.Draw(gameTime);
        }
    }
}
Миниатюры
Проблемы, связанные с ContentManager и загрузкой/выгрузкой контента   Проблемы, связанные с ContentManager и загрузкой/выгрузкой контента  
0
22 / 22 / 1
Регистрация: 17.07.2011
Сообщений: 53
14.06.2012, 01:24 37
скорее всего в LoadContent перенести эту строчку
0
6 / 6 / 0
Регистрация: 01.08.2011
Сообщений: 133
02.08.2012, 06:23 38
День добрый. Два вопроса, как бы альтернатива друг другу:

1. Как загрузить шейдер из .fx файла без контент менеджера?

2. Как создать экземпляр контент менеджера без класса Game (в простом WindowsForms проекте), если есть только GraphicsDevice?
0
brony
77 / 57 / 4
Регистрация: 02.01.2012
Сообщений: 521
02.08.2012, 17:58 39
Мне кажется было бы легче к xna game проекту подключить формы стандартного окна чем наоборот
0
6 / 6 / 0
Регистрация: 01.08.2011
Сообщений: 133
02.08.2012, 18:06 40
Не в данном случае. Нужно именно без Game.
0
02.08.2012, 18:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.08.2012, 18:06
Помогаю со студенческими работами здесь

Подскажите совет как разобраться с загрузкой разного контента
Имеется пункты меню &lt;MenuItem Header=&quot;База данных&quot;&gt; &lt;MenuItem Header=&quot;База...

Оптимизация и доработка выпадающего меню с загрузкой, посредством Ajax, контента
Всем добра. Делаю меню для сайта, вот сам код. &lt;ul class=&quot;sub-catalog&quot;&gt; &lt;li&gt; &lt;a...

Проблемы с загрузкой
Здравствуйте. У меня есть такая проблема. Я установил Windows 8, перезагрузил, и тут же у меня...

Проблемы с загрузкой HDD
Ребутнул ноут на днях, теперь не грузит систему с диска. БИОС определяет веник все как надо быть,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru