C++ OpenGL纹理未使用提供的UV坐标正确环绕对象
我试图让纹理在OpenGL中正常工作 现在的问题是: 如您所见,图像位于每个三角形的各个面上,而不是整个网格周围 我希望纹理正常工作:即:环绕整个网格,而不是每个三角形。 进一步说明问题;我创建了模型的线框,并将各个点加载到“文本转储”中,以便您可以看到映射应如何工作: 上述模型的顶点/法线/UV 上面图像的纹理 代码清单 正在加载图像: 下面是我如何在中加载图像(部分代码列表): 绑定属性并加载到GPU 下面是我如何绑定各种属性并将数据发送到GPU:C++ OpenGL纹理未使用提供的UV坐标正确环绕对象,c++,image,opengl,textures,coordinates,C++,Image,Opengl,Textures,Coordinates,我试图让纹理在OpenGL中正常工作 现在的问题是: 如您所见,图像位于每个三角形的各个面上,而不是整个网格周围 我希望纹理正常工作:即:环绕整个网格,而不是每个三角形。 进一步说明问题;我创建了模型的线框,并将各个点加载到“文本转储”中,以便您可以看到映射应如何工作: 上述模型的顶点/法线/UV 上面图像的纹理 代码清单 正在加载图像: 下面是我如何在中加载图像(部分代码列表): 绑定属性并加载到GPU 下面是我如何绑定各种属性并将数据发送到GPU: glGenVertexArrays(
glGenVertexArrays(1, &Pointer_VAO);
glBindVertexArray(Pointer_VAO);
glGenBuffers(1, &Vertex_VBO);
glBindBuffer(GL_ARRAY_BUFFER, Vertex_VBO);
glBufferData(GL_ARRAY_BUFFER, TotalBufferSize, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, NULL, VerticesBufferSize, Vertices);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
if (HasNormals) {
glBufferSubData(GL_ARRAY_BUFFER, NormalOffset, NormalBufferSize, Normals);
/*
Set up our Attribute pointer so that our Shader knows where to get our normals.
*/
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
}
if (HasUVs) {
glBufferSubData(GL_ARRAY_BUFFER, UVOffset, UVBufferSize, UVs);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(2);
}
glGenBuffers(1, &MVP_VBO);
glBindBuffer(GL_ARRAY_BUFFER, MVP_VBO);
glBufferData(GL_ARRAY_BUFFER, ModelMatrixInstances.size() * sizeof(glm::mat4), NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(GLfloat) * 0));
glEnableVertexAttribArray(3);
glVertexAttribDivisor(3, 1);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(GLfloat) * 4));
glEnableVertexAttribArray(4);
glVertexAttribDivisor(4, 1);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(GLfloat) * 8));
glEnableVertexAttribArray(5);
glVertexAttribDivisor(5, 1);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(GLfloat) * 12));
glEnableVertexAttribArray(6);
glVertexAttribDivisor(6, 1);
glGenBuffers(1, &NormalMatrix_VBO);
glBindBuffer(GL_ARRAY_BUFFER, NormalMatrix_VBO);
glBufferData(GL_ARRAY_BUFFER, ModelMatrixInstances.size() * sizeof(glm::mat3), NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(glm::mat3), (void*)(sizeof(GLfloat) * 0));
glEnableVertexAttribArray(7);
glVertexAttribDivisor(7, 1);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(glm::mat3), (void*)(sizeof(GLfloat) * 3));
glEnableVertexAttribArray(8);
glVertexAttribDivisor(8, 1);
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(glm::mat3), (void*)(sizeof(GLfloat) * 6));
glEnableVertexAttribArray(9);
glVertexAttribDivisor(9, 1);
glGenBuffers(1, &Index_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Index_VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, TotalPolygonCount * 3 * sizeof(unsigned int), Indices, GL_STATIC_DRAW);
glBindVertexArray(0);
着色器
顶点着色器:
#version 430
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;
layout(location = 3) in mat4 ModelViewProjectionMatrix;
layout(location = 7) in mat3 NormalMatrix;
out vec3 SurfaceNormal;
out vec2 TextureCoordinates;
void main () {
SurfaceNormal = normalize(NormalMatrix * vNormal);
TextureCoordinates = vUV;
gl_Position = ModelViewProjectionMatrix * vec4(vPosition, 1.0);
}
片段着色器:
#version 430
uniform MaterialBlock
{
vec4 MaterialColor;
vec4 AmbientMeshColor;
vec4 EmmissiveMeshColor;
vec4 DiffuseMeshColor;
vec4 SpecularMeshColor;
float MeshShininess;
float ObjectHasMaterialFile;
} Material;
uniform float EnableWireframe;
uniform vec4 WireframeColor;
uniform float IfEnableMaterial;
uniform float EnableLighting;
uniform float EnableSun;
uniform vec3 SunDirection;
uniform vec3 LightHalfVector;
uniform vec4 SunColor;
uniform vec4 SunSpotCutoff;
uniform float SunlightStrength;
in vec3 SurfaceNormal;
in vec2 TextureCoordinates;
uniform sampler2D MainTextureSampler;
out vec4 finalColor;
void SunlightWithMaterials() {
vec4 MaterialTextureColor = texture2D(MainTextureSampler, TextureCoordinates);
float DiffuseValue = max(0.0, dot(SurfaceNormal, SunDirection));
float SpecularValue = max(0.0, dot(SurfaceNormal, LightHalfVector));
if (DiffuseValue == 0.0) {
SpecularValue = 0.0;
} else {
SpecularValue = pow(SpecularValue, Material.MeshShininess);
}
vec3 ScatteredLight = Material.AmbientMeshColor.rgb + (SunColor.rgb * DiffuseValue);
vec3 ReflectedLight = SunColor.rgb * SpecularValue * SunlightStrength;
vec3 CalculatedColor = min(MaterialTextureColor.rgb * ScatteredLight + ReflectedLight, vec3(1.0));
finalColor = vec4(CalculatedColor, Material.MaterialColor.a);
}
void SunlightWithoutMaterials() {
float DiffuseValue = max(0.0, dot(SurfaceNormal, SunDirection));
float SpecularValue = max(0.0, dot(SurfaceNormal, LightHalfVector));
if (DiffuseValue == 0.0) {
SpecularValue = 0.0;
} else {
SpecularValue = pow(SpecularValue, Material.MeshShininess);
}
vec3 ScatteredLight = Material.AmbientMeshColor.rgb + (SunColor.rgb * DiffuseValue);
vec3 ReflectedLight = SunColor.rgb * SpecularValue * SunlightStrength;
vec3 CalculatedColor = min(Material.MaterialColor.rgb * ScatteredLight + ReflectedLight, vec3(1.0));
finalColor = vec4(CalculatedColor, Material.MaterialColor.a);
}
void main()
{
if (EnableWireframe == 1) {
finalColor = WireframeColor;
} else {
if (IfEnableMaterial == 1.0 && ObjectHasMaterialFile == 1.0) {
if (EnableLighting == 1.0) {
if (EnableSun == 1.0) {
SunlightWithMaterials();
}
else {
vec4 MaterialTextureColor = texture2D(MainTextureSampler, TextureCoordinates);
finalColor = min(MaterialTextureColor * Material.AmbientMeshColor, vec4(1.0));
}
}
else {
vec4 MaterialTextureColor = texture2D(MainTextureSampler, TextureCoordinates);
finalColor = MaterialTextureColor;
}
}
else {
if (EnableLighting == 1.0) {
if (EnableSun == 1.0) {
SunlightWithoutMaterials();
}
else {
finalColor = min(Material.MaterialColor * Material.AmbientMeshColor, vec4(1.0));
}
} else {
finalColor = Material.MaterialColor;
}
}
}
}
在OpenGL中绘制图像:
glBindVertexArray(指针);
对于(int i=0;iGetViewMatrix()*ModelMatrixinStations[i];
glm::mat3 NormalMatrix=glm::transpose(glm::inverse(glm::mat3(ModelViewMatrix));
glm::mat4 ModelViewProjectionMatrix=CurrentOpenGLController->GetProjectionViewMatrix()*ModelMatrixinStations[i];
glBindBuffer(GL_数组_BUFFER,MVP_VBO);
glBufferSubData(GL_ARRAY_BUFFER,(i*(sizeof(glm::mat4))),sizeof(glm::mat4),glm::value_ptr(ModelViewProjectionMatrix));
glBindBuffer(GL_数组_BUFFER,NormalMatrix_VBO);
glBufferSubData(GL_数组_BUFFER,(i*(sizeof(glm::mat3))),sizeof(glm::mat3),glm::value_ptr(NormalMatrix));
}
if(材质[0]。HasMaterialFile==true){
GLfloat ObjectHasMaterial=1.0f;
glUniform1fv(CurrentOpenGLController->GetObjectHasMaterialFileID(),1,&ObjectHasMaterial);
glUniform1i(CurrentOpenGLController->GetMainTextureID(),1);
材质[0],纹理(1);
}
否则{
glBindTexture(GL_TEXTURE_2D,空);
}
glBufferData(GL_统一_缓冲区,sizeof(材质[0]。颜色属性),材质[0]。颜色属性,GL_动态_绘制);
GLDRAILEMENTSINCED(GLU三角形、总顶点计数、,
GL_UNSIGNED_INT,NULL,NumberOfChildItems+1);
if(材质[0]。HasMaterialFile==true){
glActiveTexture(空);
glBindTexture(GL_TEXTURE_2D,空);
}
我们来看看这个
Vertex: X: -1 Y: 1 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.666667
Vertex: X: 1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.333333
Vertex: X: -1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.666667
Vertex: X: 1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.333333
Vertex: X: -1 Y: 1 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.666667
Vertex: X: 1 Y: 0.999999 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.333333
把它浓缩一点
X Z s [1/3] t
A -1 1 (SW) 1 2
B 1 -1 (NE) 2 1
C -1 -1 (NW) 2 2
B 1 -1 (NE) 2 1
A -1 1 (SW) 1 2
D 1 1 (SE) 1 1
现在取细分中重复的点-A和B,即西南和东北
假设s从西向东生长,因此t从北向南生长
因此,西北部的aka C应位于st=(1,1),东南部的aka D应位于st=(2,2)
但事实并非如此。它们被交换了谢谢;我尝试在我的加载代码中交换S和T,但都没有用。作为一项故障排除措施,我将最终颜色设置为纹理坐标以可视化问题:。交换所有S和T只会将问题旋转90度。在我的示例中,您必须将STs交换为相应的点,如C和D
glBindVertexArray(Pointer_VAO);
for (int i = 0; i < ModelMatrixInstances.size(); i++) {
glm::mat4 ModelViewMatrix = CurrentOpenGLController->GetViewMatrix() * ModelMatrixInstances[i];
glm::mat3 NormalMatrix = glm::transpose(glm::inverse(glm::mat3(ModelViewMatrix)));
glm::mat4 ModelViewProjectionMatrix = CurrentOpenGLController->GetProjectionViewMatrix() * ModelMatrixInstances[i];
glBindBuffer(GL_ARRAY_BUFFER, MVP_VBO);
glBufferSubData(GL_ARRAY_BUFFER, (i * (sizeof(glm::mat4))), sizeof(glm::mat4), glm::value_ptr(ModelViewProjectionMatrix));
glBindBuffer(GL_ARRAY_BUFFER, NormalMatrix_VBO);
glBufferSubData(GL_ARRAY_BUFFER, (i * (sizeof(glm::mat3))), sizeof(glm::mat3), glm::value_ptr(NormalMatrix));
}
if (Materials[0].HasMaterialFile == true) {
GLfloat ObjectHasMaterial = 1.0f;
glUniform1fv(CurrentOpenGLController->GetObjectHasMaterialFileID(), 1, &ObjectHasMaterial);
glUniform1i(CurrentOpenGLController->GetMainTextureID(), 1);
Materials[0].bindTexture(1);
}
else {
glBindTexture(GL_TEXTURE_2D, NULL);
}
glBufferData(GL_UNIFORM_BUFFER, sizeof(Materials[0].ColorProperties), Materials[0].ColorProperties, GL_DYNAMIC_DRAW);
glDrawElementsInstanced(GL_TRIANGLES, TotalVertexCount,
GL_UNSIGNED_INT, NULL, NumberOfChildItems + 1);
if (Materials[0].HasMaterialFile == true) {
glActiveTexture(NULL);
glBindTexture(GL_TEXTURE_2D, NULL);
}
Vertex: X: -1 Y: 1 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.666667
Vertex: X: 1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.333333
Vertex: X: -1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.666667
Vertex: X: 1 Y: 1 Z: -1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.666667 T: 0.333333
Vertex: X: -1 Y: 1 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.666667
Vertex: X: 1 Y: 0.999999 Z: 1 Normal: X: 2.38419e-007 Y: 1 Z: 1.63913e-007 UV Point: S: 0.333333 T: 0.333333
X Z s [1/3] t
A -1 1 (SW) 1 2
B 1 -1 (NE) 2 1
C -1 -1 (NW) 2 2
B 1 -1 (NE) 2 1
A -1 1 (SW) 1 2
D 1 1 (SE) 1 1