簡體   English   中英

將 OpenGL 到 Vulkan 的 UV 坐標歸一化

[英]Normalizing UV Coordinates From OpenGL To Vulkan

我正在為GWEN(沒有奢侈廢話的 GUI)編寫 Vulkan 渲染器,並且在獲取紋理坐標以匹配時遇到問題。

這是我應該看到的: 正確輸出

這就是目前正在發生的事情: 輸出不正確

中心顯示的紋理是我們用於 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);
}

該庫構建一個頂點向量,然后最終每幀渲染頂點緩沖區。

作為參考,這里是來自 OpenGL 示例渲染器的相同 function:

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 坐標的原因。 可悲的是,我仍然得到不正確的 output。 我已經為texCoord.xtexCoord.y嘗試了很多組合,但我永遠無法得到正確的 output。 有誰知道我在這里可能做錯了什么?

編輯將紋理除以 128 而不是 512 產生了正確的結果。 我不明白為什么這解決了我的問題。 紋理大小確實是 512x512 單位,所以除以 512 應該給我一個 0.0-1.0 的范圍? 相反,我只除以紋理大小的 1/4 的 128 來得到我的 0.0-1.0 范圍?

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

事實證明,當涉及到 UV 坐標時,Vulkan 和 OpenGL 共享相同的物理0,0 position。 翻轉y值是不必要的。 最后給我正確的 output 是將紋理的大小除以1/4th128而不是512 由於某種原因,這產生了正確的 output 並且所有 UV 都正確排列。

正確的公式:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM