gpt4 book ai didi

c++ - 将 UV 坐标从 OpenGL 标准化为 Vulkan

转载 作者:行者123 更新时间:2023-12-02 17:31:54 25 4
gpt4 key购买 nike

我正在为 GWEN (GUI Without Extravagant Nonsense) 编写 Vulkan 渲染器并且在获取纹理坐标匹配时遇到问题。

这是我应该看到的: Correct Output

这就是当前正在发生的事情: Incorrect Output

中心显示的纹理是我们用于 GUI 的图像,我确保测试将其渲染到四边形以确保正确加载它。

GUI 的结构似乎是正确的,这使我相信 UV 坐标不正确。特别是 Y 坐标,因为据我所知,X 看起来没问题。

void Vulkan::AddVert(int x, int y, float u, float v)
{
vertices.emplace_back();

vertices.back().pos.x = ((float)x / 400) - 1.f;
vertices.back().pos.y = ((float)y / 300) - 1.f;
// Our image is 512x512 px
vertices.back().texCoord.x = (u / 512.0f);
vertices.back().texCoord.y = 1.0f - (v / 512.0f);
}

void Vulkan::DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect rect, float u1, float v1, float u2, float v2)
{
// ToDo: Implement textures through GWEN
// The GUI texture is hardcoded for now
// Once we're rendering properly i'll expand this function to handle textures
Translate(rect);

AddVert(rect.x, rect.y, u1, v1);
AddVert(rect.x + rect.w, rect.y, u2, v1);
AddVert(rect.x, rect.y + rect.h, u1, v2);
AddVert(rect.x + rect.w, rect.y, u2, v1);
AddVert(rect.x + rect.w, rect.y + rect.h, u2, v2);
AddVert(rect.x, rect.y + rect.h, u1, v2);
}

该库构建一个顶点 vector ,然后最终渲染每帧的顶点缓冲区。

作为引用,这里是 OpenGL 示例渲染器中的相同函数:

void OpenGL::AddVert( int x, int y, float u, float v )
{
m_Vertices[ m_iVertNum ].x = ( float ) x;
m_Vertices[ m_iVertNum ].y = ( float ) y;
m_Vertices[ m_iVertNum ].u = u;
m_Vertices[ m_iVertNum ].v = v;
m_Vertices[ m_iVertNum ].r = m_Color.r;
m_Vertices[ m_iVertNum ].g = m_Color.g;
m_Vertices[ m_iVertNum ].b = m_Color.b;
m_Vertices[ m_iVertNum ].a = m_Color.a;
m_iVertNum++;
}

void OpenGL::DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect rect, float u1, float v1, float u2, float v2)
{
GLuint* tex = ( GLuint* ) pTexture->data;

// Missing image, not loaded properly?
if ( !tex )
{
return DrawMissingImage( rect );
}

Translate(rect);
GLuint boundtex;
GLboolean texturesOn;
glGetBooleanv( GL_TEXTURE_2D, &texturesOn );
glGetIntegerv( GL_TEXTURE_BINDING_2D, ( GLint* ) &boundtex );

if ( !texturesOn || *tex != boundtex )
{
Flush();
glBindTexture( GL_TEXTURE_2D, *tex );
glEnable( GL_TEXTURE_2D );
}

AddVert(rect.x, rect.y, u1, v1);
AddVert(rect.x + rect.w, rect.y, u2, v1);
AddVert(rect.x, rect.y + rect.h, u1, v2);
AddVert(rect.x + rect.w, rect.y, u2, v1);
AddVert(rect.x + rect.w, rect.y + rect.h, u2, v2);
AddVert(rect.x, rect.y + rect.h, u1, v2);
}

我知道 Vulkan 采用从 0.0 到 1.0 的纹理坐标,这就是为什么我将 uv 除以纹理的大小 512 x 512。我还了解 Vulkan 使用图像的左下角作为 0,0 这就是我翻转 Y 坐标的原因。可悲的是我仍然得到不正确的输出。我已经尝试了 texCoord.x 和 texCoord.y 的多种组合,但我永远无法获得正确的输出。有谁知道我在这里可能做错了什么?

编辑将纹理除以 128 而不是 512 会产生正确的结果。我不明白为什么这解决了我的问题。纹理大小确实是 512x512 单位,所以除以 512 应该给我一个 0.0-1.0 的范围?相反,我只需除以 128(纹理大小的 1/4)即可得到 0.0-1.0 范围?

vertices.back().texCoord.x = (u / 128);
vertices.back().texCoord.y = (v / 128);

最佳答案

事实证明,在 UV 坐标方面,Vulkan 和 OpenGL 共享相同的物理 0,0 位置。翻转 y 值是不必要的。最后,给我正确输出的是将纹理的大小除以 1/4th128 而不是 512。由于某种原因,这产生了正确的输出,并且所有 UV 都正确排列。

正确的公式:

vertices.back().texCoord.x = (u / 128);
vertices.back().texCoord.y = (v / 128);

关于c++ - 将 UV 坐标从 OpenGL 标准化为 Vulkan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58822967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com