OpenGL 4.3错误地将第4个纹理坐标映射到与第3个纹理坐标相同的位置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL 4.3错误地将第4个纹理坐标映射到与第3个纹理坐标相同的位置相关的知识,希望对你有一定的参考价值。
当我运行这个程序时,它似乎只是将我的纹理映射到一个直角三角形的三个边(我的顶点数组中的前三个点),并完全错过了第四个,就像当我改变那个位时,没有任何变化图片。 https://imgur.com/a/MvhsYYv这里是当前输出作为顶部图像,预期输出作为第二图像。当我在我的着色器中使用一种颜色对其进行纹理处理时,它会使用纹理进行精细贴图,但它似乎仍然是绘制一个正方形,但是当它应该映射到右上角时映射到左上角。
Vertex vertices[] = {
//Position //Colour
vec3(-0.5f, 0.5f, 0.f), vec3(1.f, 0.f, 0.f), vec2(0.f, 1.f), //Top left
vec3(-0.5f, -0.5f, 0.f), vec3(0.f, 1.f, 0.f), vec2(0.f, 0.f), //Bottom Left
vec3(0.5f, -0.5f, 0.f), vec3(0.f, 0.f, 1.f), vec2(1.f, 0.f), //Bottom Right
vec3(0.5f, 0.5f, 0.f), vec3(1.f, 1.f, 1.f), vec2(1.f, 1.f) //Top Right
};
unsigned int numOfVertices = sizeof(vertices) / sizeof(Vertex);
GLuint indices[] = {
0,1,2,
3,0,2
};
unsigned numOfIndices = sizeof(indices) / sizeof(GLint);
void updateInput(GLFWwindow* window) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main() {
//INIT GLFW
glfwInit();
Wrapper mainWrapper = Wrapper();
Shader *mainShader = new Shader(vs_source.c_str(), fs_source.c_str());
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0,4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(2);
glBindVertexArray(0);
//TEXTURE INIT
int image_width = 0;
int image_height = 0;
unsigned char* image = SOIL_load_image("images/super-meat-boy.png", &image_width, &image_height, NULL, SOIL_LOAD_RGBA);
GLuint texture0;
glGenTextures(1, &texture0);
glBindTexture(GL_TEXTURE_2D, texture0);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (image) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
std::cout << "IMAGE LOADED";
}
else {
std::cout << "Error loading image";
}
//Clean up, needed when stuff done with texture
glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
//MAIN LOOP
while (!glfwWindowShouldClose(mainWrapper.getWindow())) {
//UPDATE INPUT
updateInput(mainWrapper.getWindow());
glfwPollEvents();
//UPDATE
//DRAW------
//clear
glClearColor(0.f,0.f,0.f,1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//draw
glUseProgram(mainShader->myProgram);
//activate texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture0);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, numOfIndices, GL_UNSIGNED_INT, 0);
//END DRAW
glfwSwapBuffers(mainWrapper.getWindow());
glFlush();
}
//END OF PROGRAM
glfwDestroyWindow(mainWrapper.getWindow());
delete mainShader;
glfwTerminate();
return 0;
}
#version 440
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec3 vertex_texcoord;
out vec3 vs_position;
out vec3 vs_color;
out vec2 vs_texcoord;
void main() {
vs_position = vertex_position;
vs_color = vertex_color;
vs_texcoord = vec2(vertex_texcoord.x, vertex_texcoord.y * -1.f);
gl_Position = vec4(vertex_position, 1.f);
}
#version 440
in vec3 vs_position;
in vec3 vs_color;
in vec2 vs_texcoord;
out vec4 fs_color;
uniform sampler2D texture0;
void main() {
fs_color = vec4(vs_color, 1.f);
fs_color = texture(texture0, vs_texcoord);
}
答案
glVertexAttribPointer
的第二个参数必须是顶点缓冲区中属性的元组大小(数量)。
您的顶点坐标有3个分量x,y,z。颜色属性也有3个组件(红色,绿色,蓝色)。纹理坐标有2个组件u和v:
glVertexAttribPointer(0,
3, // 3 instead of 4
GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,
3, // 3 instead of 4
GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, color));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2,
3, // 2 instead of 3
GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(2);
纹理坐标的元组大小的参数3会导致您访问顶点缓冲区超出索引3的顶点坐标的边界。
另一答案
我的glVertexAttribPointer中的大小调整不正确。我已经将我的顶点更改为vec2,vec3,vec2,并相应地更改了大小。
以上是关于OpenGL 4.3错误地将第4个纹理坐标映射到与第3个纹理坐标相同的位置的主要内容,如果未能解决你的问题,请参考以下文章