0

我目前正在尝试在 OpenGL 中制作一个小游戏,以尝试学习如何使用 API。我已经到了可以在简单场景周围移动相机的地步,我可以渲染模型并使用简单的 phong 模型着色器对它们进行着色。

我现在正在处理场景中的模型纹理,所以我得到了一份 Maya 的副本,并制作了一个带有纹理的正方形(费了很大力气),并在 Maya 中制作了 UV 贴图。

当我渲染场景时,纹理被应用,但远非正确。我使用自己编写的解析器将模型读取为 .obj 文件,并使用我不久前在网上找到的函数读取纹理。

我不确定如何足够详细地描述问题,也不确定在代码中寻找什么,但这里有一些我怀疑包含问题的代码片段。

读取纹理

 GLuint loadTexture(Image* image){
   GLuint textureId;
   glGenTextures(1, &textureId);
   glBindTexture(GL_TEXTURE_2D, textureId);
   glTexImage2D(GL_TEXTURE_2D,
     0,
     GL_RGB,
     image->width, image->height,
     0,
     GL_RGB,
     GL_UNSIGNED_BYTE,
     image->pixels);
   return textureId;
 }

在渲染网格之前设置纹理

// set texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->body_texture);
current_shader->setUniformint(0, "Difuse_texture");

顶点着色器

#version 410

layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 1) in vec2 TextureCoord;



out vec3 Position;
out vec3 Normal;
out vec2 TexCoord;

uniform mat4 ModelMatrix;
uniform mat4 VeiwMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;


void main(){

  mat4 ModelVeiwMatrix = VeiwMatrix * ModelMatrix;
  mat4 MVP = ProjectionMatrix * ModelVeiwMatrix;

  TexCoord = TextureCoord;
  Normal = normalize( NormalMatrix * VertexNormal );
  Position = vec3(ModelVeiwMatrix * vec4(VertexPosition, 1.0));

  gl_Position = MVP * vec4(VertexPosition, 1.0);
}

片段着色器

#version 410

in vec3 Position;
in vec3 Normal;
in vec2 TexCoord;

uniform vec4 LightPosition;
uniform vec3 LightIntensity;
uniform vec3 Kd;
uniform vec3 Ka;
uniform vec3 Ks;
uniform float Shininess;

uniform sampler2D Difuse_texture;

layout(location = 0) out vec4 FragColor;

vec4 ads(){
  vec3 n = normalize( Normal );
  vec3 s = normalize( vec3(LightPosition) - Position );
  vec3 v = normalize( vec3(-Position) );
  vec3 r = reflect( -s, n );

  vec3 specular_light = Ks * pow(max(dot(r, v), 0.0), Shininess);

  vec3 ad_light = Ka + Kd * max(dot(s, n), 0.0);

  vec4 TexColor = texture2D(Difuse_texture, TexCoord);

  return TexColor; // (vec4(LightIntensity, 1.0)  * (vec4(ad_light, 1.0) * TexColor + vec4(specular_light, 1.0)));
}


void main() {
  FragColor = ads();
}

我知道有些东西写得很奇怪,但在这一点上,我开始尝试任何事情来让它工作。

有人对如何解决这个奇怪的 UV 贴图有什么建议吗?

编辑:

对象加载

我已经让 obj 加载器打印所有顶点属性,并将这些属性与 .obj 文件中的索引进行比较。看起来 verecies、法线和 UV 以正确的顺序显示。

截屏

场景看起来像这样,仅使用简单的 reg 到绿色渐变作为纹理图像。

(根据我的理解,正方形应该显示纹理的渐变?不仅仅是一种颜色)

对齐听起来像是一个可能的缺陷,我该如何纠正这个问题?

http://imageshack.com/a/img674/9927/y0bJ51.png

解决方案

我犯了一个非常简单且容易忽略的错误。在我写的顶点着色器的顶部

layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 1) in vec2 TextureCoord;

所以我猜当我将法线数据发送到位置 1 时,我将纹理坐标设置为法线数据,因此 UV 坐标从未到达片段着色器。

更改为以下内容即可解决问题,无需进一步更改。

layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 2) in vec2 TextureCoord;
4

0 回答 0