2013-07-05 168 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