使用立方体创建一个新的场景,在其上添加嵌入纹理,将场景导出到glb 2。输出文件(test_1.glb)有一个破碎的纹理,纹理-〉mheight = 0,格式为null
。image texture file output.jpg纹理来自JPEG文件(“output.jpg”),宽度为200像素,高度为300像素。
// Create fresh secen
aiScene *scene_1 = new aiScene;
scene_1->mRootNode = new aiNode();
// add 2 materials
scene_1->mMaterials = new aiMaterial*[ 2 ];
scene_1->mMaterials[ 0 ] = nullptr;
scene_1->mMaterials[ 1 ] = nullptr;
scene_1->mNumMaterials = 2;
scene_1->mMaterials[ 0 ] = new aiMaterial();
scene_1->mMaterials[ 1 ] = new aiMaterial();
// add 2 textures
scene_1->mTextures = new aiTexture*[ 2 ];
scene_1->mTextures[ 0 ] = nullptr;
scene_1->mTextures[ 1 ] = nullptr;
scene_1->mNumTextures = 2;
scene_1->mTextures[ 0 ] = new aiTexture();
scene_1->mTextures[ 1 ] = new aiTexture();
scene_1->mMeshes = new aiMesh*[ 1 ];
scene_1->mMeshes[ 0 ] = nullptr;
scene_1->mNumMeshes = 1;
scene_1->mMeshes[ 0 ] = new aiMesh();
scene_1->mMeshes[ 0 ]->mMaterialIndex = 1;
scene_1->mRootNode->mMeshes = new unsigned int[ 1 ];
scene_1->mRootNode->mMeshes[ 0 ] = 0;
scene_1->mRootNode->mNumMeshes = 1;
auto pMesh = scene_1->mMeshes[ 0 ];
pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> uvs;
//Default Fill Location Vector
int draw_order[36] =
{
0,2,1, 2,3,1,
1,3,5, 3,7,5,
5,7,4, 7,6,4,
4,6,0, 6,2,0,
4,0,5, 0,1,5,
2,6,3, 6,7,3
};
glm::vec3 data[8] =
{
glm::vec3(-1.0f/2.0f,1.0f/2.0f,1.0f/2.0f),
glm::vec3(1.0f/2.0f,1.0f/2.0f,1.0f/2.0f),
glm::vec3(-1.0f/2.0f,-1.0f/2.0f,1.0f/2.0f),
glm::vec3(1.0f/2.0f,-1.0f/2.0f,1.0f/2.0f),
glm::vec3(-1.0f/2.0f,1.0f/2.0f,-1.0f/2.0f),
glm::vec3(1.0f/2.0f,1.0f/2.0f,-1.0f/2.0f),
glm::vec3(-1.0f/2.0f,-1.0f/2.0f,-1.0f/2.0f),
glm::vec3(1.0f/2.0f,-1.0f/2.0f,-1.0f/2.0f)
};
for(int i = 0; i < 36; i++)
{
vertices.push_back(data[draw_order[i]]);
}
//Default Fill Normal Vector
for(int i = 0; i < 36; i++)
{
if(i < 6) {normals.push_back(glm::vec3(0,0,1));}
else if(i < 12) {normals.push_back(glm::vec3(1,0,0));}
else if(i < 18) {normals.push_back(glm::vec3(0,0,-1));}
else if(i < 24) {normals.push_back(glm::vec3(-1,0,0));}
else if(i < 30) {normals.push_back(glm::vec3(0,1,0));}
else if(i < 36) {normals.push_back(glm::vec3(0,- 1,0));}
}
//Default Fill UV Vector
for(int i = 0; i < 6; i++)
{
uvs.push_back(glm::vec2(0,1));
uvs.push_back(glm::vec2(0,0));
uvs.push_back(glm::vec2(1,1));
uvs.push_back(glm::vec2(0,0));
uvs.push_back(glm::vec2(1,0));
uvs.push_back(glm::vec2(1,1));
}
const auto& vVertices = vertices;
pMesh->mVertices = new aiVector3D[ vVertices.size() ];
pMesh->mNormals = new aiVector3D[ vVertices.size() ];
pMesh->mNumVertices = vVertices.size();
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ vVertices.size() ];
pMesh->mNumUVComponents[ 0 ] = vVertices.size();
int j = 0;
for ( auto itr = vVertices.begin(); itr != vVertices.end(); ++itr )
{
pMesh->mVertices[ itr - vVertices.begin() ] = aiVector3D( vVertices[j].x, vVertices[j].y, vVertices[j].z );
pMesh->mNormals[ itr - vVertices.begin() ] = aiVector3D( normals[j].x, normals[j].y, normals[j].z );
pMesh->mTextureCoords[0][ itr - vVertices.begin() ] = aiVector3D( uvs[j].x, uvs[j].y, 0 );
j++;
}
pMesh->mFaces = new aiFace[ vVertices.size() / 3 ];
pMesh->mNumFaces = (unsigned int)(vVertices.size() / 3);
int k = 0;
// create all faces
for(int i = 0; i < (vVertices.size() / 3); i++)
{
aiFace &face = pMesh->mFaces[i];
face.mIndices = new unsigned int[3];
face.mNumIndices = 3;
face.mIndices[0] = k;
face.mIndices[1] = k+1;
face.mIndices[2] = k+2;
k = k + 3;
}
if(pMesh->HasTextureCoords(0)){
// read data from JPEG file using libjpeg
std::string filename = "output.jpg";
const char* file_to_open = &filename[0];
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
if ((outfile = fopen(file_to_open, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", file_to_open);
}
jpeg_stdio_src(&cinfo, outfile);
jpeg_read_header(&cinfo, TRUE); // read jpeg file header
jpeg_start_decompress(&cinfo); // decompress the file
int img_width = cinfo.output_width;
int img_height = cinfo.output_height;
int channels = cinfo.num_components;
std::vector<int> color_data;
unsigned long data_size = img_width * img_height * channels;
unsigned char * rowptr[1]; // pointer to an row array
unsigned char * jdata; // pixel data of image
jdata = (unsigned char *)malloc(data_size);
while (cinfo.output_scanline < cinfo.image_height) {
rowptr[0] = (unsigned char *)jdata + 3* cinfo.image_width * cinfo.output_scanline;
jpeg_read_scanlines(&cinfo, rowptr, 1);
}
// embed texture from the image
auto texture_1 = scene_1->mTextures[ 0 ];
texture_1->mWidth = img_width;
texture_1->mHeight = img_height;
// specify format hint
texture_1->achFormatHint[0] = 'r';
texture_1->achFormatHint[1] = 'g';
texture_1->achFormatHint[2] = 'b';
texture_1->achFormatHint[3] = 'a';
texture_1->achFormatHint[4] = '8';
texture_1->achFormatHint[5] = '8';
texture_1->achFormatHint[6] = '8';
texture_1->achFormatHint[7] = '0';
aiTexel *temp_1 = new aiTexel [img_width*img_height];
unsigned int count_1 = 0;
for(int j = 0; j < img_height; j++){
for(int k = 0; k < img_width; k++){
temp_1[count_1].r = jdata[count_1*3 + 0];
temp_1[count_1].g = jdata[count_1*3 + 1];
temp_1[count_1].b = jdata[count_1*3 + 2];
count_1++;
}
}
texture_1->pcData = temp_1;
auto temp_material = scene_1->mMaterials[ 1 ];
aiColor3D color_red(0.6f,0.1f,0.1f);
int two_sided = 1;
int uv_mapping = 0;
aiString mat_1("mat_1");
temp_material->AddProperty(&mat_1, AI_MATKEY_NAME);
temp_material->AddProperty<aiColor3D>(&color_red,1, AI_MATKEY_COLOR_DIFFUSE);
temp_material->AddProperty<int>(&two_sided,1,AI_MATKEY_TWOSIDED);
temp_material->AddProperty<int>(&uv_mapping,1,AI_MATKEY_MAPPING(aiTextureMapping_UV,0));
temp_material->AddProperty<int>(&uv_mapping,1,AI_MATKEY_TEXFLAGS(aiTextureFlags_IgnoreAlpha,0)); // TEXFLAGS
temp_material->AddProperty<int>(&uv_mapping,1,AI_MATKEY_MAPPINGMODE_U(aiTextureMapMode_Wrap,0)); // MAPPINGMODE_U
temp_material->AddProperty<int>(&uv_mapping,1,AI_MATKEY_MAPPINGMODE_V(aiTextureMapMode_Wrap,0)); // MAPPINGMODE_V
temp_material->AddProperty<int>(&uv_mapping,1,AI_MATKEY_TEXOP(aiTextureOp_Add,0)); // TEXOP
aiString dummy_tex("*0");
// add texture "0" (index of the texture in scene_1->mTextures) to the materail "1" (index of the material in scene_1->mMaterials)
temp_material->AddProperty(&dummy_tex, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,0));
}
char* mFilePath = " ";
// create exporter
Assimp::Exporter exporter;
mFilePath = "test_1.glb";
exporter.Export(scene_1, "glb2", mFilePath, aiProcess_Triangulate);
1条答案
按热度按时间r7knjye21#
您可能已经知道了,但如果嵌入/导出的纹理高度为0,则宽度为贴图的大小,并且数据存储为压缩文件格式(如PNG)。