OpenGL将纹理映射到球体 [英] OpenGL mapping texture to sphere

查看:352
本文介绍了OpenGL将纹理映射到球体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有OpenGL程序,我想纹理球体与地球的位图。我在Blender中准备了网格,并将其导出到OBJ文件。程序加载适当的网格数据(顶点,uv和法线)和位图正确 - 我已经检查它纹理立方体与骨位图。



我的程序是纹理球,但不正确或在我不期望的方式)。该球的每个三角形包括该位图的变形副本。我已经检查位图和uv似乎是确定。我尝试了许多大小的位图(2的幂,2的倍数等)。



这里是纹理:





我的程序的屏幕截图(像忽略我的UV坐标):



>



Blender中的UVs映射我已经这样做:





代码设置纹理加载后(除了代码添加纹理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;

相机相机;
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);
gIbindBuffer(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:



<$在vec3 vertexPosition中的p $ p> #version 330

布局(位置= 0)
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);
}


解决方案

答案。错误是:

  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; //在InitTextures()中用局部变量声明覆盖的成员
...
}

我错误地在类范围中声明了覆盖 TBO_ID 的本地 TBO_ID





我不得不承认,我提供的信息太小,无法启用帮助。我应该把计划类的所有代码。感谢所有尝试过的人。


I have OpenGL program that I want to texture sphere with bitmap of earth. I prepared mesh in Blender and exported it to OBJ file. Program loads appropriate mesh data (vertices, uv and normals) and bitmap properly- I have checked it texturing cube with bone bitmap.

My program is texturing sphere, but incorrectly (or in the way I don't expect). Each triangle of this sphere includes deformed copy of this bitmap. I've checked bitmap and uv seems to be ok. I've tried many sizes of bitmap (powers of 2, multiples of 2 etc).

Here's the texture:

Screenshot of my program (like It would ignore my UV coords):

Mappings of UVs in Blender I've done in this way:

Code setting texture after loading it (apart from code adding texture to VBO- I think it's ok):

  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);

Is there needed any extra code to map this texture properly?

[Edit] Initializing textures (earlier presented code is in LoadTextureBMP_custom() function)

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;
}

My main loop:

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);
}

解决方案

Finally, I've got the answer. Error was there:

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);
}

There is the part of Program class declaration:

class Program
{
 private:
  Shader shader;
  GLuint textureID;

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

I've erroneously declared local TBO_ID that covered TBO_ID in class scope. UVs were generated with crummy precision and seams are horrible, but they weren't problem.

I have to admit that information I've supplied is too small to enable help. I should have put all the code of Program class. Thanks everybody who tried to.

这篇关于OpenGL将纹理映射到球体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆