Flipped texture coordinates
Nazara now use a top-left corner origin for UVs (DirectX-like) Former-commit-id: 550dd76cf15bc731d1e23060d1af15c3cd5cb4fd
This commit is contained in:
parent
9b1f63ce11
commit
98aa804de5
|
|
@ -95,6 +95,10 @@ int main()
|
|||
// Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle.
|
||||
params.mesh.scale.Set(0.01f); // Un centième de la taille originelle
|
||||
|
||||
// Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend
|
||||
// Nous devons dire au moteur de les retourner lors du chargement
|
||||
params.mesh.flipUVs = true;
|
||||
|
||||
// On charge ensuite le modèle depuis son fichier
|
||||
// Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...)
|
||||
if (!spaceship.LoadFromFile("resources/Spaceship/spaceship.obj", params))
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ struct NAZARA_API NzMeshParams
|
|||
// Faut-il centrer le mesh autour de l'origine ?
|
||||
bool center = false;
|
||||
|
||||
// Faut-il retourner les UV ?
|
||||
bool flipUVs = false;
|
||||
|
||||
// Faut-il optimiser les index buffers ? (Rendu plus rapide, mais le chargement dure plus longtemps)
|
||||
bool optimizeIndexBuffers = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ namespace
|
|||
if (index >= 0)
|
||||
{
|
||||
const NzVector3f& uvw = texCoords[index];
|
||||
vertex.uv.Set(uvw.x, uvw.y);
|
||||
vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
|
||||
}
|
||||
else
|
||||
hasTexCoords = false;
|
||||
|
|
|
|||
|
|
@ -1048,33 +1048,25 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s
|
|||
return false;
|
||||
}
|
||||
|
||||
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format);
|
||||
|
||||
unsigned int size = box.width*box.height*box.depth*bpp;
|
||||
std::unique_ptr<nzUInt8[]> flipped(new nzUInt8[size]);
|
||||
NzImage::Copy(flipped.get(), pixels, bpp, box.width, box.height, box.depth, 0, 0, srcWidth, srcHeight);
|
||||
|
||||
// Inversion de la texture pour le repère d'OpenGL
|
||||
if (!NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_impl->format, box.width, box.height, box.depth, flipped.get(), flipped.get()))
|
||||
NazaraWarning("Failed to flip image");
|
||||
|
||||
SetUnpackAlignement(bpp);
|
||||
SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format));
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth);
|
||||
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight);
|
||||
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
switch (m_impl->type)
|
||||
{
|
||||
case nzImageType_1D:
|
||||
glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, flipped.get());
|
||||
glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, pixels);
|
||||
break;
|
||||
|
||||
case nzImageType_1D_Array:
|
||||
case nzImageType_2D:
|
||||
glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, flipped.get());
|
||||
glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels);
|
||||
break;
|
||||
|
||||
case nzImageType_2D_Array:
|
||||
case nzImageType_3D:
|
||||
glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, flipped.get());
|
||||
glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels);
|
||||
break;
|
||||
|
||||
case nzImageType_Cubemap:
|
||||
|
|
@ -1192,20 +1184,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
|
|||
return false;
|
||||
}
|
||||
|
||||
nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format);
|
||||
|
||||
// Inversion de la texture pour le repère d'OpenGL
|
||||
unsigned int size = rect.width*rect.height*bpp;
|
||||
std::unique_ptr<nzUInt8[]> flipped(new nzUInt8[size]);
|
||||
NzImage::Copy(flipped.get(), pixels, bpp, rect.width, rect.height, 1, 0, 0, srcWidth, srcHeight);
|
||||
|
||||
if (!NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_impl->format, rect.width, rect.height, 1, flipped.get(), flipped.get()))
|
||||
NazaraWarning("Failed to flip image");
|
||||
|
||||
SetUnpackAlignement(bpp);
|
||||
SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format));
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth);
|
||||
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight);
|
||||
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, flipped.get());
|
||||
glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, pixels);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,10 @@ namespace
|
|||
{
|
||||
const unsigned int fixedIndex = indexFix[j];
|
||||
const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]];
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(static_cast<float>(texC.u) / header.skinwidth, 1.f - static_cast<float>(texC.v)/header.skinheight);
|
||||
float u = static_cast<float>(texC.u) / header.skinwidth;
|
||||
float v = static_cast<float>(texC.v) / header.skinheight;
|
||||
|
||||
vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -178,10 +178,7 @@ namespace
|
|||
}
|
||||
|
||||
vertices->position = finalPos;
|
||||
|
||||
// Le format MD5 spécifie ses UV avec l'origine en bas à gauche, contrairement au moteur
|
||||
// dont l'origine est en haut à gauche, nous inversons donc la valeur en Y.
|
||||
vertices->uv.Set(vertex.uv.x, 1.f - vertex.uv.y);
|
||||
vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé
|
||||
vertices++;
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +268,7 @@ namespace
|
|||
|
||||
// On retourne le modèle dans le bon sens
|
||||
vertex->position = scale * (rotationQuat * finalPos);
|
||||
vertex->uv.Set(md5Vertex.uv.x, 1.f - md5Vertex.uv.y);
|
||||
vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé
|
||||
vertex++;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue