Assimp не импортирует текстуры

Я использую Assimp для импорта 3D-моделей в моем игровом движке. По какой-то причине, независимо от того, какую модель или формат модели я использую, assimp не сообщает о каких-либо текстурах. Почему это?

Ниже приведена очень простая установка с assimp:

const aiScene* scene = importer.ReadFile(asset, aiProcessPreset_TargetRealtime_Quality);

if (scene->HasMaterials())
{
for (unsigned int i = 0; i < scene->mNumMaterials; i++)
{
const aiMaterial* material = scene->mMaterials[i];
aiString texturePath;

unsigned int numTextures= material->GetTextureCount(aiTextureType_DIFFUSE);   // always 0

if (material->GetTextureCount(aiTextureType_DIFFUSE) > 0 && material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath) == AI_SUCCESS)
{
// never happens..
// scene->mNumTextures is always 0 aswell.
}
}
}

Я использую различные модели, которые, как я уверен, имеют текстуры, например, модели из учебных пособий, которые разработаны по очень конкретной причине загрузки текстурированных моделей с использованием Assimp. (например, http://www.lighthouse3d.com/cg-topics/code-samples/importing-3d-models-with-assimp)

Что может быть причиной этого?

2

Решение

Я знаю, что это довольно старая проблема, но у меня была именно эта проблема последние пару дней, и мне удалось ее решить, так что вот решение для тех, кто ищет.

Есть две возможные причины, по которым ваши текстуры не загружаются:

  1. Текстуры встроены.

или же

  1. Что-то не так с вашим файлом материалов для модели.

Если это случай № 1, то он не работает просто потому, что GetTexture и GetTextureCount не применяются к встроенным материалам. Вложенные материалы, как правило, просто простые цвета. Если вы хотите узнать, как импортировать внедренные материалы, взгляните на примеры кодов ASSIMP или исходный код AssimpView.

Скорее всего, ваша проблема в случае № 2: что-то не так с вашим файлом материалов. Например, файлы модели .OBJ поставляются с соответствующим файлом .MTL, если они текстурированные. Если файл .MTL отсутствует, текстуры не будут загружаться. Если с файлом .MTL что-то не так, текстуры также не будут загружаться.

Итак, убедитесь, что все ваши файлы .mtl есть и любые другие файлы материалов (включая изображения для самих текстур). Если они есть, то следующее, что вам нужно сделать, это открыть модель с помощью инструмента AssimpView. Убедитесь, что модель загружается правильно со всеми своими текстурами. Если это не так, либо что-то не так с файлом материалов (решение ниже), либо что-то не так с файлом модели, и Assimp просто не может его загрузить (или что-то в корне не так с Assimp). Если он загружается правильно, вы должны увидеть названия диффузных текстур в правой части AssimpView.

Итак, если все это проверено и импортер Assimp в вашей программе все еще не распознает текстуры из вашей модели (даже если AssimpView это делает), то следующее, что вы хотите сделать, — это на самом деле открыть файл .MTL с помощью чего-то вроде блокнота. Вы увидите что-то вроде этого:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg

Существуют различные вещи, которые могут быть не так с этими файлами. Обратите внимание, что map_Kd определяет файл изображения, который будет использоваться для диффузной текстуры. Иногда вместо того, чтобы указывать правильный путь или просто имя файла, вы увидите полный путь к каталогу относительно компьютера, на котором была сделана модель (то есть он скажет что-то вроде C: / Users / blah blah blah / MoonMap2 …). Вы можете легко исправить это, удалив путь к каталогу и сохранив только имя файла изображения (и сохранив изображение в той же папке, что и модель), или вы можете указать свой собственный путь и поместить туда текстуры.

Другая проблема, с которой вы можете столкнуться, — это то, что переменные перечислены в файле .MTL без фактических значений.

Например:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg
map_Ka

Обратите внимание на «map_Ka» в конце там. Это не имеет ничего рядом с этим. Это не только предотвращает правильное распознавание текстур, но и вообще не позволяет AssimpView загружать модели. Просто удалите все свойства, которые вы видите, когда у них нет значений рядом с ними.

Наконец, если ничего из этого не работает, то вам, возможно, придется просто поэкспериментировать с файлом .MTL — в нем может быть свойство / переменная, которая по какой-то причине вызывает проблемы, поэтому попробуйте удалить строки, в которых вы абсолютно уверены, что вы не используете не нужно (обратите внимание, что Kd представляет диффузную текстуру, Ka будет представлять текстуру окружающей среды, Ks зеркальная и т. д.). Файл .MTL, который я использовал здесь в качестве примера, содержит то, что, как я считаю, является минимальными строками, которые должен иметь файл MTL, чтобы иметь возможность загружать диффузную текстуру.

Надеюсь это поможет. Если ничего из этого не работает, я бы заподозрил, что с вашей библиотекой ASSIMP что-то не так. Если в вашем файле модели нет файла материалов … это ваша проблема.

10

Другие решения

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

В файле obj есть ссылки на файл материала и название материала в этом файле. Если вы переименовали файл, они не будут совпадать, и материал не будет найден.

В файле obj вы найдете строку, которая выглядит следующим образом

mtllib deer-obj.mtl

Это имя файла материала. Если вы переименовали материал, вы должны переименовать его и здесь.

В этом же файле вы найдете ссылки на названия материалов, определенных в файле материалов, например:

usemtl deer

Это должно соответствовать названиям материалов в файле материалов. В файле MTL я определил это:

newmtl deer

Имена «usemtl» и «newmtl» должны совпадать, чтобы найти материал.

0

Изучение источников assimp показывает, что в импортере OBJ нет mNumTextures ++.
Так что это никогда не даст положительного результата при импорте OBJ-файлов.

Правильный метод загрузки текстур — добавить в конец apply_material () (вы можете получить исходные коды в репозитории assimp на github) следующий код (язык D):

aiString path;
if(aiReturn_SUCCESS == aiGetMaterialTexture(mtl, aiTextureType_DIFFUSE, 0, &path))
{
string p = (cast(const(char)*)(path.data)).to!(string)();

GLuint texture_name;
glGenTextures(1, &texture_name);// generate GL-textures ID's
glBindTexture(GL_TEXTURE_2D, texture_name);// Binding of texture name
//
//redefine standard texture values
//
// We will use linear interpolation for magnification filter
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// tiling mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, true ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, true ? GL_REPEAT : GL_CLAMP);

auto image = IMG_Load(p.toStringz);
if (!image)
{
throw new Exception(format("Error while loading texture: %s", p));
}

// Texture specification
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.w, image.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
image.pixels);
}

И для отображения этой текстуры добавьте в recursive_render () между glColor4fv и glNormal3fv следующую строку:

glTexCoord2f(mesh.mTextureCoords[0][index].x, 1.0-mesh.mTextureCoords[0][index].y);
0