我有一个使用assimp库从obj文件加载的场景。我按照教程进行操作。它的工作原理,但纹理与原始颜色相比有不同的颜色,它们似乎都在顶部翻转。图像都是tga(我也想摆脱所有的别名)
这是结果
窗帘应该是红色的
我使用freeImage
以这种方式加载纹理bool Texture::Load(){
FIBITMAP* bitmap = FreeImage_Load(
FreeImage_GetFileType(m_fileName.c_str(), 0),
m_fileName.c_str());
FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap);
int nWidth = FreeImage_GetWidth(pImage);
int nHeight = FreeImage_GetHeight(pImage);
glGenTextures(1, &m_textureObj);
glBindTexture(m_textureTarget, m_textureObj);
glTexImage2D(m_textureTarget, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));
glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
FreeImage_Unload(pImage);
return true;
}
使用assimp加载场景并以这种方式处理
void Mesh::InitMesh(const aiMesh* paiMesh,
vector<Vector3f>& Positions,
vector<Vector3f>& Normals,
vector<Vector2f>& TexCoords,
vector<unsigned int>& Indices){
const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);
aiMatrix4x4 Scale(0.3f, 0.0f, 0.0f, 0.0f,
0.0f, 0.3f, 0.0f, 0.0f,
0.0f, 0.0f, 0.3f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
// Populate the vertex attribute vectors
for (unsigned int i = 0; i < paiMesh->mNumVertices; i++) {
if (paiMesh->mVertices[i].x < lowX) lowX = paiMesh->mVertices[i].x;
if (paiMesh->mVertices[i].x > highX) highX = paiMesh->mVertices[i].x;
if (paiMesh->mVertices[i].y < lowY) lowY = paiMesh->mVertices[i].y;
if (paiMesh->mVertices[i].y > highY) highY = paiMesh->mVertices[i].y;
if (paiMesh->mVertices[i].z < lowZ) lowZ = paiMesh->mVertices[i].z;
if (paiMesh->mVertices[i].z > highZ) highZ = paiMesh->mVertices[i].z;
//paiMesh->mVertices[i] = Scale*paiMesh->mVertices[i];
const aiVector3D* pPos = &(paiMesh->mVertices[i]);
const aiVector3D* pNormal = &(paiMesh->mNormals[i]);
const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D;
Positions.push_back(Vector3f(pPos->x, pPos->y, pPos->z));
Normals.push_back(Vector3f(pNormal->x, pNormal->y, pNormal->z));
TexCoords.push_back(Vector2f(pTexCoord->x, pTexCoord->y));
}
bbox[0] = Vector3f(abs(lowX), abs(lowY), abs(lowZ));
bbox[1] = Vector3f(abs(highX), abs(highY), abs(highZ));
// Populate the index buffer
for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) {
const aiFace& Face = paiMesh->mFaces[i];
assert(Face.mNumIndices == 3);
Indices.push_back(Face.mIndices[0]);
Indices.push_back(Face.mIndices[1]);
Indices.push_back(Face.mIndices[2]);
}
}
这就是我初始化纹理的方法
bool Mesh::InitMaterials(const aiScene* pScene, const string& Filename){
// Extract the directory part from the file name
string::size_type SlashIndex = Filename.find_last_of("/");
string Dir;
if (SlashIndex == string::npos) {
Dir = ".";
}
else if (SlashIndex == 0) {
Dir = "/";
}
else {
Dir = Filename.substr(0, SlashIndex);
}
bool Ret = true;
// Initialize the materials
for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
const aiMaterial* pMaterial = pScene->mMaterials[i];
m_Textures[i] = NULL;
if (true || pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
aiString Path;
if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
string FullPath = Dir + "/" + Path.data;
m_Textures[i] = new Texture(GL_TEXTURE_2D, FullPath.c_str());
if (!m_Textures[i]->Load()) {
printf("Error loading texture '%s'\n", FullPath.c_str());
delete m_Textures[i];
m_Textures[i] = NULL;
Ret = false;
}
else {
printf("%d - loaded texture '%s'\n", i, FullPath.c_str());
}
}
}
}
return Ret;
}
最后,我以这种方式呈现所有内容
void Mesh::Render()
{
glBindVertexArray(m_VAO);
glActiveTexture(GL_TEXTURE0);
GLenum oldObj = 0;
if (m_Textures[m_Entries[0].MaterialIndex]){
m_Textures[m_Entries[0].MaterialIndex]->Bind(GL_TEXTURE0);
oldObj = m_Textures[m_Entries[0].MaterialIndex]->m_textureObj;
}
vector<GLsizei> numIdx;
vector<GLint> baseVc;
vector<void*> idx;
unsigned int drawCount = 0;
for (unsigned int i = 0; i < m_Entries.size(); i++) {
const unsigned int MaterialIndex = m_Entries[i].MaterialIndex;
assert(MaterialIndex < m_Textures.size());
drawCount++;
numIdx.push_back(m_Entries[i].NumIndices);
baseVc.push_back(m_Entries[i].BaseVertex);
idx.push_back((void*)(sizeof(unsigned int) * m_Entries[i].BaseIndex));
if (i == m_Entries.size() - 1){
glDrawElementsBaseVertex(GL_TRIANGLES,
m_Entries[i].NumIndices,
GL_UNSIGNED_INT,
(void*)(sizeof(unsigned int) * m_Entries[i].BaseIndex),
m_Entries[i].BaseVertex);
}else
if (m_Textures[m_Entries[i + 1].MaterialIndex] && m_Textures[m_Entries[i+1].MaterialIndex]->m_textureObj != oldObj) {
glMultiDrawElementsBaseVertex(GL_TRIANGLES,
&numIdx[0],
GL_UNSIGNED_INT,
&idx[0],
drawCount,
&baseVc[0]);
numIdx.clear();
baseVc.clear();
idx.clear();
m_Textures[m_Entries[i + 1].MaterialIndex]->Bind(GL_TEXTURE0);
oldObj = m_Textures[m_Entries[i + 1].MaterialIndex]->m_textureObj;
drawCount = 0;
}else if (!m_Textures[m_Entries[i].MaterialIndex]){
glMultiDrawElementsBaseVertex(GL_TRIANGLES,
&numIdx[0],
GL_UNSIGNED_INT,
&idx[0],
drawCount,
&baseVc[0]);
}
}
// Make sure the VAO is not changed from the outside
glBindVertexArray(0);
}
对于大量代码感到抱歉,但由于我不知道错误在哪里发布了整个内容。所有评论
答案 0 :(得分:1)
在尝试减小纹理的大小时,我遇到了这样的问题,我把RGBA置于错误的位置。您确实使用了位图纹理,这意味着它们不存储Alpha通道,尝试将它们置于GL_RGB模式(您将在GL_RGBA中发送它们)。
答案 1 :(得分:0)
所以事实证明我必须删除flippedUV并且我必须使用RGBA作为内部格式而BGRA用于其他格式