2013-07-05 219 views
7

我有OpenGL程序,我想用地球的位圖紋理球體。我在Blender中準備網格並將其導出到OBJ文件。程序正確地加載適當的網格數據(頂點,UV和法線)和位圖 - 我已經用骨位圖檢查了紋理立方體。OpenGL將紋理映射到球體

我的程序是紋理領域,但不正確(或以我不期望的方式)。此球體的每個三角形都包含此位圖的變形副本。我檢查過位圖和uv似乎沒問題。我已經嘗試了許多尺寸的位圖(2的倍數,2的倍數等)。

這裏的質地:

Earth texture

我的程序的截圖(像它會忽略我的UV COORDS):

enter image description here

在攪拌機UV的映射我在做這樣:

enter image description here

代碼(從代碼中除了添加紋理VBO-我認爲這是確定)加載它之後設置的質地:

GLuint texID; 
    glGenTextures(1,&texID); 
    glBindTexture(GL_TEXTURE_2D,texID); 
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_BGR,GL_UNSIGNED_BYTE,(GLvoid*)&data[0]); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); 

是否有所需的任何額外的代碼來此紋理正確映射?

[編輯] 初始化紋理(前面給出的代碼是在LoadTextureBMP_custom()函數)

bool Program::InitTextures(string texturePath) 
{ 
    textureID = LoadTextureBMP_custom(texturePath); 
    GLuint TBO_ID; 
    glGenBuffers(1,&TBO_ID); 
    glBindBuffer(GL_ARRAY_BUFFER,TBO_ID); 
    glBufferData(GL_ARRAY_BUFFER,uv.size()*sizeof(vec2),&uv[0],GL_STATIC_DRAW); 
    return true; 
} 

我的主循環:

bool Program::MainLoop() 
{ 
    bool done = false; 
    mat4 projectionMatrix; 
    mat4 viewMatrix; 
    mat4 modelMatrix; 
    mat4 MVP; 

    Camera camera; 
    shader.SetShader(true); 

    while(!done) 
    { 
    if((glfwGetKey(GLFW_KEY_ESC))) 
     done = true; 
    if(!glfwGetWindowParam(GLFW_OPENED)) 
     done = true; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Tutaj przeksztalcenia macierzy 
    camera.UpdateCamera(); 
    modelMatrix = mat4(1.0f); 
    viewMatrix = camera.GetViewMatrix(); 
    projectionMatrix = camera.GetProjectionMatrix(); 
    MVP = projectionMatrix*viewMatrix*modelMatrix; 
    // Koniec przeksztalcen 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D,textureID); 

    shader.SetShaderParameters(MVP); 

    SetOpenGLScene(width,height); 

    glEnableVertexAttribArray(0); // Udostepnienie zmiennej Vertex Shadera => vertexPosition_modelspace 
    glBindBuffer(GL_ARRAY_BUFFER,VBO_ID); 
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0); 

    glEnableVertexAttribArray(1); 
    glBindBuffer(GL_ARRAY_BUFFER,TBO_ID); 
    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void*)0); 

    glDrawArrays(GL_TRIANGLES,0,vert.size()); 

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 

    glfwSwapBuffers(); 
    } 
    shader.SetShader(false); 

    return true; 
} 

VS:

#version 330 

layout(location = 0) in vec3 vertexPosition; 
layout(location = 1) in vec2 vertexUV; 
out vec2 UV; 

uniform mat4 MVP; 

void main() 
{ 
    vec4 v = vec4(vertexPosition,1.0f); 
    gl_Position = MVP*v; 
    UV = vertexUV; 
} 

FS:

#version 330 

in vec2 UV; 
out vec4 color; 

uniform sampler2D texSampler; // Uchwyt tekstury 

void main() 
{ 
    color = texture(texSampler, UV); 
} 
+3

這看起來像一個UV映射問題。你確定模型中的UV座標是否正確?也就是說,在Blender中它看起來不錯嗎? – manabreak

+2

什麼是你的UV值的範圍? – Alnitak

+1

p.s.該紋理不適合在球體上繪圖。你需要一個已經被拉伸成圓柱形的地圖,就像這個 - http://paulbourke.net/geometry/transformationprojection/earth.jpg – Alnitak

回答

1

最後,我已經得到了答案。錯誤在那裏:

bool Program::InitTextures(string texturePath) 
{ 
    textureID = LoadTextureBMP_custom(texturePath); 
    // GLuint TBO_ID; _ERROR_ 
    glGenBuffers(1,&TBO_ID); 
    glBindBuffer(GL_ARRAY_BUFFER,TBO_ID); 
    glBufferData(GL_ARRAY_BUFFER,uv.size()*sizeof(vec2),&uv[0],GL_STATIC_DRAW); 
} 

在節目類聲明的一部分:

class Program 
{ 
private: 
    Shader shader; 
    GLuint textureID; 

    GLuint VAO_ID; 
    GLuint VBO_ID; 
    GLuint TBO_ID; // Member covered with local variable declaration in InitTextures() 
    ... 
} 

我錯誤地宣稱本地TBO_ID涵蓋TBO_ID類範圍。紫外線產生的精確度很差,接縫也很糟糕,但它們不是問題。

enter image description here

我不得不承認,我提供的信息是太小,無法實現幫助。我應該把所有的代碼程序類。感謝所有嘗試過的人。

1

我還沒有做過任何專業的GL編程,但我一直在使用3D軟件相當多。

  • 您的UV是最容易壞
  • 你的紋理是一個糟糕的配合投射在球體上
  • 考慮的UV是壞的,你可能要檢查你的法線以及
  • 考慮的等球面代替經常一個以更有效地利用多邊形

您當前使用的是扁平紋理映射持平,這可能會給你非常難看的結果,因爲你將在「外」 PE非常低的分辨率如果你喜歡這兩個投影相遇的話,最有可能是一個討厭的接縫神器......旋轉這個星球或者其他東西。

請注意,您不必具有任何特定的UV貼圖,只需要正確使用幾何圖形即可,它看起來不像現在。球形貼圖會照顧其餘部分。由於大多數地球紋理都處於合適的投影中,因此也可以使用圓柱形地圖。

+0

我已經用其他模型測試了我的程序,它以相同的方式工作,將紋理的一個實例映射到模型的每個三角形。感謝您提供明確的建議。 – CppMonster

+0

@CppMonster - 看起來您沒有紫外線,例如所有的紫外線都會佔據整個空間,並且在彼此頂部重疊,而不是按照他們需要的平坦網格對齊。你自己提供UV座標嗎?也許你沒有提供,你看到的是默認行爲,例如每張臉都會填滿整個紋理空間。 – dtech

+0

我下載了簡單的.obj模型(帶有uvs)並試用了它們。它是一樣的,一張臉的質地(三角形)。有些東西一定是錯誤的代碼,也許... – CppMonster