我一直试图将一个.obj文件加载到我的OpenGl应用程序中,我认为它最终完成了它,但仔细观察后,该模型似乎已经变成了一个超低多边形版本,或者整个模型都有从里面翻过来,导致脸看起来怪异地凹凸不平,法线/纹理也会产生意想不到的结果。
我不确定这是由装载机还是其他东西引起的,只是为了节省发布文本墙,只是发布加载器代码,如果需要更多代码请告诉我,我会更新我的问题。
bool ObjLoader::loadOBJ(
const char * path,
std::vector<glm::vec3> & out_vertices,
std::vector<glm::vec2> & out_uvs,
std::vector<glm::vec3> & out_normals
)
{
printf("Loading OBJ file %s...\n", path);
std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
std::vector<glm::vec3> temp_vertices;
std::vector<glm::vec2> temp_uvs;
std::vector<glm::vec3> temp_normals;
FILE * file = fopen(path, "r");
if( file == NULL ){
printf("Cant find the file!!\n");
return false;
}
while( 1 ){
char lineHeader[128];
int res = fscanf(file, "%s", lineHeader);
if (res == EOF)
break;
if ( strcmp( lineHeader, "v" ) == 0 ){
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z );
temp_vertices.push_back(vertex);
}else if ( strcmp( lineHeader, "vt" ) == 0 ){
glm::vec2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y );
temp_uvs.push_back(uv);
}else if ( strcmp( lineHeader, "vn" ) == 0 ){
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z );
temp_normals.push_back(normal);
}else if ( strcmp( lineHeader, "f" ) == 0 ){
std::string vertex1, vertex2, vertex3;
unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] );
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices .push_back(uvIndex[0]);
uvIndices .push_back(uvIndex[1]);
uvIndices .push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}else{
char stupidBuffer[1000];
fgets(stupidBuffer, 1000, file);
}
}
for( unsigned int i=0; i<vertexIndices.size(); i++ ){
unsigned int vertexIndex = vertexIndices[i];
unsigned int uvIndex = uvIndices[i];
unsigned int normalIndex = normalIndices[i];
glm::vec3 vertex = temp_vertices[ vertexIndex-1 ];
glm::vec2 uv = temp_uvs[ uvIndex-1 ];
glm::vec3 normal = temp_normals[ normalIndex-1 ];
out_vertices.push_back(vertex);
out_uvs .push_back(uv);
out_normals .push_back(normal);
}
return true;
}
更新
添加一些应该看起来像和我的绘图代码的图片。
它应该是这样的:
这实际上是这样的:
更新2: 由于评论中的请求而添加我的着色器代码抱歉这成为一个巨大的文本墙也in_Color被视为一个uv我还没有重命名它。 顶点着色器:
#version 150 core
uniform mat4 M;
uniform mat4 MVP;
uniform vec3 LightPosition_worldspace;
uniform mat4 V;
in vec3 in_Position;
in vec2 in_Color;
in vec3 in_Normals;
out vec2 pass_Color;
out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;
void main(void)
{
gl_Position = MVP* vec4(in_Position, 1.0);
Position_worldspace = (M * vec4(in_Position,1)).xyz;
vec3 vertexPosition_cameraspace = ( V * M * vec4(in_Position,1)).xyz;
EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;
vec3 LightPosition_cameraspace = ( V * vec4(LightPosition_worldspace,1)).xyz;
Normal_cameraspace = ( V * M * vec4(in_Normals,0)).xyz;
pass_Color = in_Color;
}
片段着色器:
#version 150 core
in vec2 pass_Color;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 LightDirection_cameraspace;
out vec3 out_Color;
uniform sampler2D myTextureSampler;
uniform mat4 MV;
uniform vec3 LightPosition_worldspace;
void main(void)
{
vec3 LightColor = vec3(1,1,1);
float LightPower = 200.0f;
vec3 MaterialDiffuseColor = texture2D( myTextureSampler, pass_Color ).rgb;
vec3 MaterialAmbientColor = vec3(0.1,0.1,0.1) * MaterialDiffuseColor;
vec3 MaterialSpecularColor = vec3(0.3,0.3,0.3);
float distance = length( LightPosition_worldspace - Position_worldspace );
vec3 n = normalize( Normal_cameraspace );
vec3 l = normalize( LightDirection_cameraspace );
float cosTheta = clamp( dot( n,l ), 0,1 );
vec3 E = normalize(EyeDirection_cameraspace);
vec3 R = reflect(-l,n);
float cosAlpha = clamp( dot( E,R ), 0,1 );
out_Color = MaterialAmbientColor
+ MaterialDiffuseColor * LightColor * LightPower
* cosTheta / (distance*distance) +MaterialSpecularColor
* LightColor * LightPower * pow(cosAlpha,5) / (distance*distance);
}
答案 0 :(得分:1)
将评论转化为答案,因为它原来是解决方案:
在着色器代码中,您有一个名为LightDirection_cameraspace
的变量变量,您可以在片段着色器计算中使用它。但是你永远不会在顶点着色器中为它赋值(而是计算一个不会进一步使用的局部变量LightPosition_cameraspace
)。所以它可能在片段着色器中有一些未定义的值,导致你的光照问题。